您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

高可用集群系统如何防止脑裂

时间:2019-09-27 12:00:51  来源:  作者:

脑裂(split-brain),指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。

对于无状态服务的HA,无所谓脑裂不脑裂;但对有状态服务(比如MySQL)的HA,必须要严格防止脑裂。(但有些生产环境下的系统按照无状态服务HA的那一套去配置有状态服务,结果可想而知...)

高可用集群系统如何防止脑裂

 

如何防止HA集群脑裂

一般采用2个方法

1. 仲裁

当两个节点出现分歧时,由第3方的仲裁者决定听谁的。这个仲裁者,可能是一个锁服务,一个共享盘或者其它什么东西。

2. fencing

当不能确定某个节点的状态时,通过fencing把对方干掉,确保共享资源被完全释放,前提是必须要有可靠的fence设备。

理想的情况下,以上两者一个都不能少。

但是,如果节点没有使用共享资源,比如基于主从复制的数据库HA,我们也可以安全的省掉fence设备,只保留仲裁。而且很多时候我们的环境里也没有可用的fence设备,比如在云主机里。

那么可不可以省掉仲裁,只留fence设备呢?

不可以。因为,当两个节点互相失去联络时会同时fencing对方。如果fencing的方式是reboot,那么两台机器就会不停的重启。如果fencing的方式是power off,那么结局有可能是2个节点同归于尽,也有可能活下来一个。但是如果两个节点互相失去联络的原因是其中一个节点的网卡故障,而活下来的正好又是那个有故障的节点,那么结局一样是悲剧。

所以,单纯的双节点,无论如何也防止不了脑裂。

没有fence设备是否安全

以PostgreSQL或MySQL的数据复制为例来说明这个问题。

在基于复制的场景下,主从节点没有共享资源,所以2个节点都活着本身没有问题。问题是客户端会不会访问到本该死掉的那个节点。这又牵扯到客户端路由的问题。

客户端路由有几种方式,基于VIP,基于Proxy,基于DNS或者干脆客户端维护一个服务端地址列表自己判断主从。不管采用哪种方式,主从切换的时候都要更新路由。

基于DNS的路由是不太靠谱的,因为DNS可能会被客户端缓存,很难清干净。

基于VIP的路由有一些变数,如果本该死掉的节点没有摘掉自己身上的VIP,那么它随时可能出来捣乱(即使新主已经通过arping更新了所有主机上的arp缓存,如果某个主机的arp过期,发一个arp查询,那么就会发生ip冲突)。所以可以认为VIP也是一种特殊的共享资源,必需把它从故障节点上摘掉。至于怎么摘,最简单的办法就是故障节点发现自己失联后自己摘,如果它还活着的话(如果它死了,也就不用摘了)。如果负责摘vip的进程无法工作怎么办?这时候就可以用上本来不太靠谱的软fence设备了(比如ssh)。

基于Proxy的路由是比较靠谱的,因为Proxy是唯一的服务入口,只要把Proxy一个地方更新了,就不会发生客户端误访问的问题了,但是也要考虑Proxy的高可用。

至于基于服务端地址列表的方法,客户端需要通过后台服务判断主从(比如PostgreSQL/MySQL会话是否处于只读模式)。这时,如果出现2个主,客户端就会错乱。为防止这个问题,原主节点发现自己失联后要自己把服务停掉,这和前面摘vip的道理是一样的。

因此,为了不让故障节点捣乱,故障节点应该在失联后自己释放资源,为了应对释放资源的进程本身出现故障,可以加上软fence。在这个前提下,可以认为没有可靠的物理fence设备也是安全的。

主从切换后数据能否保证不丢

主从切换后数据会不会丢和脑裂可以认为是2个不同的问题。还以PostgreSQL或MySQL的数据复制为例来说明。

对PostgreSQL,如果配置成同步流复制,可以做到不管路由是否正确,都不会丢数据。因为路由到错误节点的客户端根本写不进任何数据,它会一直等待从节点的反馈,而它以为的从节点,现在已经是主子了,当然不会理它。当然如果老是这样也不好,但它给集群监视软件纠正路由错误提供了充足的时间。

对MySQL,即使配置成半同步复制,在超时发生后,它可能会自动降级为异步复制。为了防止MySQL的复制降级,可以设置一个超大的rpl_semi_sync_master_timeout,同时保持rpl_semi_sync_master_wait_no_slave为on(即默认值)。但是,这时如果从宕了,主也会hang住。这个问题的破解方法和PostgreSQL是一样的,或者配置成1主2从,只要不是2个从都宕机就没事,或者由外部的集群监视软件动态切换半同步和异步。

