设为首页 收藏本站
查看: 2215|回复: 0

[经验分享] Glusterfs DHT(hash分布)源代码分析

[复制链接]
发表于 2019-2-1 11:51:13 | 显示全部楼层 |阅读模式
  摘要 Glusterfs3.3.1DHT部分的简介以及源代码流程分析, http://www.iesool.com/forum.php?mod=viewthread&tid=14&fromuid=1
  glusterfs dht 集群文件系统 源码分析
  1.DHT简介
  GlusterFS使用算法进行数据定位,集群中的任何服务器和客户端只需根据路径和文件名就可以对数据进行定位和读写访问。换句话说,GlusterFS不需要将元数据与数据进行分离,因为文件定位可独立并行化进行。GlusterFS中数据访问流程如下:
  1)     计算hash值,输入参数为文件路径和文件名;
  2)     根据hash值在集群中选择子卷(存储服务器),进行文件定位;
  3)     对所选择的子卷进行数据访问。
  2.DHT源码流程分析
  2.1正常流程
  2.1.1创建目录
  创建目录的主要步骤有:
  1)       根据目录名计算哈希值,由其哈希值所在的hash区间确定hashed卷。
  2)       向hashed卷下发mkdir操作。
  3)       待hashed卷返回后,再向除hashed卷之外的所有子卷下发mkdir操作。
  4)       待所有子卷均返回后,合并目录属性。
  5)       为每个子卷在该目录上分配hash区间。
  6)       将各自的hash区间写入子卷上该目录的扩展属性中。
  7)       创建目录结束。
  其流程如下图所示:
DSC0000.jpg

  2.1.2创建文件
  创建文件的主要步骤有:
  1)       根据文件名计算hash值,根据父目录hash分布获取其hashed卷。
  2)       若hashed卷空间,inode数目等没有超过上限,则直接在hashed卷创建该文件。
  3)       若hashed卷空间,inode数目等超过了上限,则在子卷中选择一个最优的作为其avail卷。
  4)       在hashed卷上创建DHTLINKFILE,其扩展属性中记录着avail卷的名字。
  5)       在avail卷上创建该文件。
  6)       创建文件结束。
  其流程如下图所示:
DSC0001.jpg

  2.1.3打开文件
  Open文件的主要步骤有:
  1)       向其cached卷下发open操作(在open前会调用lookup获取其cached卷)。
  2)       若open成功,则将文件fd等信息返回,open操作完成(如果失败且返回的错误码是不存在,也会直接返回)。
  3)       若open失败后会重新获取dst_node(因为有可能处于数据迁移第二阶段)。
  4)       向重新获取dst_node在此下发open。
  5)       若失败,返回错误码。
  6)       若成功,将fd等返回上层,open操作完成。
  其流程如下图所示:
DSC0002.jpg

  2.1.4读取文件
  读取文件的主要流程有:
  1)       向cached卷下发read操作。
  2)       若读取成功且该文件未处于数据迁移第二阶段,则将读取数据返回,此次读取结束。
  3)       若读取成功但该文件处于数据迁移第二阶段,则会重新获取目标卷,再次下发read操作。
  4)       若失败且错误码是ENOENT,则直接返回错误码。
  5)       若失败或该文件处于数据迁移第二阶段,则会重新获取目标卷,再次下发read操作。
  6)       第二次读取,若成功则将数据返回,若读取失败,将错误码返回。
  7)       此次读取操作结束。
  其流程如下图所示:
DSC0003.jpg

  2.1.5写入文件
  向文件写入数据的主要流程有:
  1)        向cached卷下发write命令。
  2)        待返回,若正处于数据迁移第二阶段,重新获取目标卷等信息,再次下发write命令。
  3)        若正处于数据迁移第一阶段,重新获取目标卷等信息,在次下发write命令。
  4)        将返回值等返回给上层(若有第二次write,将第二次write的返回值等返回给上层)。
  写入数据的流程如下图所示:
DSC0004.jpg

  2.1.6读取目录
  读取目录项主要流程有:
  1)       向所有子卷下发opendir操作。
  2)       只将最后一个返回的返回值返回。
  3)       根据上层readdir中offset定位到某个子卷,向该子卷下发readdir操作。
  4)       将该子卷读取的目录项进行过滤(过滤DHTLINKFILE,若不是first_up_subvol,也将目录过滤掉),将读取的目录项返回。
  5)       若该子卷读取的目录项过滤后个数为0且next_offset != 0,说明该subvol尚未读完,则继续向该subvol下发readdir操作。
  6)       若该子卷读取的目录项过滤后个数为0但next_offset == 0,说明该subvol已经读完,则向next_subvol下发readdir操作。
  7)       如果next_subvol不为空,则next_subvol下发readdir操作返回后,重复执行步骤4)的操作。
  8)       如果next_subvol为空,说明该目录内的所有项以读取完毕。
  注:上述中若count = 0但next_offset != 0,说明此次读取的目录项中均为目录和DHTLINKFILE,全部被过滤掉,所以count = 0。
  读取目录的流程如图所示:
