glusterfs双副本原理解析和脑裂解决方案

时间:2022-09-14 13:11:46

1.双副本介绍

1.1 什么是双副本?

待续....

1.2 双副本的优越性

待续....

1.3 双副本的缺陷

待续....

 

2.Glusterfs双副本在虚拟化中的应用

待续....

3.Glusterfs双副本实现过程

3.1 同步写操作

glusterfs双副本原理解析和脑裂解决方案
glusterfs双副本原理解析和脑裂解决方案

1.对要写入的文件进行加锁操作,先尝试加上非阻塞锁,如果失败去掉之前加的非阻塞锁,加上阻塞锁。

原因:避免同时的更新,避免写和自修复的冲突,多个客户端的冲突。

2.在文件副本上标记“changelog”(扩展属性),表示pending write,这并不是真正的log,而是一个计数数组,在pre op操作中设置所有节点pending状态置位为1,上传到brick,将对应的文件的扩展属性加1。

3.在所有的副本上执行实际的写操作。

4.在op操作后将正常活着的节点对应的pending状态置为-1,其他为0,上传到brick,将对应的文件扩展属性进行减1或0。

5.当所有节点写操作和changelog减少完成时,释放锁。

 

Glusterfs写操作技巧点:

如果另一个写在执行则跳过changelog增加,同样的当前者的写操作完成时,略过changelog的减少。这被称为“changelog piggbacking”,因为这样让第二个写操作骑在(‘ride along”)第一个写操作的changelog增加上。

当写重叠(overlap)时忽略掉unlock和之后的lock,这被称为“eager locking”,它和change piggybacking类似,除了它是对lock 操作而不是changlog操作的优化。

使用了以上优化算法,最优的情况下一次写操作的网络通信次数可以从5次减少到1次,只剩下1次写操作。一般情况下write-behind在nfs服务端进程默认是打开的,使得这种访问模式更容易发生,另外,write-behind的缓冲机制(默认为1M)也很大的优化了写操作。

 

3.2 修复过程

3.2.1 触发事件

1.Heal进程检查到有节点上线,也就是child xlator重新连接上brick。

2.Glusterd命令操作。

3.写入操作。

4.第一次进入某个目录。

5.Heal进程启动定时器,默认10分钟检查同步。

6.……

3.2.2 修复内容

1.Metadata:元数据

2.Data:数据内容

3.Entry:目录项

3.2.3 修复模式

1.INDEX:一般默认修复模式,对应目录项修复不作深入递归修复。

2.INDEX_TO_BE_HEALED:

3,FULL:递归进行修复。

3.2.4 INDEX模式修复步骤简述

1.判断是否有另一个修复过程存在,如果存在,则退出;

2.创建一个event事件。

3.在INDEX模式下,需要修复的文件都存储在brick上index xlator对应的路径下,通过设置标记GF_XATTROP_INDEX_GFID和getxattr操作获取index对应的index gfid。

4.通过index gfid查找或创建一个inode附着于dir_loc中,通过lookup操作获取iattr,通过iattr->gfid更新dir_loc中的inode,到此,拿到了需要修复文件所在的目录对应的gfid。

5.通过更新后的dir_loc查找fd,如果查找不到通过dir_loc->inode创建一个index_fd。

6.通过index_fd进行read_dir操作,获取到需要修复的文件列表,存入链表,需要注意的是这里并不是一次性获取全部的文件,而是通过该offset作为标志,循环每次获取一部分的文件。

7.有了文件列表,逐步的对一个一个文件进行修复。

8.从文件链表中取出文件,通过文件的gfid查找或创建inode,并将inode关联到loc上,设置字典xdata的"attempt-self-heal"值为1,表示要进行修复,进行afr_lookup操作,获取两边brick的文件属性,类型等iattr信息,字典数据等信息,字典里可能包含了meta,data,entry的状态信息。

9.afr_lookup_cbk回调函数中判断前面步骤设置需要修复,这时候开始就进行修复了。

10.我们知道修复一个inode文件(这里所说的文件也包含了文件夹,ext2,ext3之后,把文件夹也算作一个inode,只是ia_type文件类型进行区分)可能需要修复meta,data,entry,但是照成这些不一致的可能性有多种,例如有一个节点文件没写完,文件破损,文件不存在,或者说两边brick相同路径下的文件的gfid却不一样,或者说两个文件的ia_type不一样,也就是文件类型不一样,等等。

