Mysql半同步复制技术在高性能的数据管理中被广泛采用,但它在可靠性方面却存在不足.本文对半同步复制技术进行优化,提出了一种快速全同步复制技术,通过对半同步数据复制过程中的事务流程设置、线程资源合理应用、批量日志应用等技术手段,在保证数据可靠性的基础上降低复制过程中的性能损失,实现了快速的全同步复制.测试结果表明,快速全同步复制技术可以在性能、可靠性和一致性方面做到很好的均衡,有效提高了Mysql存储集群的业务承载能力.
目录
2 快速全同步复制的功能实现
2.1 主机节点
2.2 备机节点
2.3 Mysql存储集群快速全同步的状态变量
2.4 快速全同步配置参数
2 快速全同步复制的功能实现
Mysql过去的半同步复制和全同步复制技术是通过插件的方式实现,而快速全同步复制技术为了提高复制性能及实现高可靠性,直接在Mysql的事务处理流程里设置断点及增加相应函数,通过在事务处理过程中,增加等待备机节点的 ACK 消息等一系列流程后才完成事务来实现快速全同步.本文设计的快速全同步复制技术具体应用在 Sharding-sphere的Sharding-proxy分库分表解决方案场景上,具体的应用方案如下.
在如图 3 所示的架构中,应用程序通过 Shard-ing-Proxy 访问存储集群里的数据,Sharding-Proxy复制 SQL 语句的路由下发 SQL 到对应的存储集群 . 在每个存储集群里,通过快速全同步技术实现
高可用性,HA manager 负责集群监测和角色管理(如主从切换).
快速全同步技术定义了一系列的数据库参数和状态变量,用于控制和展示快速全同步技术的运行,主机节点和备机节点的实现原理及过程如下.
2.1 主机节点
快速全同步复制采用了 after-commit 的同步模式.在处理用户会话的工作线程完成事务T提交或prepare(XA prepare)且还未向客户端确认成功(即发送OK包)之前,主节点检查事务T的binlog是否已经收到足够数量的备机ACK.通过主机节点设置参数数据库参数 Fullsync_consistency_level,定义了主节点需要让每个事务等待多少个备机的 ACK ,如果是0就不等待任何ACK ;如果大于0则等待定义数量备机的ACK .
在数据库集群中,数据库管理员根据集群节点数量为每个 Master 节点设置合理的 Fullsync_consis-tency_level.通常的设定方法是对于一个2*n+1个节点的存储节点,设置Fullsync_consistency_level=n,从而在同时有n个节点消失的情况下,集群仍然可以
正常写入 . 也可以支持其他策略,比如要求所有备机全部确认等.
若释放条件满足,则工作线程直接返回成功状态给客户端,且完成本次请求处理,否则工作线程就把会话对象放到Fullsync ACK等待队列,然后去处理其他连接中收到的请求 . 主节点收到 ACK 后会对等待队列中的会话做释放条件检查,满足释放条件的会话会被释放,也就是返回成功状态给客户端.在等待备机ACK的过程中,用户会话并不占用工作线程.如超时(Fullsync_timeout)未收到足够的ACK来释放一个等待的会话时,Mysql存储集群有如下两种策略(由全局变量disable_fullsync_on_slave_ack_timeout来控制):
(1)如果 disable_fullsync_on_slave_ack_timeout=1,那么 fullsync 会自动退化为异步,这样后续等待的事务将不再做 fullsync 等待,当主节点再次收到备机ACK后,会自动启用Fullsync机制.
(2)如果 disable_fullsync_on_slave_ack_timeout=0,那么Fullsync等待超时的会话,会返回错误(错误号9000)给客户端,对于数据库集群来说,就是计算节点收到了这个错误,会触发主备切换.
2.2 备机节点
备机收到事件组(event group,即 Binlog 事务,包括普通显式事务,XA事务第一阶段,XA事务第二阶段,DDL语句,autocommit语句这几种类型,下文 简 称 EG)的 终 止 Binlog 事 件(XID_EVENT、XA_PREPARE_LOG_EVENT 或者 DDL 事务)后,它会决定是否需要把收到的若干个 EG 写到 RelayLog 文件并且刷到持久存储系统(即 flush&fsyncrelay log)中,然后发送 ACK 给主节点来确认这些收到的EG.
这个决定基于最小化资源消耗和最优化性能来确定:如果备机收到了足够多的EG(配置参数:full-
sync_fsync_ack_least_txns),或足够量的Binlog(配置参数:fullsync_fsync_ack_least_event_bytes),或太久没有发送 ACK(配置参数:fullsync_fsync_ack_wait_max_milli_secs),它就会落盘Relay Log再发送ACK.
一个 ACK 包含这些信息:备机的 server_id,落盘的最后一个 EG 在主节点 Binlog 中的终止位置
(文件编号和偏移值).主节点收到一个备机的ACK后就可以确认这个备机收到并持久存储了ACK位置之前的所有EG.使用fullsync_relaylog_fsync_ack_level 全局变量来控制一个备机节点落盘 Relay Log 和发送 ACK行为的时机,其含义如表1所示:
备机有两种方法发送 ACK 给主节点,这两种方法都要求备机使用Mysql客户端库连接主节点,这样每个备机节点有两个连接连到主节点,一个是备机的IO线程的连接,另一个是备机发送ACK的连接.在此连接中备机发送Mysql存储集群特有的COM_BINLOG_ACK 命令或者发送 Mysql 存储集群可以理解的SQL语句,前者性能更好,但是后者可以让各种第三方 Binlog 存储组件向主节点发送ACK.
(1)发送COM_BINLOG_ACK命令使用 Mysql 存储集群的客户端库文件及其mysql.h 头文件编译程序,然后调用 mysql_send_binlog_ack()函数发送ACK. Mysql存储集群快速全同步功能使用此方法发送ACK给其主节点.
(2)使用 SLAVE server_id CONSISTENT TOfile_index offset SQL语句这种方法可以使用任何社区版 Mysql 客户端库,Mysql存储集群的主节点可以正确处理该语句,把它当作确认ACK.此方法特别适合各种Binlog存储组件.
2.3 Mysql存储集群快速全同步的状态变量
这些状态变量可以帮助DBA观察快速全同步的运行情况和性能,并且作为辅助调节快速全同步配置参数的依据,如表2所示.
2.4 快速全同步配置参数
Mysql存储集群快速全同步支持丰富的配置参数,让用户在性能、资源消耗和一致性方面取得适当的平衡 . 这些变量都是 Mysql 的全局变量,其意义 和 用 法 说 明 如 表 3 所 示 . 关 键 的 参 数 如 en-able_fullsync 开启快速全同步复制,fullsync_timeout设置了等待超时时间等.