InnoSQL HA Suite的实现原理与配置说明

Virtual Sync Replication

搭建一个MySQL数据库的复制(replication)环境是相当简单的,这点是MySQL数据库的优势,特别是对比Oracle DataGurad、Microsoft SQL Server Mirroring来说。但是,一个令人烦恼的问题就是MySQL的复制是极易出错的,例如常见的1062、1053、1032错误。因此,我一直强调这样一个观点:搭建一个严格的、符合生产环境复制需求的是有极大的挑战。如果根据我的标准来看,可能很多公司、甚至是所谓的大公司线上的复制配置都没有达到严格的标准。MySQL 5.6支持了crash safe功能,开启该功能可以解决很大一部分的问题。

然而很多时候,用户还抱怨MySQL的复制,不支持数据不丢失的场景。这也就是说,使用MySQL的复制功能就注定了需要承担数据丢失的风险,这点上MySQL数据库对比Oracle、Microsoft SQL Server来说就显得有些不足了。更糟的是,这造成了MySQL DBA这样的一个印象,数据是可以丢失的。从数据库的设计角度来说,ACID的目的之一就是保证数据的持久性,简单来说就是数据不可丢失。如果容忍丢失的话,那么用户的选择其实可以有很多,比如MongoDB、Redis等NoSQL数据库。

当然,MySQL数据库紧密的与互联网应用绑定,或许互联网应用本身并不强调数据的不可丢失性。例如博客、微薄这样的一些应用,但是从开发人员以及DBA的角度来看,我们需要确保提交的数据在宕机后可以恢复。当然,可以结合一些应用来实现这样的效果,例如应用程序记录每个操作日志,但是恢复会是一个比较麻烦与漫长的过程。

MySQL 5.5版本引入了半同步复制(semi-sync replicaiton)的功能,但是这同样会导致数据丢失的问题,只是丢失的内容会变得少。淘宝的周振兴提出了enhanced semi-sync replication的想法[1],并在5.5中予以实现。但是他的方案性能较差,并未能在淘宝内部得以广泛的使用。InnoSQL借鉴了周振兴的想法,并结合了组提交优化,通过减少fsync的次数来抵消网络的开销,此外可以通过增大组提交的比例来进一步优化性能,在InnoSQL中把这种实现称之为virtual sync replication(VSR),并已经在网易公司内部广泛的得以使用。

MySQL 5.7版本终于实现了类似的机制,称之为loss-less replication[2],相信随着5.7版本发布,越来越多的用户会拥抱这样功能。可惜的是,5.7版本离生产环境的使用至少还需要1年时间的等待。所以说InnoSQL是用户一个很好的选择,5.5版本就保证主从数据的完全一致性。

实现原理与机制

首先,virtual sync replication是基于MySQL原生的semi-sync replication技术实现的,因此非常易于理解。简单来说,VSR的实现就是调整了semi-sync的提交与等待顺序,原先semi-sync的等待顺序过程为:

  1. InnoDB引擎层prepare事务
  2. MySQL层写二进制日志
  3. InnoDB引擎层commit事务
  4. 通过复制的dump线程发送二进制日志event
  5. 等待接受从机的ACK回复

这样的处理机制会存在这样一个问题,由于步骤4的时候,事务已经提交,那么之前事务所做的修改对其他用户已经是可见的了,那么当发生宕机进行主从切换时,slave上可能会不存在之前已经存在的数据。VSR机制在于改变了3和4的步骤,这样保证在发送二进制日志的event时,事务没有提交,数据不可见,那么当进行主从故障切换时,不会存在上述semi-sync replication的问题。VSR的实现机制见下图:

InnoSQL HA Suite的实现原理与配置说明-MySQL社区 Inside MySQL Group

Virtual Sync Replication的实现机制

有用户可能会对VSR的性能抱有担心,的确网络的延迟是无法避免的,这决定了VSR的性能会比异步的复制要差。但是VSR的性能会比semi-sync复制的性能要好很多。其实这是非常容易理解的,因为步骤3,4交换顺序后,可以极大的提高组提交的比例,从而减少fysnc的次数,提高性能,这就是前面说的,通过减少fsync来减缓网络延迟带来的开销。Facebook也有类似VSR的实现机制(FB称之为semi synchronous replication),他们也证实了VSR的性能要比semi-sync来得好[3]

HA Suite(MySQL双机高可用套件)

