这篇文章总结了之前对Galera replication的调研,内容包括Galera特性,原理,Galera cluster配置,参数及性能等
Galera replication是什么
MySQL DBA及开发应该都知道MySQL源生复制及semi-sync半同步复制,它们都基于MySQL binlog,原生复制是完全异步的,master不需要保证slave接收并执行了binlog,能够保证master最大性能,但是slave可能存在延迟,主备数据无法保证一致性,在不停服务的前提下如果master宕机让slave顶上,就会丢失数据,semi-sync在异步复制基础上增加了数据保护的考虑,master必须确认slave收到binlog后(但不保证slave执行了事务)才能最终提交事务,在没有退化(延迟较大时可能发生)成异步复制之前可以保证数据安全,此时master挂掉之后,slave可以在apply完所有relay log后切换成master提供读写服务
Galera replication是codership提供的MySQL数据同步方案,具有高可用,易于扩展等特点,它将多个MySQL节点组织成一个cluster
Galera replication特性
1. 同步复制,主备无延迟
2. 支持多主同时读写,保证数据一致性
3. 集群中各节点保存全量数据
4. 节点添加/删除,自动检测和配置
5. 行级别并行复制
6. 不需要写binlog
相对于MySQL源生复制和semi-sync,Galera replication比较有吸引力的特性:
1. 同步复制,主备无延迟,master宕机后slave可以立即顶上并提供服务(semi-sync需要apply完所有relay log)
2. 事务冲突检测保证数据一致性,多个节点可以同时读写数据,可以极大简化数据访问
3. 行级别并行复制,MySQL 5.6之前slave sql线程只有一个,这个长期饱受诟病,是导致slave落后master的主要原因
Galera replicateion限制
1. 集群至少3个节点(2个节点也可以运行)
2. 存储引擎:Innodb / XtraDB / Maria
3. 不支持的SQL:LOCK / UNLOCK TABLES / GET_LOCK(), RELEASE_LOCK()…
4. 不支持XA Transaction
目前可用的产品:MariaDB Galera Cluster 和 Percona XtraDB Cluster
Galera replication原理
Galera replication是一种Certification based replication,保证one-copy serializability,理论基于这两篇论文:Don’t be lazy, be consistent 和 Database State Machine Approach
算法示意图
算法伪代码(Certification包含了后续流程,来自上面两篇论文)
事务执行协议
遵守deferred update replication,事务在commit时才复制到其他节点,执行过程分为4个阶段:
客户端/Galera节点信息交互图
Galera replication采取的是乐观策略,即事务在一个节点提交时,被认为与其他节点上的事务没有冲突,首先在本地“执行”(之所以带引号,是因为事务没有执行完)后再发送到所有节点做冲突检测,存在两种情况下需要回滚事务:
1. WS复制到其它节点,被加到每个节点的slave trx queue中,与queue中前面的trxs在做certification test时发现冲突
2. WS通过了certification test后被保证一定会执行,在它执行过程中,如果该节点上有与其冲突的local trxs(Local phase),回滚local trxs
Galera提供了两个状态参数记录冲突:
wsrep_local_cert_failures:certification test中未通过的trx数目
wsrep_local_bf_aborts:apply trxs(已经通过certification test)时,回滚的local trxs(open but not commit)数目
因此事务在commit节点广播后,节点之间不交换“是否冲突”的信息,各个节点独立异步的处理该事务,certification based replication协议保证:
1. 事务在所有节点上要么都commit,要么都rollback/abort
2. 事务在所有节点的执行顺序一致
Certification based replication所依赖的基础技术:
Group Communication System
1) Atomic delivery (事务传输要么成功传给了所有节点,要么都失败)
2) Total order (事务在所有节点中的顺序一致)
3) Group maintenance (每个节点知道所有节点的状态)
传统的2PC(两阶段提交)做法
1. 2PC 事务结束时,所有节点数据达到一致
2. 协调者与参与者之间通信,参与者之间无连接
3. 受网络状态影响较大
4. 两次通信,需要得到每个参与者的反馈后才能决定是否提交事务
因此Galera replicateion相对于2PC减少了网络传输次数,消除了等待节点返回“决定是否冲突”的时间,从而可以提高了性能
Galera replication原理总结
1. 事务在本地节点执行时采取乐观策略,成功广播到所有节点后再做冲突检测
2. 检测出冲突时,本地事务优先被回滚
3. 每个节点独立、异步执行队列中的WS
4. 事务T在A节点执行成功返回客户端后,其他节点保证T一定会被执行,因此有可能存在延迟,即虚拟同步
Galera flow control
galera是同步复制(虚拟同步)方案,事务在本地节点(客户端提交事务的节点)上提交成功时,其它节点保证执行该事务。在提交事务时,本地节点把事务复制到所有节点后,之后各个节点独立异步地进行certification test、事务插入待执行队列、执行事务。然而由于不同节点之间执行事务的速度不一样,长时间运行后,慢节点的待执行队列可能会越积越长,最终可能导致事务丢失。
galera内部实现了flow control,作用就是协调各个节点,保证所有节点执行事务的速度大于队列增长速度,从而避免丢失事务。实现原理和简单:整个galera cluster中,同时只有一个节点可以广播消息(数据),每个节点都会获得广播消息的机会(获得机会后也可以不广播),当慢节点的待执行队列超过一定长度后,它会广播一个FC_PAUSE消息,所以节点收到消息后都会暂缓广播消息,直到该慢节点的待执行队列长度减小到一定长度后,galera cluster数据同步又开始恢复
flow control相关参数:
gcs.fc_limit:待执行队列长度超过该值时,flow control被触发,对于Master-Slave模式(只在一个节点写)的galera cluster,可以配置一个较大的值,对启动多写的galera cluster,较小的值比较合适,因为较大待执行队列长度意味着更大的冲突,默认值16
gcs.fc_factor:当待执行队列长度开始小于(gcs.fc_factor*gcs.fc_limit)时,数据同步恢复,默认0.5
gcs.fc_master_slave:galera cluster是否为Master-Slave模式,默认
安装MariaDB Galera Cluster
安装准备:
1. MariaDB Galera Cluster 5.5.28a RC
1) https://downloads.mariadb.org/mariadb-galera/5.5.28a/
2) patched MariaDB 5.5.28,代码中增加了Galera Library API(wsrep API),并在事务、锁、handler等模块添加/修改了调用逻辑
2. Galera wsrep provider
1) https://launchpad.net/galera/+download
2) Galera Library的实现,其中实现了group communication system, certification
编译安装
1. MariaDB Galera Cluster 5.5.28a RC
1) 与MariaDB基本相同,cmake时增加两项:-DWITH_WSREP=ON , -DWITH_INNODB_DISALLOW_WRITES=1.
2. Galera wsrep provider: 源码编译后得到libgalera_smm.so(需要用到scons)
参数配置(每个节点)
wsrep_provider = /path/to/libgalera_smm.so
wsrep_cluster_address = cluster connection URL(后面详细介绍)
binlog_format = ROW
default_storage_engine = INNODB
innodb_autoinc_lock_mode = 2
innodb_locks_unsafe_for_binlog = 1
选配:(可以提高性能,galera保证不丢数据)
innodb_flush_log_at_trx_commit = 2
构建集群(三个节点)
节点名称 | IP地址 |
---|---|
galera_node1 | 10.0.0.11 |
galera_node2 | 10.0.0.22 |
galera_node3 | 10.0.0.33 |
新建Galera Cluster
以galera_node1作为第一个节点新建集群,在my.cnf中配置参数:
添加galera_node2节点
在my.cnf中配置wsrep_cluster_address为node1的ip或者hostname
添加galera_node3节点
在my.cnf中配置wsrep_cluster_address为node1的ip或者hostname
多实例配置
因为测试机器资源有限,需要在同一台机器上启动多个mysqld实例,为每个mysqld配置两个端口号(一个是mysql server端口号,默认3306;另外一个是wsrep端口号,默认4567),并修改部分wsrep配置参数,例如:
节点名称 | IP地址 | SERVER PORT | WSREP PORT | WSREP配置 |
---|---|---|---|---|
galera_node1 | 127.0.0.1 | 3306 | 4405 | wsrep_cluster_address=gcomm:// wsrep_node_address=127.0.0.1:4405 port=3306 |
galera_node2 | 127.0.0.1 | 3307 | 4407 | wsrep_cluster_address=gcomm://127.0.0.1:4405 wsrep_node_address=127.0.0.1:4407 port=3307 |
galera_node3 | 127.0.0.1 | 308 | 4409 | wsrep_cluster_addres=gcomm:// 127.0.0.1:4405 wsrep_node_address=127.0.0.1:4409 port=3308 |
启动后在每个节点执行:
当看到下述状态时:
则galera集群建立成功,如下图所示:
说明:
1. MariaDB Galera Cluster 5.5.28a RC源码安装,在编译时若没有打开-DWITH_WSREP=ON, -DWITH_INNODB_DISALLOW_WRITES=1,或者没有配置任何wsrep相关参数,它运行时就是一个普通的mysqld实例
2. Galera cluster复制不依赖于binlog文件,因此mysql-binlog和log-slave-updates都可以不配置,当然如果需要记录binlog,也可以打开
3. 需要以wsrep_cluster_address = gcomm://启动第一个节点后,才能相继添加其他节点
Galera相关参数配置
InnoDB 相关参数
galera补丁版的mysql在cmake时需要指定:
-DWITH_WSREP=ON , -DWITH_INNODB_DISALLOW_WRITES=1
galera 目前只支持Innodb/xtradb/mariad存储引擎
default_storage_engine = INNODB
为了降低冲突,下列两项需要设置
innodb_autoinc_lock_mode = 2
innodb_locks_unsafe_for_binlog = 1(gap不加锁)
选配:(可以提高性能,galera保证不丢数据)
innodb_flush_log_at_trx_commit = 2
选配:galera可以不写binlog,注释binlog路径理论上可以提高性能
#log-bin
#log-slave-updates=1
wsrep 相关参数
wsrep参数都是以wsrep_开头的(30+个),其中有一个字符串参数(wsrep_provider_options)可以配置50+个更底层的参数。
可以通过“show variables like wsrep%”查看,wsrep_开头参数,点击查看详情
列举几个重要的参数:
wsrep_provider_options
该参数是一个字符串,包含了group communication system中很多参数设置,配置时使用分号隔开:
wsrep_provider_options=”key_a=value_a;key_b=value_b;key_c=value_c”,点击查看详情
列举其中部分重要参数:
一个例子
Galera status variables
Galera提供了很多以wsrep_开头状态参数监控mysql状态,通过show status like ‘wsrep%’可以查看:
一个截图:
如何检查节点是否加入到集群
1. wsrep_cluster_state_uuid应该与其它所有节点相同
2. wsrep_cluster_conf_id应该与其它所有节点相同
3. wsrep_cluster_size应该是所有节点的数目
4. wsrep_cluster_status取值应该是:Primary
5. wsrep_ready取值应该是ON
6. wsrep_connected取值应该是ON
判断复制过程是否出现问题
wsrep_flow_control_paused,正常情况下,其取值应该接近于0.0,大于0.0意味着有‘慢节点’影响了集群的速度,可以尝试通过增大wsrep_slave_threads来解决
找出最慢的节点
wsrep_flow_control_sent,wsrep_local_recv_queue_avg两个值最大的节点
参考:galera status,galera monitoring
性能测试
由于galera同步复制在每个写事务提交时都增加了replicate trx和certification test的开销,因此性能远远低于异步MySQL实例
测试场景
使用TPCC进行测试,包含3组数据:
1、normal mysql: baseline,单个mysql server
2、galera (RTT: 0.5ms): 2-nodes galera cluster,单节点读写
3、galera (RTT: 15.2ms): 2-nodes galera cluster,单节点读写
测试结论:
1. 相对于异步MySQL实例,Galera replication性能下降约50% ~ 60%左右
2. Galera最大性能不受RTT影响,RTT 较小时(0.5ms),在达到最大性能之前(32并发),性能下降并不明显 (32并发下降25%,16并发性能下降更低),RTT较大时(15.2ms),在达到最大性能之前(64并发),相对于norml mysq性能下降一直到很明显,当压力逐渐增大,由于group io的原因,galera性能在达到最大时还会提高
Galera replication for MySQL学习资料
1. codership官网
2. mysqlperformanceblog搜索中PXC(Percona XtraDB Cluster)