改朝换代:MySQL Group Replication

​Paxos将成为这个新时代的主宰,这点姜老师深信不疑。四五年前甚至知道现在,仍有很多人怀疑MySQL是否能取代Oracle数据库,多年后腾讯、网易、阿里等互联网公司们用自己的实际案例大声地告诉那些土老冒们,开源数据库早已不是玩具数据库,他们才将站在下个世纪的浪潮之巅。

开源数据库在新王登基的道路上,正是由于有了Paxos一致性协议的辅佐,未来数据一致性与可靠性将不再成为用户选择开源数据库时的疑问,相反以Paxos为基础的数据高可用保障将成为数据库未来的事实标准。区区甚至敢大胆断言用不了多久,基于Paxos的KV系统,数据库系统、分布式文件系统、消息队列将随处可见,而MySQL Group Replication将成为其中的爆款。

这里顺便说下Raft协议,Paxos虽然工程上较难实现,但总会出现一个成熟且可靠的Paxos开源算法,正如腾讯开源的PhxPaxose库一样。

或许很多同学觉得Paxos不好理解,但若能静心阅读[1]、[2]、[3]三篇论文,将会发现Paxos或许并没有这么难以理解。

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

MySQL Group Replication(下简称:MGR)是MySQL官方推出的一种基于Paxos协议的状态机复制。在MGR出现之前,用户常见的MySQL高可用方式,无论怎么变化架构,本质就是Master-Slave架构。MySQL 5.7版本开始支持无损半同步复制(lossless semi-sync replication),从而进一步提示数据复制的强一致性。

Master-Slave始终无法解决的一个问题是选主(Leader Election),特别是当由于网络分区发生脑裂时,目前大多的高可用解决方案都会导致双写的问题,这在金融场景下显然是无法接受的。为避免此问题的发生,有时不得不强行关闭一台服务,从而保证同一时间只有一个节点可以写入,然而这时数据库集群可用性又可能会收到极大的影响。

MongoDB、TiDB这些出现的后起之后通过Raft协议来进行选主,从而避免脑裂问题的产生。然而他们依然是单写的场景,即一个高可用集群下,写入依然是单个节点。

MGR的解决方案现在来看可说非常完美:

  • 数据一致性保障:确保集群中大部分节点收到日志
  • 多节点写入支持:多写模式下支持集群中的所有节点都可以写入
  • Fault Tolerance: 确保系统发生故障(包括脑裂)依然可用,双写对系统无影响

从MGR公布的特性来基本是数据库所追求的最终完美形式。然而很多同学还会问MGR和无损半同步复制的区别,比如1个集群5个节点,无损半同步复制可以设置至少有2个节点收到ACK请求再提交事务,也能保障数据一致性。

Quorum原则(大部分原则)只是Paxos实现的一小部分,因此无损半同步复制解决的只是日志完整性的问题。若把日志看成是value,则只是解决了日志丢失问题。但是如何在分布式异常场景下确定这个value值,则需要Paxos协议来解决。比如,当发生脑裂情况下,谁是Primary,则MGR通过Paxos协议可以清楚的判断,从而避免双写问题。

MGR默认是Single Primary模式,用户可以通过下面的命令找出集群中的Primary(Leader)节点,这在传统的复制架构下并不能通过数据库本身感知:

mysql> SELECT VARIABLE_VALUE FROM performance_schema.global_status

->  WHERE VARIABLE_NAME= 'group_replication_primary_member';

MGR另一个模式为Multi-Primary模式。对Paxos协议比较熟悉的同学会说Paxos本身就支持多写的。的确,然而为了解决活锁的性能问题,Paxos的实现大多是Single Leader模式。很明显Leader节点会成为一个瓶颈,所以MGR并没有使用传统的Multi-Paxos算法,而是使用了Mencius算法,解决了单Leader写入性能瓶颈问题。