如果本来就是配置的异步复制,那就是说已经做好丢数据的准备了。这时候,主从切换时丢点数据也没啥大不了,但要控制自动切换的次数。比如控制已经被failover掉的原主不允许自动上线,否则如果因为网络抖动导致故障切换,那么主从就会不停的来回切,不停的丢数据,破坏数据的一致性。

如何实现上面的策略

你可以自己完全从头开始实现一套符合上述逻辑的脚本。但我更倾向于基于成熟的集群软件去搭建,比如Pacemaker+Corosync+合适的资源Agent。Keepalived我是极不推荐的,它就不适合用于有状态服务的HA,即使你把仲裁,fence那些东西都加到方案里,总觉得别扭。

使用Pacemaker+Corosync的方案也有一些注意事项

1)了解资源Agent的功能和原理

了解资源Agent的功能和原理,才能知道它适用的场景。比如pgsql的资源Agent是比较完善的,支持同步和异步流复制,并且可以在两者之前自动切换,并且可以保证同步复制下数据不会丢失。但目前MySQL的资源Agent就很弱了,没有使用GTID又没有日志补偿,很容易丢数据,还是不要用的好,继续用MHA吧(但是,部署MHA时务必要防范脑裂)。

2)确保法定票数(quorum)

quorum可以认为是Pacemkaer自带的仲裁机制,集群的所有节点中的多数选出一个协调者,集群的所有指令都由这个协调者发出,可以完美的杜绝脑裂问题。为了使这套机制有效运转,集群中至少有3个节点,并且把no-quorum-policy设置成stop,这也是默认值。(很多教程为了方便演示,都把no-quorum-policy设置成ignore,生产环境如果也这么搞,又没有其它仲裁机制,是很危险的!)

但是,如果只有2个节点该怎么办?

一是拉一个机子借用一下凑足3个节点,再设置location限制,不让资源分配到那个节点上。

二是把多个不满足quorum小集群拉到一起,组成一个大的集群,同样适用location限制控制资源的分配的位置。

但是如果你有很多双节点集群,找不到那么多用于凑数的节点,又不想把这些双节点集群拉到一起凑成一个大的集群(比如觉得不方便管理)。那么可以考虑第三种方法。

第三种方法是配置一个抢占资源,以及服务和这个抢占资源的colocation约束,谁抢到抢占资源谁提供服务。这个抢占资源可以是某个锁服务,比如基于zookeeper包装一个,或者干脆自己从头做一个,就像下面这个例子。

http://my.oschina.net/hanhanztj/blog/515065

(这个例子是基于http协议的短连接,更细致的做法是使用长连接心跳检测,这样服务端可以及时检出连接断开而释放锁)

但是,一定要同时确保这个抢占资源的高可用,可以把提供抢占资源的服务做成lingyig高可用的,也可以简单点,部署3个服务,双节点上个部署一个,第三个部署在另外一个专门的仲裁节点上,至少获取3个锁中的2个才视为取得了锁。这个仲裁节点可以为很多集群提供仲裁服务(因为一个机器只能部署一个Pacemaker实例,否则可以用部署了N个Pacemaker实例的仲裁节点做同样的事情。)。但是,如非迫不得已,尽量还是采用前面的方法,即满足Pacemaker法定票数,这种方法更简单,可靠。



Tags:脑裂   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
ZK(zookeeper)是微服务解决方案中拥有服务注册发现最为核心的环境,是微服务的基石。作为服务注册发现模块,并不是只有ZK一种产品,目前得到行业认可的还有:Eureka、Consul。这里我...【详细内容】
2021-03-04  Tags: 脑裂  点击:(179)  评论:(0)  加入收藏
脑裂(split-brain),指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。...【详细内容】
2019-09-27  Tags: 脑裂  点击:(161)  评论:(0)  加入收藏
▌简易百科推荐
本文分为三个等级自顶向下地分析了glibc中内存分配与回收的过程。本文不过度关注细节,因此只是分别从arena层次、bin层次、chunk层次进行图解,而不涉及有关指针的具体操作。前...【详细内容】
2021-12-28  linux技术栈    Tags:glibc   点击:(3)  评论:(0)  加入收藏
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(2)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(10)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(20)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(25)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(25)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条