11.接下来就是通过两边brick的lookup操作返回的信息确定需要进行哪些修复并设置,需要注意的事如果有一个节点返回值是-1的话,默认全部需要修复,这里的修复类型有:

    1.do_data_self_heal:

    2.do_metadata_self_heal:

    3.do_entry_self_heal:

        上面三个的情况比较多,例如可能是文件权限不同,文件拥有者不同,文件大小不同,文件类型不同,或者文件扩展属性里changelog的那三个字段数据不匹配规则,这里偷懒下,先不说了,先说下下面两个更不常见的。

   

4.do_gfid_self_heal:brick返回成功,但是获取iattr->ia_gfid却为null,照成这种错误的应用场景是什么呢?谁想到了告诉我下。

5.do_missing_entry_self_heal:两边brick都返回成功,但是获取iattr->ia_gfid却不相等,这样的应用场景比较好想到,例如一个节点1掉线,节点2创建了一个文件,节点2掉线,节点1上线,节点1创建了一个相同路径和名字的文件,导致通过文件却不同的gfid,这种情况很有可能脑裂了。

 

12.通过上面的设置,接下判断是否需要metadata的修复,如果需要元数据修复,先判断是否元数据脑裂,这里判断元数据是否脑裂的依据比较简单,简而言之,一句话:通过一定规则是否可以创建和确定metadata修复的source,确定不了就说明脑裂了。

13. Glusterfs这样获取source的,首先根据child的个数n创建一个n维数组矩阵matrix[n][n],每一维数组存储的事对应的brick通过lookup返回changelog的关于meta的数据段的值,上面有讲到brick的lookup操作会返回字典xdata,而字典里面存有文件changelog扩展属性,可以通过pending_key[j](trust.gfid.clientName)作为key获取到,有了这些数据,就可以填充数组矩阵matrix[n][n]


14.数组矩阵填充完成之后,开始试着选取source,首先我们先介绍下ChangeLog的数值确定了副本的几种状态:

1)WISE,智慧的,即该副本的ChangeLog中对方对应的数值大于0而且自身对应的数值等于0.

2)INNOCENT,无辜的,即该副本上的ChangeLog即不指责对方也不指责自己,ChangeLog全为0.

3)FOOL,愚蠢的,即该副本上的ChangeLog是指责自己的。

套用上面所说的3种状态,如果该副本对应矩阵matrix[child_index_self][n]全为零,则说明该副本状态为INNOCENT不指责对方和自己,如果该副本对应自己matrix[child_self_index][child_self]的值是大于零的,说明是FOOL副本,自己指责自己需要修复,如果matrix[child_self_index][child_self] 的值为零,说明自己是WISE副本,满足source节点的一部分条件。


15.接下来可以通过上面的说的规则给每个child(副本)设置为WISE、INNOCENT或着FOOL,有了每个child的状态根据不同个组合来断定谁是source。

    1)如果所有副本都为INNOCENT,则最小ia_uid的副本作为source;

    2)如果找不到WISE副本则选取最大文件作为source;

    3)如果存在WISE副本,且和其他WISE副本,这时候就脑裂了。

    4)如果存在WISE副本,且没有其他WISE副本或者其他WISE副本没有冲突,这时候该副本就可以作为source。

    5)可能出现多个不冲突的WISE,取第一个作为source。

 

16.开始对其修复或者设置相应的脑裂标识,这里面过程比较多,有点类似写操,只是一点点类似,且暂时和需要修改的代码关系不大,这里简单说下meta的修复:

1)加inode锁,非阻塞。

2)lookup选举source

3)通过source获取文件属性和扩展属性。

4)用获取到的属性给其他非source副本进行设置。

5)清除之前的changelog扩展属性。

6)解锁。

17.Data修复:和meta操作方法相似,这里不细说

18.Entry修复:同上

4.  Glusterfs双副本一致性和可用性分析

4.1    CAP原理

glusterfs双副本原理解析和脑裂解决方案

一致性 ( Consistency) :任何一个读操作总是能读取到之前完成的写操作结果;

可用性 ( Availability) :每一个操作总是能够在确定的时间内返回;

分区可容忍性 (Tolerance ofnetwork Partition) :在出现网络分区的情况下,仍然能够满足一致性和可用性;

