这是我参与「第四届青训营 」笔记创作活动的第8天,今天分享一下写简易分布式存储系统设计的一些心得,这是我们项目的GitHUb地址,欢迎大家批评指导: liuzongzhou/GoDFS (github.com) 本次继续介绍stat、rename、list接口设计和开发。
系统设计
Stat:显示文件元数据信息
在nameNode记录的元数据信息中增加key为文件绝对路径,value为文件元数据信息的hash表,当Stat方法被调用时,只需要远程调用nameNode获取hash表中存储的文件元数据信息即可。
特殊设计点:
- 在nameNode的元数据信息中直接存储文件和其元数据信息的map,查询时间为O(1)的复杂度。
List:显示目录下所有文件元数据信息
在nameNode记录的元数据信息中除了增加Stat中提及的key为文件绝对路径,value为文件元数据信息的hash表外,同时增加key为目录,value为目录下所有文件的相对路径的目录元数据信息表,当List方法被调用时,只需要远程调用nameNode首先获取目录元数据信息表中所List的目录下所有文件的相对路径,和目录拼接后得到文件的绝对路径,通过该绝对路径获取hash表中存储的文件元数据信息即可。
特殊设计点:
- 在nameNode的元数据信息中直接存储目录和包含文件的map,结合文件和其元数据信息的map,实现查询时间为O(1)的复杂度。
Rename:重命名文件名或者目录
ReNamePath
使用rpc调用NameNode的ReName方法,传入重命名的参数:ReNameSrcFileName和ReNameDestFileName,修改NameNode的元数据信息并返回修改是否成功即可。 特殊设计点:
- 在nameNode的元数据信息中直接存储了key为文件绝对路径的map,实现查重命名为O(1)的复杂度。FileNameToBlocks存储了文件绝对路径和Block块的对应关系,FileNameSize存储了文件绝对路径和文件元数据信息的对应关系,在重命名过程中,只需要对相应key进行修改即可,最后修改DirectoryToFileName存储的目录和目录下所有文件的相对路径的对应关系即可。
ReNameFile
首先取得当前存活的所有dataNodes节点信息,构造nameNode实例,向所有存活dataNode发起重命名目录的rpc请求,当所有的dataNode上路径重命名均成功时,才会修改nameNode上存储的元数据信息。
特殊设计点:
- 实现了防止dataNode出现脏数据的功能
即首先修改dataNode的路径信息,再修改nameNode的元数据信息,当重命名在某个节点执行失败时,由于元数据信息不丢失,只要重新发起请求即可。
- 使用Golang自带的前缀匹配函数加速文件元数据信息的修改
我们在nameNode的元数据中存储了三个Hash表,FileNameToBlocks存储了文件绝对路径和Block块的对应关系,FileNameSize存储了文件绝对路径和文件元数据信息的对应关系,DirectoryToFileName存储了目录和目录下所有文件的相对路径的对应关系,这三个Hash表的元数据在重命名过程中都需要修改,我们使用strings.HasPrefix(fileName, renameSrcPath)函数定位到需要修改的文件绝对路径,通过strings.Replace(fileName, renameSrcPath, renameDestPath, 1)修改相应的元数据信息。
简易分布式存储系统设计介绍完毕!