仅仅通过VSR机制就能保证主从数据的完全一致性吗?很可惜,还是不能。VSR还是与semi-sync一样,存在故障切换后,原master服务器的数据比slave多的情况。这是因为上述的步骤2已经写二进制日志了,master故障恢复后依然会提交该事务,但是这部分二进制日志可能会没有传送到slave。但是VSR和semi-sync不同的是,由于事务还在提交过程中,数据对其他事务不可见,这意味着,这部分已经写入到二进制日志的事务可以回滚。这部分的操作,最早通过外部脚本来控制,后来InnoSQL决定将这部分的工作交由数据库自己来完成,最后以一个高可用的套件形式来展现给用户,那么这部分的操作对用户来说就都是透明的了。

要配置HA Suite是及其简单的,假设复制环境的主服务器为192.168.1.2,从服务器为192.168.1.3,那么将其配置为双主的形式,启用semi-sync replication的插件,然后进行类似如下的配置:

[mysqld]
binlog = mysqld-bin#开启二进制日志,搭建双主环境
sync_binlog = 1 #保证crash safe
innodb_flush_log_trx_commit = 1 #保证crash safe
rpl_semi_sync_master_timeout = 100000000 #不要超时,防止切异步,保证主从数据的完全一致性
rpl_semi_sync_master_commit_after_ack = 1 #启用VSR功能
enable_table_relay_info = 1 #开启crash safe功能
relay_log_recovery = 1 #开启crash safe功能
slave_parallel_threads=16 #并行复制的线程数
ha_partner_host = 192.168.1.3 #配置partner服务器(另一台配置为192.168.1.2)
ha_partner_user = xxx #连接partner服务器的数据库用户,用户直接使用复制的用户即可
ha_partner_password = xxx #连接partner服务器的数据库用户密码
ha_partner_port = 3306
read_only = 1 #可选配置

可以看到对于VSR来说最为重要的就是网络,对于网络的要求极高,当然这也非常容易理解,这对于Oracle DataGurad、Microsoft SQL Server Mirroring来说也是一样的要求。HA Suite配置之前介绍的并行复制功能,又能极大的提高从机的性能,同时又能缩短故障恢复的时间。

关于InnoSQL

InnoSQL是国产MySQL版本,并且遵守GPL v2协议,对开源所有修改的代码。InnoSQL针对互联网与传统金融企业的数据库应用进行性能优化与数据保障。

InnoSQL技术讨论QQ群:166583560
InnoSQL官方网站:www.innosql.net
InnoSQL社区论坛:http://bbs.chinaunix.net/forum-324-1.html
InnoSQL公众账号:InsideMySQL
InnoSQL微薄:@InnoSQL

参考文献

  1. https://code.google.com/p/enhanced-semi-sync-replication/
  2. http://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html
  3. http://yoshinorimatsunobu.blogspot.com/2014/04/semi-synchronous-replication-at-facebook.html
发表评论

11 条评论
  • #6 qRRZy 

    打开 288d.pw 都是 浪美眉

  • #5 Joe 

    “这是因为上述的步骤2已经写二进制日志了,master故障恢复后依然会提交该事务,但是这部分二进制日志可能会没有传送到slave。但是VSR和semi-sync不同的是,由于事务还在提交过程中,数据对其他事务不可见,这意味着,这部分已经写入到二进制日志的事务可以回滚”能否详细说下这块实现?谢谢可否在“通过复制的dump线程发送二进制日志event”步骤后再写入一个binlog event表明binlog已传输到slave,master crash recovery时,若读到到该binlog event,则最终commit,否则rollback?(只是思路还不了解细节)

  • #4 伽达默尔 

    打算试用一下。

  • 板凳 Luocs 

    姜总,enable_multi_replication = 1 #启用并行复制,该参数multi 还是muti,并行复制和这个文档的参数名不一样。

    • 姜 承尧
      姜承尧 

      不需要这个参数了,只要启用slave_parallel_threads=16,就自动开启并行复制了

  • 椅子 isadba 

    没有和keeplive配合的文档啊.

    • 姜 承尧
      姜承尧 

      keeplived这个自己配吧,相信你比我要熟悉的多啊

  • 沙发 Luocs 

    姜总文档拜读了,很吸引的功能

相关文章
IMG社区MySQL技术沙龙南京站圆满结束
IMG社区MySQL技术沙龙南京站圆满结束
改朝换代:MySQL Group Replication
改朝换代:MySQL Group Replication
数据库行业的朋友圈内幕,不知道就没法混了
数据库行业的朋友圈内幕,不知道就没法…
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了?
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年,数据库世界的诸神之战