前两天,听了公司DBA老大的分享,也是首次接触到了MGR这个架构,其对MGR的大力推崇,让作为业务开发人员的我也对其产生了兴趣,至此,用同事“老司机”的话说,是时候学习一波了。
一、CAP与MySQL
谈MGR之前,先要熟悉一下CAP与MySQL的关系。当前MySQL的master-slave架构,取AP舍C,嗯嗯,DBA们的PPT就是这样告诉俺们的。
C:(consistency)一致性,之前在同事分享时,大家一起讨论过什么叫一致性,后来能让大家比较认同的解释是:“违背了预定的一致性约束,就是违背了一致性”,这话看起来跟没说似的,但是其强调了一个很重要的点,即“约束条件”。例如,一张表的某个字段在现实世界中是唯一unique的,只是在建表的时候没指定unique key,然后某一天出了故障,插入了两条相同字段的record,这种情况,也应该算是违背了一致性的。只是一般在分布式系统的背景下,大家默认的理解都将其限定在不同节点的value是否一致这个更窄的概念上,以方便讨论。
A:(availability)可用性,指所有的读写请求,在有限的时间内都能获得响应。我理解的A,应该是指一个request到达server之后,server能够在有限的时间内,发出一个response。不能把client-server看成整个系统,client发出的一个request根本就没到达server,自然不会有response。你把人家机房的光缆挖断了,然后挑战人家系统的可用性,这就蛋疼了。换个例子,比如server的CPU飙到最高了,这时候来一个request,server直接不处理,给丢了,这才是系统可用性应该考虑的范畴。
P:(partition-tolerance)分区容忍性,这个一直是个很容易让人困惑的概念,我比较认同的一个解释是:“在网络分区的情况下,被分隔的节点仍能正常对外服务”。就是说,由于网络的因素,将原本联通的分布式系统,分隔成彼此无法通信的一个个子集了,这时候这个单独的子集能够继续对外提供服务。
个人理解:
1. 对于CAP别较真,网上一搜,众说纷纭,去扣CAP的概念、证明(至于那个反证的证明,着实蛋疼)都没意义,还容易疯。就是一个在设计系统的时候的参考,核心指导作用是说在设计的时候,别去追求完美,实事求是,具体问题具体分析,get这一点就足以了。
2. 在CAP中,没有舍谁取谁的,都是权衡罢了。这世间之事吧,就从来没有非此即彼。
接下来就以CAP的角度说说MySQL的master-slave架构:
所谓master-slave架构,就是由master负责写,slave负责读,然后将master的binlog不断的发送到slave执行,使整个DB集群达到一致。先来说P,master与slave节点失联之后,木有关系,master还是负责client发过来的写请求,slave还是负责读请求,大家各司其职,也就实现了P,同时,由于master的数据无法同步给slave了,也就自然无法保证C了。还有就是哪怕在网络非常健康的情况,master与slave存在的延迟,也使整个集集群无法实现强一致。既然存在问题,也就必然存在着问题的解决之道,接下来就来说说MGR。
二、MySQL group replication
在默认情况下,MySQL的复制(replication)策略是异步(asynchronous)复制,如下图:
图有点毛病,一般是在事务commit之后,才将binlog发送到slave,但问题是一样的,就是C太弱了,master将binlog发送出去之后,就不管了。要是slave没收到,那系统自然就不一致了,既然C太弱了,就可以想办法来保障C,比如采取半同步(semi-synchronous)的策略:
也即master等每一个slave ACK之后,再提交事务,告诉client这次的更新成功了。如此,就保证commit之后,slave肯定收到binlog了,自然也就提升了C。但问题也就随之而来了,即性能下降了,每一条变更SQL的性能下降带动系统QPS的下降,从而影响了A。此外,当集群中新增节点时,会让系统性能下降。看,问题又来了,那何如平衡C与A呢?MGR就提供了一个解决思路,先看看引入MGR之后,系统大概变成了什么样子:
如图,一个明显的变化就是系统不再区分master与slave了,每个节点都是master,都可以进行写,然后使用一致性算法来实现整个集群的对外一致性。其写过程大概变成了下面酱紫:
也就是在一个节点写完之后,使用一致性协议使整个集群达到一致,然后就可以返回了。指的注意的是,整个集群达到一致,可不是说每个节点都ACK了。通过一致性协议,要比等每个slave都ACK更快,还能让整个DB集群实现多节点写入,对于DB集群的性能来说,自然会有不小的性能提升。根据MySQL官方文档,MGR有两种模式:
single-primary mode:只有主节点负责写,集群能够自动选举主节点
multi-primary mode:所有节点都接受写
贴一下MySQL对于group replication的文档和其性能测评:
文档:https://dev.mysql.com/doc/refman/5.7/en/group-replication.html
性能对比:http://mysqlhighavailability.com/performance-evaluation-mysql-5-7-group-replication/
三、一致性协议
MGR使用了paxos协议来实现集群的一致性。先贴一个分布式系统一致性问题的演示动画:
http://thesecretlivesofdata.com/raft/
协议挺复杂的,咱不就介绍了,明确两个点就得了:
1. 在paxos算法中,过半数的节点同意变量v = 2了,就叫达成一致了
2. 在没一轮写入之后,通过节点之间相互通信、投票,趋于实现达成一致