下面有一篇经典的文章,载自http://baike.baidu.com/view/45961.htm#4

  在足球比赛里,一个球员在一场比赛中进三个球,称之为帽子戏法(HAT-TRICK)。在分布式数据系统中,也有一个帽子原理(CAP THEOREM),不过此帽子非彼帽子。CAP原理中,有三个要素:
  一致性(CONSISTENCY)可用性(AVAILABILITY)分区容忍性(PARTITION TOLERANCE)CAP原理指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。因此在进行分布式架构设计时,必须做出取舍。而对于分布式数据系统,分区容忍性是基本要求,否则就失去了价值。因此设计分布式数据系统,就是在一致性和可用性之间取一个平衡。对于大多数WEB应用,其实并不需要强一致性,因此牺牲一致性而换取高可用性,是目前多数分布式数据库产品的方向。
  当然,牺牲一致性,并不是完全不管数据的一致性,否则数据是混乱的,那么系统可用性再高分布式再好也没有了价值。牺牲一致性,只是不再要求关系型数据库中的强一致性,而是只要系统能达到最终一致性即可,考虑到客户体验,这个最终一致的时间窗口,要尽可能的对用户透明,也就是需要保障“用户感知到的一致性”。通常是通过数据的多份异步复制来实现系统的高可用和数据的最终一致性的,“用户感知到的一致性”的时间窗口则取决于数据复制到一致状态的时间。
  最终一致性(EVENTUALLY CONSISTENT)
  对于一致性,可以分为从客户端和服务端两个不同的视角。从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。一致性是因为有并发读写才有的问题,因此在理解一致性的问题时,一定要注意结合考虑并发读写的场景。
  从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。如果能容忍后续的部分或者全部访问不到,则是弱一致性。如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。
  最终一致性根据更新数据后各进程访问到数据的时间和方式的不同,又可以区分为:
  因果一致性(CAUSAL CONSISTENCY)
  如果进程A通知进程B它已更新了一个数据项,那么进程B的后续访问将返回更新后的值,且一次写入将保证取代前一次写入。与进程A无因果关系的进程C的访问遵守一般的最终一致性规则。“读己之所写(READ-YOUR-WRITES)”一致性。当进程A自己更新一个数据项之后,它总是访问到更新过的值,绝不会看到旧值。这是因果一致性模型的一个特例。会话(SESSION)一致性。这是上一个模型的实用版本,它把访问存储系统的进程放到会话的上下文中。只要会话还存在,系统就保证“读己之所写”一致性。如果由于某些失败情形令会话终止,就要建立新的会话,而且系统的保证不会延续到新的会话。单调(MONOTONIC)读一致性。如果进程已经看到过数据对象的某个值,那么任何后续访问都不会返回在那个值之前的值。单调写一致性。系统保证来自同一个进程的写操作顺序执行。要是系统不能保证这种程度的一致性,就非常难以编程了。上述最终一致性的不同方式可以进行组合,例如单调读一致性和读己之所写一致性就可以组合实现。并且从实践的角度来看,这两者的组合,读取自己更新的数据,和一旦读取到最新的版本不会再读取旧版本,对于此架构上的程序开发来说,会少很多额外的烦恼。
  从服务端角度,如何尽快将更新后的数据分布到整个系统,降低达到最终一致性的时间窗口,是提高系统的可用度和用户体验非常重要的方面。对于分布式数据系统:
  N — 数据复制的份数W — 更新数据是需要保证写完成的节点数R — 读取数据的时候需要读取的节点数如果W+R>N,写的节点和读的节点重叠,则是强一致性。例如对于典型的一主一备同步复制的关系型数据库,N=2,W=2,R=1,则不管读的是主库还是备库的数据,都是一致的。
  如果W+R<=N,则是弱一致性。例如对于一主一备异步复制的关系型数据库,N=2,W=1,R=1,则如果读的是备库,就可能无法读取主库已经更新过的数据,所以是弱一致性。
  对于分布式系统,为了保证高可用性,一般设置N>=3。不同的N,W,R组合,是在可用性和一致性之间取一个平衡,以适应不同的应用场景。
  如果N=W,R=1,任何一个写节点失效,都会导致写失败,因此可用性会降低,但是由于数据分布的N个节点是同步写入的,因此可以保证强一致性。如果N=R,W=1,只需要一个节点写入成功即可,写性能和可用性都比较高。但是读取其他节点的进程可能不能获取更新后的数据,因此是弱一致性。这种情况下,如果W<(N+1)/2,并且写入的节点不重叠的话,则会存在写冲突   

 