DSC0005.jpg

  2.1.7lookup
  Lookup操作的主要流程有:
  1)       根据name获取其hash卷。
  2)       若不是第一次查询且是目录,则向所有子卷下发lookup操作,比对与inode中的信息是否一致,若不一致则更新。
  3)       若不是第一次查询但不是目录,则向cached下发lookup操作,若不存在,则需调用dht_lookup_everywhere.,找到后为其创建DHTLINKFILE。
  4)       若是第一次查询且是目录,则会向其hashed卷下发lookup操作,然后再向其它子卷下发lookup操作,合并后返回。
  5)       若是第一次查询但不是目录,则会向其hashed卷下发lookup操作,若返回的是DHT_LINKFILE,则还有向其cached卷下发lookup操作,将其属性返回。
  Lookup操作的流程如下图所示:
DSC0006.jpg

  2.2特殊处理
  2.2.1添加卷后lookup
  添加卷后lookup的主要流程有:
  1)       执行添加卷命令后,将会重新初始化。
  2)       lookup目录时,待各个子卷将目录信息返回后,都会调用dht_layout_merge(),将各个子xlator指针,返回值等添加到layout中。
  3)       然后调用dht_layout_normalize时,新添加的list.err(start=stop=0,在检测是否有空洞和重叠时已按hash区间排序,所以新添加的卷没有空洞和重叠)会被置为ENOENT。
  4)       所以dht_layout_normalize返回!=0,然后进入目录修复。
  5)       会调用dht_selfheal_dir_mkdir在新添加的卷上创建该目录setattr(该目录没有分布区间信息,所以不需要setxattr)。
  6)       最后调用dht_selfheal_dir_finish结束。
  注:再次lookup时,在dht_layout_normalize中因为layout->list.err < 0(err ==-1),所有该函数返回0(第一次该函数会返回ret>0),不会触发目录修复动作。
2.2.2后端手动添加文件  在后端手动添加文件后,再执行ls操作,其主要流程有:
  1)       readdir时,其父目录会将该目录项返回给上层。
  2)       然后对该文件进行lookup。
  3)       若通过hashed_subvol直接定位到了该文件,则将该文件属性返回给上层。
  4)       若没有,则会lookup_everywhere,找到该文件,然后将该文件作为其cached_subvol,并创建hashed_subvol到cached_subvol的链接文件。
2.2.3后端手动添加目录  后端手动添加目录后,执行ls操作,其主要流程有:
  1)       若该新添加的目录不是位于first_up_subvol,则该目录向在其父目录readdir时会被过滤,即在挂载点不会看到你新添加的目录。
  2)       若新添加的目录位于first_up_subvol,则在readdir父目录时会向将该目录项返回给上层。
  3)       然后对该目录项进行lookup,在其hashed_subvol找到该目录的话,执行looku_directory(各个卷查找该目录)。若找不到,则会执行lookup_everywhere.
  4)       在lookup_diectory后,若需要修复,则在各子卷创建该目录,并分配hash区间。
  5)       在lookup_everywhere时,找到该目录,然后再执行looku_directory.
2.2.4修复目录layout  修复目layout的主要流程有:
  1)       重新分配hash区间,hash区间按子卷个数划分,优先分配与原区间重叠最大的区间段。
  2)       将重新分配的hash区间,存储到其扩展属性中。
2.2.5数据迁移  数据迁移的主要流程有:
  1)       首先lookup该目录。
  2)       遍历该目录下的DHT_LINKFIFE.
  3)       如果该文件实际就是符号链接,则根据源文件信息在to上建立该符号链接,如果是设备文件,在to上mknode。然后将源文件unlink
  4)       如果是普通文件,则在其hash卷上create该文件。
  5)       然后打开源文件。
  6)       检测是否含有空洞文件。
  7)       进行读写。
  8)       读写完毕后,move扩展属性。
  9)       unlink源文件,truncate,然后清楚标志位等。
  10)    迁移该文件结束。
  3.结束
  通过对DHT源代码的分析,已基本清楚其工作流程。本文档描述了dht部分的工作流程,若有描述或理解错误,请各位给予指正,谢谢。(原文地址 Glusterfs3.3.1DHT(hash分布)源代码分析【文档中流程图登录后才可见】
  http://www.iesool.com/forum.php?mod=viewthread&tid=14&fromuid=1
  (出处: 吖Sool-社区)
  )
  (我就是原文的作者,哈哈  欢迎支持 吖Sool-社区 http://www.iesool.com  注册有惊喜奥)
  
  转自:http://my.oschina.net/uvwxyz/blog/182224


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-670425-1-1.html 上篇帖子: KVM虚拟化开源高可用方案(七)GLUSTERFS搭建及常见故障处理 下篇帖子: GlusterFS学习2
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表