曾经很多人问我,某银行生产采用Oracle RAC双节点架构,脑裂了怎么办?很多面试Oracle DBA的同学面试过程中也有经常问道:Oracle RAC双节点脑裂了怎么处理?双节点的Oracle RAC真的会脑裂吗?如果你对Oracle RAC集群底层工作原理及机制特别熟悉的话,那么你一定会思考这个问题去寻找答案,官方对于双节点集群脑裂问题也给除了明确的解释,那么会不会脑裂呢?下面我们看看分析一下。
一、Oracle RAC集群心跳仲裁机制。
1、问题1:Oracle 最多支持多少个成员组成RAC集群?
Oracle官方FAQ是这么描述的:
How many nodes can be had in an HP-UX/Solaris/AIX/Windows/Linux cluster?
The number of nodes supported is not limited by Oracle, but more generally by the clustering software/hardware in question.
When using solely Oracle Clusterware: 63 nodes (Oracle 9i or Oracle RAC 10g Release 1) With 10g Release 2, the maximum nodes is 100
When using a third party clusterware:
- Sun: 8
- HP UX: 16
- HP Tru64: 8
- IBM AIX:
- * 8 nodes for Physical Shared (CLVM) SSA disk
- * 16 nodes for Physical Shared (CLVM) non-SSA disk
- * 128 nodes for Virtual Shared Disk (VSD)
- * 128 nodes for GPFS
* Subject to storage subsystem limitations
Veritas: 8-16 nodes (check w/ Veritas)
For 3rd party vendor clusterware, please check with the vendor.
大致意思就是在不同的平台上支持不同规模的集群,做多可支持128个,国外8个成员的很常见,但是国内超过8个的我是没见过,根据我们之前测试,国内某银行RAC集群跑在一台HP 9000系列中Superdome机器不同分区上,整个集群超过4个节点的时候明显ops/tps会有断崖式下降,为此某行大多采用的是2各成员组成的一套RAC集群环境。这里也就牵扯出为何采用2个成员组成集群的原因。
2、问题2:何为仲裁、脑裂?
集群是由多个节点组成的一个协同工作的系统。在计算机集群软件中也有个领导者,我们称之为cluster manager(CM)。集群中的领导者CM一般是通过投票的方式由集群中的所有符合资格的成员(quorum node)采用少数服从多数的原则共同推举产生。被选举出的CM通过网络通信协调各个节点的工作。这就有个问题,当网络出现故障的情况下,部分节点将失去与集群的联系无法得到CM指令,从而产生两个或多个孤立系统,俗称split brain(脑裂)。一个健康的集群是不允许产生脑裂情况的,因为多个无法协调行为的系统一起使用共享数据会造成数据的不一致。
仲裁(voting盘):就是各个节点都可以访问的一个或多个共享存储盘,所以仲裁盘都必须放在可以供所有节点访问的共享存储上,一旦集群心跳网络不通后,各个节点则通过仲裁盘进行通信来做出正确的判断。
脑裂:脑裂(split brain):描述的是私有网络心跳出现故障的时候,而每个节点都正常运行,这时侯每个节点都认为其他的节点宕机了,自己应该获得集群的控制权,rac正常情况下,每秒钟都监听各个节点间的心跳信息,若某个节点在miscount秒内没有被接收到心跳信息,就会形成了两个或多个子集群,这样的状况就是脑裂,如果发生了脑裂,决定子集群存活的因素(voting disk正常的时候)是:
1.拥有节点最多的子集群存活
2.如果两个子集群节点相等,那么节点级别低将别踢出.
当节点别踢出集群以后,为了保证被踢出的节点不能访问共享存储的数据,io fencing来解决这个问题,oracle rac会重启被踢出集群的节点,来保证共享存储的数据。
ORACLE有三种冗余保护模式分别是:
- external(外部)
- normal(正常)
- high(高)
一般情况下三种模式需要的voting磁盘:(voting盘会组成一个OCRVOTE的磁盘组)
- external 1块,即一副本,数据信息只往一块voting盘里写。
- normal 3块,即两副本,数据信息随机往其中两块voting盘里写,保证了断掉一块voting盘后数据信息不丢失。
- high 5块,即三副本,数据信息随机往其中三块voting盘里写,保证了断掉两块voting盘后数据信息不丢失。
- external模式下,如果一块voting盘掉了,voting磁盘组信息丢失,集群就异常停止。
- normal模式下,如果两块voting盘掉了,voting磁盘组信息丢失,集群就异常停止。
- high模式下,如果三块voting盘掉了,voting磁盘组信息丢失,集群就异常停止。
voting disk oracle 建议至少3个以上,即至少使用normal冗余。
3、问题3:表决仲裁的原理是什么?
解决这个问题的通常办法是使用投票算法(Quorum Algorithm). 它的算法机理如下:
集群中各个节点需要心跳机制来通报彼此的"健康状态",假设每收到一个节点的"通报"代表一票。对于三个节点的集群,正常运行时,每个节点都会有3票。 当结点A心跳出现故障但节点A还在运行,这时整个集群就会分裂成2个小的partition。 节点A是一个,剩下的2个是一个。 这是必须剔除一个 partition才能保障集群的健康运行。对于有3个以上节点的集群, A 心跳出现问题后, B 和 C 是一个partion,有2票, A只有1票。 按照投票算法, B 和C 组成的集群获得控制权, A 被剔除。
如果只有2个节点呢?这里就是文章开头说得,两个成员节点之间机制是怎样得呢?
Oracle RAC中Brain Split脑裂决议的一些概念, 几乎所有的Candidate都告诉我当”只有2个节点的时候,投票算法就失效了,会让2个节点去抢占Quorum Disk,最先获得的节点将活下来” 。 我们姑且把这套理论叫做” 抢占论”。“抢占论”的具体观点可能与下面这一段文字大同小异:
观点1-抢占论:
解决这个问题的通常办法是使用投票算法(Quorum Algorithm). 它的算法机理如下:
如果只有2个节点,投票算法就失效了。 因为每个节点上都只有1票。 这时就需要引入第三个设备:Quorum Device. Quorum Device 通常采用饿是共享磁盘,这个磁盘也叫作Quorum disk。 这个Quorum Disk 也代表一票。 当2个结点的心跳出现问题时, 2个节点同时去争取Quorum Disk 这一票, 最早到达的请求被最先满足。 故最先获得Quorum Disk的节点就获得2票。另一个节点就会被剔除。
- 观点2:
先看官方FAQ给出得解释:
1.When interconnect breaks – keeps the largest cluster possible up, other nodes will be evicted, in 2 node cluster lowest number node remains.
2.Node eviction: pick a cluster node as victim to reboot.Always keep the largest cluster possible up, evicted other nodes two nodes: keep the lowest number node up and evict other.
翻译大概意思如下:
1.当互连中断时——保持尽可能大的集群,其他节点将被逐出,在2节点集群中,剩下的节点数最小。
2.节点逐出:选择一个群集节点作为受害者重新启动。始终保持尽可能大的集群,逐出其他节点两个节点:保持数量最少的节点,逐出其他节点。
在脑裂检查阶段Reconfig Manager会找出那些没有Network Heartbeat而有Disk Heartbeat的节点,并通过Network Heartbeat(如果可能的话)和Disk Heartbeat的信息来计算所有竞争子集群(subcluster)内的节点数目,并依据以下2种因素决定哪个子集群应当存活下去:
- 拥有最多节点数目的子集群(Sub-cluster with largest number of Nodes)
- 若子集群内数目相等则为拥有最低节点号的子集群(Sub-cluster with lowest node number),举例来说在一个2节点的RAC环境中总是1号节点会获胜。
结论:
争议主要体现在 ,“抢占论” 认为当 只有2个节点时是通过抢占votedisk 的结果来决定具体哪个节点存活下来,同时” 抢占论”没有介绍 当存在多个相同节点数目的子集群情况下的结论(譬如4节点的RAC , 1、2节点组成一个子集群,3、4节点组成一个子集群), 若按照2节点时的做法那么依然是通过子集群间抢占votedisk来决定。
我个人认为这种说法(“抢占论”)是错误的,根据运维实践也不难发现,2个节点的RAC总是1号获胜,2号重启,不管是具体脑裂时的CRS关键进程css的日志,还是Oracle官方的内部文档都可以说明该问题。实际上有部分Vendor Unix Clusterware集群软件的脑裂可能如确实是以谁先获得 “Quorum disk”为决定因素, 但是自10g 推出的Oracle 自己的Real Application Cluster(RAC) 的clusterware 或者说 CRS( cluster ready services) 在Brain Split Resolution时并非如此,在这方面类推并不能帮助我们找出正确的结论。
所以2个成员节点组成的Oracle RAC集群是一定不会出现脑裂的,因为在一个2节点的RAC环境中总是1号节点会获胜。
二、达梦DMDSC集群心跳仲裁机制。
DM共享存储数据库集群的英文全称DM Data Shared Cluster,简称DMDSC。DM共享存储数据库集群,允许多个数据库实例同时访问、操作同一数据库,具有高可用、高性能、负载均衡等特性。DMDSC支持故障自动切换和故障自动重加入,某一个数据库实例故障后,不会导致数据库服务无法提供。
1、问题1:DMDSC系统机构是什么样的,跟Oracle有什么区别呢?
DMDSC集群是一个多实例、单数据库的系统。多个数据库实例可以同时访问、修改同一个数据库的数据。用户可以登录集群中的任意一个数据库实例,获得完整的数据库服务。数据文件、控制文件在集群系统中只有一份,不论有几个节点,这些节点都平等地使用这些文件,这些文件保存在共享存储上。每个节点有自己独立的联机日志和归档日志,其中联机日志保存在共享存储上,归档日志可以保存在本地存储上也可以保存在共享存储上。
DMDSC集群得以实现的重要基础就是共享存储。DM支持的共享存储有两种:裸设备和DMASM。这两种存储的区别在于后者在前者的基础上,部署并使用了DMASM文件系统。为了方便对裸设备上的磁盘或文件进行管理,推荐用户使用后者。
DMDSC集群主要由数据库和数据库实例、共享存储、本地存储、通信网络、以及集群控制软件DMCSS组成。下面以部署了DMASM的DMDSC集群为例,展示DMDSC集群系统结构:
2、问题2:DMDSC最多支持多少个成员组成集群?
目前DM8以上版本支持最大8个节点共享存储集群。
3、问题2:DMDSC 仲裁脑裂算法?
DMCSS(Dameng Cluster Synchronization Services)达梦集群同步服务,使用DMASM集群或DMDSC集群都必须要配置DMCSS服务。在DMASM集群或DMDSC集群中,每个节点都需要配置一个DMCSS服务。这些DMCSS服务自身也构成一个集群,DMCSS集群中负责监控、管理整个DMASM集群和DMDSC集群的节点称为控制节点(control node),其他DMCSS节点称为普通节点(normal node)。DMCSS普通节点不参与DMASM集群和DMDSC集群管理,当DMCSS控制节点故障时,会从活动的普通节点中重新选取一个DMCSS控制节点。
DMCSS工作的基本原理是:在Voting disk中,为每个被监控对象(dmasmsvr、dmserver、DMCSS)分配一片独立的存储区域,被监控对象定时向Voting Disk写入信息(包括时间戳、状态、命令、以及命令执行结果等);DMCSS控制节点定时从Voting Disk读取信息,检查被监控对象的状态变化,启动相应的处理流程;被监控对象只会被动的接收DMCSS控制节点命令,执行并响应。
DMCSS主要功能包括:写入心跳信息、选举DMCSS控制节点、选取DMASM/DMDSC控制节点、管理被监控对象的启动流程、集群状态监控、节点故障处理、节点重加入等,DMCSS还可以接收并执行DMCSSM指令。DMCSS实例启动后,每间隔1秒向Voting Disk指定区域写入心跳信息(包括自身的状态、时间戳等),表示DMCSS节点处于活动状态。
DMCSS启动后向Voting Disk写入信息,并读取其他DMCSS节点的信息,如果DMCSS集群中还没有活动的控制节点,则选举DMCSS控制节点。DMCSS选举的原则有两条:
- 先启动的DMCSS作为控制节点。
- 如果DMCSS同时启动,那么则选择节点号小的节点为控制节点。
- 如果DMCSS控制节点挂掉,那么会将先向Voting Disk写入心跳信息的节点设置为控制节点;若同时有多个节点先向Voting Disk写入心跳信息,那么选择节点号小的节点为控制节点。
DMCSS控制节点启动后,会为基于DMASM/裸设备的DMDSC集群指定控制节点。DMCSS选取监控对象控制节点的原则有两条:
-
只有一个活动节点,则设置活动节点为控制节点。
-
存在多个活动节点,则选择节点号小的节点为控制节点。
注: DMCSS控制节点每秒从Voting Disk读取被监控对象的心跳信息。一旦被监控对象的时间戳在DCR_GRP_DSKCHK_CNT秒内没有变化,则认为被监控对象出现异常。
DMCSS普通节点定时读取DMCSS控制节点的心跳信息,监控DMCSS运行状态。
结论:
读到这里越读越是不是觉得DMDSC跟Oracle RAC是不一样的呢,是不是感觉有点儿像Mysql的3M(MMM)架构了,也有点MHA(MHA 的manager节点存在点单问题,DMDSC不存在,解决了管理服务单点问题)或者redis sentinel哨兵模式的味道呢,故障选取自动转移。这里就不过多的表述关于MySQL和Redis 的具体原理了。感兴趣的可以去看看,在我看在大多故障转移都是采用一定选举算法。DMDSC基本上选举是通过集群组件DMCSS组件控制节点感知Voting 信息来相互通讯感知的。
4、DMDSC表决磁盘和仲裁机制如何?
DM官方给出的结论是DMDSC是不会出现脑裂问题的,因为一旦具备脑裂的发生条件,DMDSC集群的DMCSS会做一些预处理,避免脑裂问题。具体如下:
DMCSS控制节点检测到实例故障后,首先向故障实例的Voting disk区域写入Kill命令(所有实例一旦发现Kill命令,无条件自杀),是不是有点儿胆大心细,简单粗暴呢,避免故障实例仍然处于活动状态,引发脑裂,然后启动故障处理流程,不同类型实例的故障处理流程存在一些差异。
-
DMCSS控制节点故障处理流程
-
活动节点重新选举DMCSS控制节点
-
新的DMCSS控制节点通知出现DMCSS故障节点对应的dmasmsvr、dmserver强制退出
-
DMASMSVR实例故障处理流程
-
挂起工作线程
-
更新DCR的节点故障节点信息
-
通知故障节点对应dmserver强制退出
-
dmasmsvr进行故障恢复
-
恢复工作线程
-
dmserver实例故障处理流程
-
更新DCR故障节点信息
-
重新选取一个控制节点
-
通知dmserver控制节点启动故障处理流程(参考DMDSC故障处理)
-
等待dmserver故障处理结束
-
节点重加入
如果检测到故障节点恢复,DMCSS会通知控制节点启动节点重加入流程。
- 数据库实例重加入
-
挂起工作线程
-
修改节点的状态
-
执行恢复操作
-
重新进入STARTUP状态,准备启动
-
OPEN重加入的节点
-
重启工作线程
-
执行OPEN数据库实例的操作
- DMASM实例重加入
-
挂起工作线程
-
修改节点的状态
-
执行恢复操作
-
重新进入STARTUP状态,准备启动
-
OPEN重加入的节点
-
重启工作线程。
最后,总结得出:在架构设计方面DMDSC与Oracle RAC很相似,但是在内部工作机制上其实我觉得DMDSC在Oracle RAC基础上也做了很大的区别,而且整合借鉴了Mysql MMM和MHA与的一些好的做法,并且完善了有些缺陷,比如MHA 的manager管理节点单点故障问题。DMDSC不管是几个成员节点,都是不会出现脑裂这种情况的呢。