通过Mencius算法进一步优化Paxos的多写场景是可能的,然而数据库的复杂之处在于写入的数据之间可能是有依赖冲突的。比如节点1、节点2都在对记录1进行更新,在Multi-Primary模式MGR会开启冲突检测机制,并遵循Commit First原则。

最后来看看MGR真正的伟大之处:

  • 采用更先进的Mencius算法,而非传统的Multi-Paxos算法
  • 支持节点多写,并通过冲突检测机制保证同时写入的数据之间不会冲突

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

近期MySQL 5.7.19版本发布,修复并改进之前MySQL Group Replication(下简称:MGR)的一些问题。随着跨IDC数据强一致需求的不断出现,是时候将5.7的无损复制与MGR做一个正面的对比。

测试采用sysbench,10张表,每张表1亿数据量,总共数据量大小240G,BP 60G。另外,测试未采用默认的OLTP测试,该测试压力太小。这里选用了读写1:1的测试,即一个事务里有4条根据主键的SELECT,4个DML操作,这样在测试过程中可将I/O压满。测试的语句如下:

sysbench ./src/lua/oltp_read_write.lua --table_size=100000000 --tables=10 --rand-spec-res=75 --threads=128 --time=3600 --warmup-time=100 --report-interval=3 --point_selects=4 --non_index_updates=1 --delete_inserts=1 --index_updates=1 --simple_ranges=0 --order_ranges=0 --range_selects=off  run

测试服务器的配置信息大致如下:

配置说明
CPU 24 Core E5-2620 v3 @ 2.40GHz
内存 128G
存储 Intel DC P3600 2TB NVMe PCIe 3.0

对于MGR一些核心的配置如下所示,主要是开启了Multi-Primary模式:

group_replication_compression_threshold=100

group_replication_flow_control_mode=0

group_replication_single_primary_mode=0

group_replication_enforce_update_everywhere_checks=1

由于本次测试主要目标是金融业务场景下的数据一致性的测试,故而这里将测试分为了同城跨IDC强同步复制和跨城跨机房强同步复制:

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

同城跨IDC强同步复制

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

跨城跨IDC强同步复制

同城跨IDC和跨城跨IDC的场景下,由于至少有大部分服务器在远程IDC,因此远程IDC机房的数据库服务器可以马上接管。然而机房之间的网络并不可靠(即使是同城IDC),那么同城跨IDC架构在网络抖动时,可能发生IDC1机房的写入被hang住,在半同步复制场景下这是一个令人困扰的问题。

跨城跨IDC架构(通常说的两地三中心)的好处在于避免了同城机房网络之间不可靠的问题,当发生网络问题时,另一个机房也能接管,极大的缓解hang住的问题。

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

在同城跨IDC的场景下,异步复制能拿到11W+ QPS,而这时半同步复制的性能就显得比较一般了,只有异步的35%左右的性能。after_sync比after_commit模式性能更好些。而MGR的性能有接近异步的60%性能,非常不错的性能测试结果。如果将after_commit作为性能测试基线,则:

性能提升
after_commit /
after_sync +4.5%
MGR +64.8%
async +197.1%

MGR在同城跨机房IDC的测试结果着实令人兴奋,当然这里很重要的原因之一在于MGR可以对复制的日志进行压缩,见上述的参数group_replication_compression_threshold。然而,在跨城跨IDC的场景测试下,测试结果却出现了逆转:

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

未曾料到的是在跨城跨IDC场景下MGR的性能出现了大幅下降,而半同步复制却依旧不会有太大的变化。既然Paxos遵循大部分原则,那么一台数据库服务器在跨城IDC性能应该不受影响才对。

​Paxos将成为这个新时代的主宰,这点姜老师深信不疑。四五年前甚至知道现在,仍有很多人怀疑MySQL是否能取代Oracle数据库,多年后腾讯、网易、阿里等互联网公司们用自己的实际案例大声地告诉那些土老冒们,开源数据库早已不是玩具数据库,他们才将站在下个世纪的浪潮之巅。

