Glusterfs3.3.1DHT(hash分布)源代码分析

作者:老叮当猫

来源:开源中国

原文:https://my.oschina.net/uvwxyz/blog/182224

版权声明:本文为博主原创文章,转载请附上博文链接!

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)      创建目录结束。

其流程如下图所示:

2.1.2创建文件

创建文件的主要步骤有:

1)      根据文件名计算hash值,根据父目录hash分布获取其hashed卷。

2)      若hashed卷空间,inode数目等没有超过上限,则直接在hashed卷创建该文件。

3)      若hashed卷空间,inode数目等超过了上限,则在子卷中选择一个最优的作为其avail卷。

4)      在hashed卷上创建DHTLINKFILE,其扩展属性中记录着avail卷的名字。

5)      在avail卷上创建该文件。

6)      创建文件结束。

其流程如下图所示:

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操作完成。

其流程如下图所示:

2.1.4读取文件

读取文件的主要流程有:

1)      向cached卷下发read操作。

2)      若读取成功且该文件未处于数据迁移第二阶段,则将读取数据返回,此次读取结束。

3)      若读取成功但该文件处于数据迁移第二阶段,则会重新获取目标卷,再次下发read操作。

4)      若失败且错误码是ENOENT,则直接返回错误码。

5)      若失败或该文件处于数据迁移第二阶段,则会重新获取目标卷,再次下发read操作。

6)      第二次读取,若成功则将数据返回,若读取失败,将错误码返回。

7)      此次读取操作结束。

其流程如下图所示:

2.1.5写入文件

向文件写入数据的主要流程有:

1)        向cached卷下发write命令。

2)        待返回,若正处于数据迁移第二阶段,重新获取目标卷等信息,再次下发write命令。

3)        若正处于数据迁移第一阶段,重新获取目标卷等信息,在次下发write命令。

4)        将返回值等返回给上层(若有第二次write,将第二次write的返回值等返回给上层)。

写入数据的流程如下图所示:

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。

读取目录的流程如图所示:

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操作的流程如下图所示:

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部分的工作流程,若有描述或理解错误,请各位给予指正,谢谢。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容