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 

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

相关文章
MySQL 8.0.3性能大杀器 —— CATS
MySQL 8.0.3性能大杀器 —— CATS
2017年MySQL数据库技术嘉年华 —— 有态度的技术大会
2017年MySQL数据库技术嘉年华 —— 有态度…
IMG社区MySQL技术沙龙南京站圆满结束
IMG社区MySQL技术沙龙南京站圆满结束
改朝换代:MySQL Group Replication
改朝换代:MySQL Group Replication
数据库行业的朋友圈内幕,不知道就没法混了
数据库行业的朋友圈内幕,不知道就没法…
Inside MySQL Group社区启用新LOGO
Inside MySQL Group社区启用新LOGO
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年,数据库世界的诸神之战