4.2  Glusterfs双副本上CAP原理分析

Glusterfs双副本模式工作下,在来回拔插网线、等一些极端的情况下,如果为了只是一味的追求可用性 ( Availability),可能会出现脑裂的情况,照成了数据的不一致性( Consistency),而类似这种操作照成的脑裂是我们不可以容忍的。

根据CAP原理,如果我们想做到既可以保证glusterfs双副本的可用性( Availability),又能够保证数据的一致性( Consistency),这是不可能的,追求这样的完美只是徒劳。所以,鱼和熊掌不能兼得,必须舍其一。

作为分布式存储系统的应用场景下,节点都在线的时候,为了提高可用性,允许备用节点暂时没同步完成,我们只需要保证两个节点的弱一致性,或者说是最终一致性。但是一个节点离线的情况下,我们必须保证在线的节点数据的强一致性,是最新的数据。

为了保证数据的一致性,Glusterfs双副本引用了一种叫做quorum的机制,而且节点被划分为主从节点。Quorum规定当在线节点数小于所用节点数的二分之一时,副本变为只读模式。当在线节点数等于所有节点数的二分之一,并且在线节点为主节点是,允许其正常工作。

Quorum作用在glusterfs双副本模式上,也就是说,如果从节点掉线不影响主节点的可用性,数据的一致性也可以得到保障,但是如果主节点掉线,从节点变为只读模式,牺牲了数据的可用性,换取数据的一致性。


5.  Glusterfs针对虚拟化应用优化策略

5.1  Glusterfs双副本虚拟化应用分析

         所谓的Glusterfs双副本虚拟化应用也就是说,brick上的一个镜像文件对应一个操作系统,一个文件损坏或不可用导致一个操作系统不可用,而一个brick变得不可用,可能导致brick上成百上千的操作系统不可用。

glusterfs双副本默认是不启动quorum机制的,这样拥有高可用的性能,但是当在一些极端情况下可能会照成节点间同一文件没同步完成的情况下继续读写,照成脑裂这种无法挽回的错误。这种概率事件虽然很低,但是随着节点数的增加发生这种情况的概率会随之增高,是迟早得面对和解决的问题。

glusterfs双副本通过配置启动quorum机制,前面有说过它是主从节点模式,当从节点离线,主节点正常读写,继保证了高可用,也保证了数据的一致性。但是如果下线的事主节点,从节点变为只读模式,不具备写权限,就是说节点上所有brick上的所有镜像文件都不可写,对于虚拟化应用,所有brick上的操作系统都不可用了,这无疑使让人不可接受的。

       从上可知,Glusterfs提供的两套解决方案,在双副本模式和虚拟化应用场景上,第一种显得太过追求可用性了,完全没考虑到一致性;而第二种为了追求数据一致性了,过多的牺牲了可用性,特别在虚拟化应用场景中,牺牲的可用性照成的损失无疑会被放大许多倍,所有在虚拟化应用中不得不放弃这种方案。

       如上文所诉,两套方案对于虚拟化应用来说都太过极端了。所有,我们需要有一套自己择中的方案:

1)为了增加系统的可用性,我们可用降低一致性,可以把quorum机制对brick的一致性降低到对文件的一致性,即使brick不一致,但是brick上的文件时一致的,仍然允许其正常读写。

2)为了保证文件的一致性,当文件没被同步完成时,我们不得不降低文件的可用性,让文件变为只读模式。


5.2  Glusterfs双副本修改策略

glusterfs双副本原理解析和脑裂解决方案
glusterfs双副本原理解析和脑裂解决方案
brick进程堆栈:

volume afr_pool-posix
    type storage/posix
    option volume-id 4d2f0895-db19-4650-a618-0a0362e13964
    option directory /vol/file1
end-volume

volume afr_pool-changelog
    type features/changelog
    option changelog-dir /vol/file1/.glusterfs/changelogs
    option changelog-brick /vol/file1
    subvolumes afr_pool-posix
end-volume

volume afr_pool-access-control
    type features/access-control
    subvolumes afr_pool-changelog
end-volume

volume afr_pool-locks
    type features/locks
    subvolumes afr_pool-access-control
end-volume


volume afr_pool-io-threads
    type performance/io-threads
    subvolumes afr_pool-locks
end-volume