现在是时候来好好研究Mencius算法。该算法为了解决单Leader写入瓶颈问题,设计了如下的实现机制[4]:

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

上图的三个节点P0,P1,P2,他们分别写入对应的Instance编号(slot号)为:

  • 0、3、6、.... 、3n+0
  • 1、4、7、... 、3n+1
  • 2、5、8、...、3n+2

由于每个节点都可以是Leader,因此能够相对减少网络和CPU的开销,从而一定程度上提升集群的整体性能,这在多节点场景下会更明显,比如有5个或甚多的节点场景下[4]。

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

因为每个节点写入的Instance编号是固定的(这与Multi-Paxos不同),因此当P1没有操作时会发出一个noop消息(特殊的propose消息,上图中为skips消息),让集群中的其他节点可以正常运行。因此在Mencius算法中,集群的性能受限于性能最差的一个节点。这也就是为什么在上述跨城跨IDC测试中,MGR的性能下降的重要原因,而半同步复制不存在这样的问题。

从优化的角度来看需要给集群中的每个节点定义一个角色,比如将跨城跨IDC的节点定义为只是acceptor节点,这样就不需要发送noop消息从而避免性能退化的问题。和官方MySQL开发人员交流后,发现官方也已注意到此问题,相信不久的将来就会对此进行优化,那时真正的MySQL时代将会君临天下。

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

关于MGR的Multi-Primary模式,虽然Menius算法可以解决网络开销,然而如果更新的数据有重叠,则冲突检测机制会回滚其中的一个事务。故当冲突非常多时,Multi-Priamry模式的MGR整体的性能将会退化。

因此对于Multi-Priamry模式,可以在大多数情况下只允许一个节点接入,其他节点依旧打开super_read_only选项。当发生故障时,再做额外处理即可。

另一种使用Multi-Priamry模式的场景是,假设一个数据库实例下有User库、Order库、Log库。则可根据库的原则进行多节点写入,这样能极大地提升集群写入的扩展性。

当网络带宽并非瓶颈,而且写入的数据之间冲突不大的场景下(需要业务控制),这时Multi-Primary模式能发挥最大的价值。在跨城跨IDC的场景下,虽然MGR性能退化较为严重,但若启用Multi-Primary模式的话,性能可以有一定幅度的提升。在三节点同时写入的场景下性能能有1倍的提升。

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

改朝换代:MySQL Group Replication-MySQL社区 Inside MySQL Group

正如我半年前的文章Galera已死,MySQL Group Replication正式发布中说的那样,PXC真的已经OUT了,除非PXC将其同步算法改为Paxos,但这样和MGR又有何区别?回头再看看其他数据库的高可用解决方案,不论是Oracle RAC、亦或是之前银行中大量使用的共享存储方案,对比MGR都已黯然褪色。天下武功,唯快不破,赶快加入到Paxos这个新王朝吧。

参考文献

  1. In Search of an Understandable Consensus Algorithm
  2. Paxos made simple
  3. Paxos make live
  4. Mencius: Building Efficient Replicated State Machines for WANs
  5. “The king is dead, long live the king”: Our Paxos-based consensus
发表评论

坐等沙发
相关文章
IMG社区MySQL技术沙龙南京站圆满结束
IMG社区MySQL技术沙龙南京站圆满结束
数据库行业的朋友圈内幕,不知道就没法混了
数据库行业的朋友圈内幕,不知道就没法…
Inside MySQL Group社区启用新LOGO
Inside MySQL Group社区启用新LOGO
MySQL 5.7 semi-sync 1024 bug 修复
MySQL 5.7 semi-sync 1024 bug 修复
MySQL超越Oracle了?
MySQL超越Oracle了?
MySQL REPLACE死锁问题深入剖析
MySQL REPLACE死锁问题深入剖析
Oracle MySQL ACE. Author of Inside MySQL and MySQL Core Series. Great at MySQL performance tuning、troubleshooting、systems availability and scalability、capacity planning, etc.

一触即发,2017年,数据库世界的诸神之战