赵海
作者赵海2021-07-12 16:19
技术经理, 大连

企业容灾选型指南-5:脑裂问题探讨

字数 4585阅读 783评论 1赞 1

【摘要】 随着全球IT产业的飞速发展,企业的IT建设逐步成为主导业务发展的核心驱动力,基于企业IT架构容灾建设的各种行业标准以及监管标准也相应提高。提高企业整体容灾体系标准是摆在企业面前的挑战,但是面对技术的日新月异和信息技术的多元化发展,很多企业在容灾架构的选型过程当中也存在着诸多困惑。因此旧事重提,我们通过一系列的文章来重新阐述这个IT界经久不衰的话题。


1. 什么是容灾中的脑裂问题?

脑裂(split-brain)就是“大脑分裂”,也就是本来一个“大脑”,由于某些原因被拆分了两个或多个“大脑”,我们都知道,如果一个人有多个大脑,并且相互独立的话,那么必然会出问题。

在容灾架构设计当中,我们经常会利用一些 HA、Cluster等高可用架构在其中,而且一般都是借助于跨地域L2网络,采用跨数据中心的方式在某一个功能层组成一个独立的集群,例如数据库集群、存储网关集群等 。假设因为两个数据中心节点通讯中断故障导致形成了两个独立的集群,彼此独立工作,那么这就是脑裂。正如下图所示情况。

第一个问题:为什么会集群可能产生脑裂?

这个问题需要回到集群的仲裁机制上来,一般来讲集群的仲裁算法是以每一个节点可以获得仲裁资源的多少来判断谁是集群的主导。集群的仲裁资源无非是来自网络层面的心跳信息和共享存储的磁盘心跳资源,在普通的节点层故障场合下,发生故障的节点可以获得的仲裁资源就会少于其他节点,那么就不会发生脑裂问题。但是在一种特殊的场合(双数据中心之间的网络发生了故障),两个节点可以获得的仲裁资源是一样的,网络彼此不能互通,存储彼此不能看到对方,这样的的场景下仲裁就会失效,脑裂发生。

第二个问题:集群如果发生了脑裂问题,那么会造成什么样的结果?

那么为什么说对于容灾架构来讲,脑裂是灾难性的事件呢?如果从一个统一集群的调度变成两个相互独立的集群调度,意味着双方的写操作相互也是独立的,但是他们的存储空间是共享的, AA模式下通过锁机制控制并发,HA模式下通过存储卷的Owner控制写的权限。但是独立之后意味着两个集群可以随时写入同样的存储地址,必然会造成脏写脏读等一系列数据不一致事件。这对业务来讲是灾难性的。

2. 优先级解决方案

2.1 Oracle RAC优先级解决方案

如图所示,以两个节点的 Oracle RAC为例来讲,ORACLE RAC ASM管理模式下,磁盘组通常有三个(+DATA,+FRA,+OCR),在OCR磁盘组当中所有的磁盘中存储的数据包括两部分,一部分是Vote File,另外一部分就是OCR(Oracle Cluster Registry)。Vote File是用来记录集群节点的磁盘心跳信息,而OCR是保存集群配置信息的数据。Vote File,以整个文件的方式存储在OCR磁盘上,不做任何条带。下图是其信息记录的一个说明:

Instance1 OK NG NG
Instance2 NG OK OK
Instance3 NG OK OK
Instance1 Instance2 Instance3

以上是一个三节点的ORACLE RAC集群的Vote FIle的一个示意矩阵,每一行是一个节点的写入的信息,例如第一行,Instance1分别把其对集群中的三个成员(1、2、3)进行私网检测的结果写入到仲裁文件当中,Instance2、Instance3同样把其检测结果写入仲裁文件,最终组成了三个节点的仲裁矩阵。当私网发生故障而从网络上导致集群分割为几个孤岛子集的时候,网络心跳同票数情况下,仲裁算法有两个非常重要的规则:

① 保障隔离后的集群子集中节点数目最多的子集存活。

② 当隔离后的集群子集获得的仲裁票数相等时,保障实例号小者存活。