volume afr_pool-index
    type features/index
    option index-base /vol/file1/.glusterfs/indices
    subvolumes afr_pool-io-threads
end-volume

volume afr_pool-spp_server
    type spp/spp_server
    option spp_sync_flag /etc/glusterd
    option spp_server_index-base /vol/file1/.glusterfs/spp_server
    subvolumes afr_pool-index
end-volume


volume afr_pool-marker
    type features/marker
    option quota off
    option gsync-force-xtime off
    option xtime off
    option timestamp-file /etc/glusterd/vols/afr_pool/marker.tstamp
    option volume-uuid 4d2f0895-db19-4650-a618-0a0362e13964
    subvolumes afr_pool-spp_server
end-volume

volume afr_pool-quota
    type features/quota
    option deem-statfs off
    option timeout 0
    option server-quota off
    option volume-uuid afr_pool
    subvolumes afr_pool-marker
end-volume

volume /vol/file1
    type debug/io-stats
    option count-fop-hits off
    option latency-measurement off
    subvolumes afr_pool-quota
end-volume

volume afr_pool-server
    type protocol/server
    option auth.addr./vol/file1.allow *
    option auth.login.6126bf34-c8c3-4840-8d5c-4cd7730a2bf1.password fc1fd2c1-8e21-4685-9856-4c7890991daa
    option auth.login./vol/file1.allow 6126bf34-c8c3-4840-8d5c-4cd7730a2bf1
    option transport-type tcp
    subvolumes /vol/file1
end-volume


self_heal进程堆栈:

volume afr_pool-client-0
    type protocol/client
    option password fc1fd2c1-8e21-4685-9856-4c7890991daa
    option username 6126bf34-c8c3-4840-8d5c-4cd7730a2bf1
    option transport-type tcp
    option remote-subvolume /vol/file1
    option remote-host 192.168.1.45
end-volume

volume afr_pool-client-1
    type protocol/client
    option password fc1fd2c1-8e21-4685-9856-4c7890991daa
    option username 6126bf34-c8c3-4840-8d5c-4cd7730a2bf1
    option transport-type tcp
    option remote-subvolume /vol/file1
    option remote-host 192.168.1.47
end-volume

volume afr_pool-replicate-0
    type cluster/replicate
    option udf_client_switch yes
    option iam-self-heal-daemon yes
    option self-heal-daemon on
    option entry-self-heal on
    option data-self-heal on
    option metadata-self-heal on
    option background-self-heal-count 0
    subvolumes afr_pool-client-0 afr_pool-client-1
end-volume

volume afr_pool-spp_client-0
    type spp/spp_client
    option spp_sync_flag /etc/glusterd
    option spp_client_nfs_opt no
    option spp_client_check_out_sync yes
    subvolumes afr_pool-replicate-0
end-volume


volume glustershd
    type debug/io-stats
    subvolumes afr_pool-spp_client-0
end-volume


nfs进程堆栈:

volume afr_pool-client-0
    type protocol/client
    option send-gids true
    option password fc1fd2c1-8e21-4685-9856-4c7890991daa
    option username 6126bf34-c8c3-4840-8d5c-4cd7730a2bf1
    option transport-type tcp
    option remote-subvolume /vol/file1
    option remote-host 192.168.1.45
end-volume

volume afr_pool-client-1
    type protocol/client
    option send-gids true
    option password fc1fd2c1-8e21-4685-9856-4c7890991daa
    option username 6126bf34-c8c3-4840-8d5c-4cd7730a2bf1
    option transport-type tcp
    option remote-subvolume /vol/file1
    option remote-host 192.168.1.47
end-volume

volume afr_pool-replicate-0
    type cluster/replicate
    option udf_client_switch yes
    option node-uuid 7d6f8c7e-bc5e-4a81-9bb1-5e9a84258714  (非标准,修改源码添加)
    subvolumes afr_pool-client-0 afr_pool-client-1
end-volume

volume afr_pool-spp_client-0
    type udf/udf_client
    option spp_sync_flag /etc/glusterd (标识文件存储路径)
    option spp_client_nfs_opt yes
    option spp_client_check_out_sync no
    subvolumes afr_pool-replicate-0
end-volume


volume afr_pool-dht
    type cluster/distribute
    subvolumes afr_pool-spp_client-0
end-volume

volume afr_pool-write-behind
    type performance/write-behind
    subvolumes afr_pool-dht
end-volume

volume afr_pool
    type debug/io-stats
    option count-fop-hits off
    option latency-measurement off
    subvolumes afr_pool-write-behind
end-volume

volume nfs-server
    type nfs/server
    option nfs.afr_pool.disable off
    option nfs3.afr_pool.export-dir /afr_share(192.168.10.0/24|192.168.1.0/24)
    option nfs.port 2049
    option rpc-auth.addr.namelookup off
    option nfs3.export-volumes off
    option nfs3.export-dirs on
    option nfs3.afr_pool.volume-id 4d2f0895-db19-4650-a618-0a0362e13964
    option rpc-auth.addr.afr_pool.allow *
    option nfs.drc off
    option nfs.nlm on
    option nfs.dynamic-volumes on
    subvolumes afr_pool
end-volume

如上所示,分别在glusterfs的客户端(nfs服务进程,pfs客户端进程,self_heal进程)和服务端(brick进程)加入了spp_client和spp_server。


1):在brick进程中:加入spp_server,这个xlator的作用是获取自身brick需要被其他brick同步的文件,而这些文件存储在/brick/.glusterfs/spp_server目录下,模仿index xlator的设计思路。

2):在self进程中:如节点上线等情况,afr程序开始自我修复时候,会将需要同步的文件列表从自身brick中取出,notify到上层spp_client,这时候,spp_client拿到了这个文件列表,将这些文件列表发送给另一个节点,由双副本另一个节点的spp_server接收到文件列表gifd,并存入/brick/.glusterfs/spp_server文件路径。并在记录标识文件的值为1,表示已经将文件列表同步给双副本的另一个节点。在同步的过程中,当同步完一个文件时,通知两端的brick进程,这时brick进程在/brick/.glusterfs/spp_server路径下将对应的文件unlink掉。当节点掉线的时候,记录标识文件的值为0。

3):在nfs进程(或pfs客户端进程)中:当双副本节点上线的时候,nfs暂时停止服务(这里时间很短,可以忽略不计,也可以通过开关设置是否停止服务),spp_client开启定时器,分别去两个brick上读取标识文件的值,当读到两边的值都是1时,说明两边的brick上需要同步的文件列表已经更新完成,这时定时读取两边brick需要同步的的文件列表更新本地文件过滤链表(这时heal进程正在同步,每次读到的文件列表会越来越少,千级以上的文件可以用哈希链表)。spp_client过滤功能被触发时,这时链表里存在的gfid文件的写操作将被过滤掉,io写操作将会被返回readonly,每个文件的过滤只需要一次,结果被记录在inode的ctx内容里面,下次遇到相同的文件则只需要读取结果记录。当强一致性开关打开时,就算两个节点同时在线,spp_client过滤功能也启用,如果关闭,只有当一个节点掉线的时候,spp_client过滤功能才被触发。

4)私人测试,仅供参考:

1:不开启quorum功能,不开启spp功能(标志glusterfs双副本测试):

1.1:可用性百分百,500线程写入500个文件测试多次故障,来回拔插网线,断电,重启,脑裂的概率为100%,脑裂文件上百个。

2:不开启quorum功能,开启spp功能后:

2.1:当强一致性开关打开时,两节点在线时,需要修复的文件无法写入直到修复完成,可用性降低。多次网络故障,来回拔插网线,断电,重启,脑裂的概率为0。

2.2:关闭强一致性开关时,两节点在线,可用性百分百,500线程写入500个文件测试多次故障,来回多次拔插网线,脑裂概率大概35%,每次最多脑裂一个文件,断电,重启脑裂概率为0。脑裂的原因是spp过滤之前有一个时间差,可能导致很小一部分文件操作流程已经穿过spp层到达afr层,导致spp无法过滤到。


双副本spp状态机详解

glusterfs双副本原理解析和脑裂解决方案

glusterfs双副本原理解析和脑裂解决方案


spp_server状态机表示图

glusterfs双副本原理解析和脑裂解决方案

nfs进程上spp_client状态机表示图

glusterfs双副本原理解析和脑裂解决方案glusterfs双副本原理解析和脑裂解决方案

Nfs.spp_client文件过滤流程

glusterfs双副本原理解析和脑裂解决方案

glusterfs双副本原理解析和脑裂解决方案

spp协议流程图

glusterfs双副本原理解析和脑裂解决方案

glusterfs双副本原理解析和脑裂解决方案