当两个节点的Oracle RAC集群面临私网故障的时候,必然会遵循以上规则,从规则内容上可以看出,第一条规则基本没有什么意义,双方的资源是对等的;但是第二条规则直接决定了集群的最终状态,那就是实例号小的节点成为新的集群,这就避免了脑裂的存在。

2.2 资源失衡配置解决方案


所谓资源失衡配置解决方案,就是要在容灾设计之初就保障主数据中心的资源配置要多于灾备中心,使得两个数据中心节点可以获取到的仲裁资源处于不平衡状态。

如上两图所示,容灾设计的时候可以将主备数据中心的节点分布数量或者仲裁文件分布数量按照2:1的非平衡策略设置。那么按照集群仲裁的一般规则:发生集群分裂故障的时候,可以获得更多仲裁资源的子集将成为新的集群。当发生数据中心之间的网络故障的时候:

第一种架构,主数据中心内部两个节点可以获取到更多的网络心跳,自然会接管集群。

第二种架构,主数据中心的节点可以获取到更多的磁盘心跳,同样会接管集群。

这也符合我们设计之初衷。但是,这种方法只适合于AA模式的多节点集群,不适合HA模式的架构。

2.3 自定义优先级解决方案

自定义优先级的解决方案,其实本质上与Oracle RAC的仲裁算法第二条“当隔离后的集群子集获得的仲裁票数相等时,保障实例号小者存活。”是一样的。只不过对于Oracle RAC,当通过第一条规则无法判断的时候(节点获取的仲裁资源矩阵是平衡的),它默认采用了实例号定义其优先级。

而其他的一些容灾方案,这个优先级定义的灵活性留给了客户。例如图当中的VPLEX产品,尤其是在双活架构的设计当中,有可能因为地域、设备新旧、运营管理等方面的差异,往往灾备中心的运行能力会稍差,那么发生数据中心之间隔离的这种故障时,大家往往希望保留主数据中心的运行。那么这个时候客户就可以根据主数据中心的节点标识来固定其仲裁优先级。

3. 仲裁解决方案

3.1 网络仲裁

网络资源是集群仲裁当中非常重要的一种心跳资源,因此通过第三方网络资源的可达性心跳信息来判断对称集群分裂后的新秩序也是一种非常有效的方法。一般在以存储网关实现数据双写的容灾架构当中比较常见,比如 VPLEX、SVC、MCC等。具体原理如下图所示:

第三方仲裁点需要满足的条件:

① 与主备两个数据中心 L3可达,并且网络质量稳定。

② 仲裁点一般需要安装具备网络探测功能的虚拟服务器或者物理服务器,具备运行条件。

如图所示,仲裁点服务器上的软件会与组成集群的存储器网关两个节点分别发送PING/ACK来确认双方的健康情况,集群会把两个节点与第三方仲裁点的网络仲裁心跳看做是最终的裁判。Vplex Witness 通过管理 IP 网络连接至两个集群节点,通过将其自身的观察与集群定期报告的信息进行协调,让集群可区分是集群内故障还是集群间链路故障,并在这些情况下自动继续相应站点上的 I/O 服务。 Vplex Witness 仅当分离规则没有定义时才会生效。当然细心的读者可能产生了一个新的问题:

如果数据中心与第三仲裁站点的网络发生故障,那会不会影响集群本身的运行?****

什么是仲裁?仲裁是只有发生集群隔离故障的时候才会起作用,如果没有发生数据中心之间的隔离故障的时候,即使他们的一方或者双方于第三烦仲裁站点发生网络暂时中断的事件,也不会对既有集群造成任何健康影响。我们需要做的是保障第三方仲裁资源在发生故障的时候有效就可以了(监控&及时修复)。

3.2 存储仲裁

存储一般是数据库集群当中非常关键的仲裁资源,数据库集群的节点负载比较重,不像存储网关模式的集群,可以再设计与 Witness Node的通讯接口。所以在这类技术方案的容灾设计当中,通常会用第三方存储阵列来作为集群的第三方仲裁点。例如Oracle Extended RAC、HA&Oracle、HA&DB2等。具体原理如下图所示:

a. 第三方站点放置一个存储阵列、并且与两个数据中心网络稳定可达。

b. 存储阵列以NFS或者ISCSI方式提供共享存储卷或文件服务给两个中心的集群节点。

c. 集群配置的时候,将这个共享存储卷或者文件作为集群的磁盘仲裁之一。

当双中心的集群发生隔离故障的时候,集群通过第三方的仲裁磁盘或者文件来判断集群的新秩序。

3.3 对称隔离场景

集群发生的故障场景有很多,有可能是网卡故障导致节点隔离,也有可能是链路问题导致节点隔离。链路问题本身又分很多种,有一种场景及时存在第三仲裁的场景下,依然有可能是对称平衡的状态。如下图所示:

如图所示,当两个中心之间的链路中断,但是其他各条线路都完好无损的情况下,及时存在第三方仲裁,那么集群分裂后的仲裁资源分布依然是平衡对称的,这又该如何解决呢?

我们认为有两种解决方式:

  1. 优先级定义解决方案,也就是说我们在第二节提到的解决方案必须成为容灾设计的必选项。

  2. 仲裁争夺方案,无论是三方的网络仲裁还是存储仲裁,假设出现集群隔离故障后各个节点开始争夺这个资源,那么必然有先后顺序之分,先到先得的规则来重新定义集群新秩序。这种方案尤其适用于以HA模式的容灾架构。当然具体如何争夺,如何确认争夺维度及结果就需要根据不同产品架构来探讨了。

4. 仲裁冲突问题

4.1什么是仲裁冲突?

我们知道在容灾整体设计当中,需要有网络层、计算层、数据库服务层、存储服务层等各方面的设计。

他们在纵向上是叠加的形态。如图所示:

上图是我们将容灾设计当中纵向抽象出来的几个功能层,其中数据跨中心复制是实现双活容灾的前提条件,它是支撑网络及计算层具备容灾意义的基础,那么如何实现数据复制,我们在《企业容灾选型指南- 2:数据复制技术》当中介绍了很多方法,基本上集中在数据库层和存储层去实现。假设我们采用了存储层的数据复制技术,存储层提供的虚拟分布式卷对于数据库集群来讲是透明的。

当数据中心之间发生线路故障的时候,数据库集群和存储网关组成的集群是两个不同的集群,他们的仲裁结果会不会不一致?

集群的仲裁是瞬间完成的,集群的仲裁触发条件有可能有片刻的先后顺序之差,数据库层的仲裁先于存储层的仲裁,那么虽然概率小,但是这个冲突是完全有可能的。但是如果存储的仲裁发生在数据库之前,理论上这个冲突是可以避免的,因为存储卷是数据库集群健康运行的前提。

4.2 如何解决仲裁冲突问题?

以 Oracle RAC 和VPLEX结合的架构为例,我们探讨它的解决方法。

风险发生的引发点有两个:

① 集群的仲裁触发 条件导致的仲裁顺序发生紊乱;

② 对称平衡状态下的仲裁规则冲突。

资源被1:1割裂之后的默认仲裁策略不一致。也就是说,只要控制这两个引发点,那么这个问题从理论上也就避免了。对于第一个引发点来讲,实际上存储集群的默认仲裁触发时间会是15秒左右,而数据库仲裁触发的控制参数由misscount这个参数来决定,所以只要我们将misscount这个参数调整到 1 5秒之后,也就是说理论上绝对保障存储集群仲裁在前,而数据库仲裁在后,那么第 1 个引发点就没有了。对于第二个引发点来讲,假设两站点节点资源对等,仲裁选票同样对等的情况下,存储集群会有一个默认的Winner策略,同样在这种情况下数据库集群也有一个默认仲裁策略:选择实例号小的集群存活。只要我们保证这两个策略结果的一致性,那么第 2 个引发点也就不存在了。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

1

添加新评论1 条评论

study123study123系统架构师, ERICSSON
2021-07-22 09:22
难得的干货!谢谢分享! 怎么没见到3呢? 谢谢!

aixchina@study123 https://www.talkwithtrend.com/Article/256121这是第三篇

2021-07-22 09:37
Ctrl+Enter 发表