Galera replication for MySQL(包括Galera replication原理)

来源:转载


GalerareplicationforMySQL(包括Galerareplication原理)

原文http://www.gpfeng.com/?p=603

转自:http://blog.sina.com.cn/s/blog_53b13d950102uxpw.html

这篇文章总结了之前对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 / Maria3. 不支持的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个阶段:

1.Localreadphasea)本地(client连接到的节点)执行事务Ti,但不真正提交,真正提交之前进入Sendphase2.Sendphasea)若事务只读,直接提交,结束(多版本,只读事务不加锁)b)将事务的写操作封装成WS(WriteSet,基于行),广播到所有节点(包括自身)3.Lock/Certificaionphasea)对收到的WS中的每个WSi(X)i.若X没有被加锁,对X加锁ii.若X已被Tj加锁且Tj处于Localreadphase/Sendphase,回滚Tj,对X加锁iii.Certificationbasedconflictdetect4.Writephasea)若检测出冲突,回滚Tib)否则,执行WS,提交事务后释放锁资源c)对于源节点,提交事务并向client返回结果客户端/Galera节点信息交互图

图片来自mysqlperformanceblog

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/abort2. 事务在所有节点的执行顺序一致

Certification based replication所依赖的基础技术:Group Communication System1) Atomic delivery (事务传输要么成功传给了所有节点,要么都失败)2) Total order (事务在所有节点中的顺序一致)3) Group maintenance (每个节点知道所有节点的状态)

传统的2PC(两阶段提交)做法

1. 2PC 事务结束时,所有节点数据达到一致2. 协调者与参与者之间通信,参与者之间无连接3. 受网络状态影响较大4. 两次通信,需要得到每个参与者的反馈后才能决定是否提交事务

因此Galera replicateion相对于2PC减少了网络传输次数,消除了等待节点返回“决定是否冲突”的时间,从而可以提高了性能

Galera replication原理总结

1. 事务在本地节点执行时采取乐观策略,成功广播到所有节点后再做冲突检测2. 检测出冲突时,本地事务优先被回滚3. 每个节点独立、异步执行队列中的WS4. 事务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,较小的值比较合适,因为较大待执行队列长度意味着更大的冲突,默认值16gcs.fc_factor:当待执行队列长度开始小于(gcs.fc_factor*gcs.fc_limit)时,数据同步恢复,默认0.5gcs.fc_master_slave:galera cluster是否为Master-Slave模式,默认

安装MariaDBGalera Cluster安装准备:

1. MariaDB Galera Cluster 5.5.28a RC1) https://downloads.mariadb.org/mariadb-galera/5.5.28a/2) patched MariaDB 5.5.28,代码中增加了Galera Library API(wsrep API),并在事务、锁、handler等模块添加/修改了调用逻辑

2. Galera wsrep provider1) https://launchpad.net/galera/+download2) Galera Library的实现,其中实现了group communication system, certification

编译安装

1. MariaDB Galera Cluster 5.5.28a RC1) 与MariaDB基本相同,cmake时增加两项:-DWITH_WSREP=ON , -DWITH_INNODB_DISALLOW_WRITES=1.2. Galera wsrep provider: 源码编译后得到libgalera_smm.so(需要用到scons)

参数配置(每个节点)

wsrep_provider = /path/to/libgalera_smm.sowsrep_cluster_address =cluster connection URL(后面详细介绍)binlog_format = ROWdefault_storage_engine = INNODBinnodb_autoinc_lock_mode = 2innodb_locks_unsafe_for_binlog = 1

选配:(可以提高性能,galera保证不丢数据)innodb_flush_log_at_trx_commit = 2

构建集群(三个节点)3-node-cluster节点名称ip地址galera_node110.0.0.11galera_node210.0.0.22galera_node310.0.0.33新建Galera Cluster

以galera_node1作为第一个节点新建集群,在my.cnf中配置参数:

wsrep_cluster_address=gcomm://wsrep_cluster_name=galera_clusterwsrep_node_address=10.0.0.11wsrep_node_name=galera_node1wsrep_sst_method=rsync添加galera_node2节点

在my.cnf中配置wsrep_cluster_address为node1的ip或者hostname

wsrep_cluster_address=gcomm://10.0.0.11wsrep_cluster_name=galera_clusterwsrep_node_address=10.0.0.22wsrep_node_name=galera_node2wsrep_sst_method=rsync添加galera_node3节点

在my.cnf中配置wsrep_cluster_address为node1的ip或者hostname

wsrep_cluster_address=gcomm://10.0.0.11wsrep_cluster_name=galera_clusterwsrep_node_address=10.0.0.33wsrep_node_name=galera_node3wsrep_sst_method=rsync多实例配置

因为测试机器资源有限,需要在同一台机器上启动多个mysqld实例,为每个mysqld配置两个端口号(一个是mysqlserver端口号,默认3306;另外一个是wsrep端口号,默认4567),并修改部分wsrep配置参数,例如:

galera-cluster节点名称ip地址server portwsrep portwsrep配置galera_node1127.0.0.133064405wsrep_cluster_address=gcomm:// wsrep_node_address=127.0.0.1:4405 port=3306galera_node2127.0.0.133074407wsrep_cluster_address=gcomm://127.0.0.1:4405 wsrep_node_address=127.0.0.1:4407 port=3307galera_node3127.0.0.13084409wsrep_cluster_addres=gcomm:// 127.0.0.1:4405 wsrep_node_address=127.0.0.1:4409 port=3308

启动后在每个节点执行:

mysql>showstatuslike‘wsrep%’;

当看到下述状态时:

wsrep_connected=ONwsrep_ready=ONwsrep_cluster_status=Primarywsrep_cluster_size=3(节点个数)

则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 = 2innodb_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_auto_increment_control:控制auto_increment_increment=#nodes和auto_increment_offset=#node_id,默认ONwsrep_causal_reads:默认是在本地节点读,读到的可能不是最新数据,开启后将读到最新数据,但会增加响应时间,默认OFFwsrep_certify_nonPK:为没有显示申明主键的表生成一个用于certificationtest的主键,默认ONwsrep_cluster_address:启动节点时需要指定galeracluster的地址,作为cluster中第一个启动的节点,wsrep_cluster_address=gcomm://,对于后续启动的节点,wsrep_cluster_address=gcomm://node1,node2,node3wsrep_cluster_name:所有node必须一样,默认my_test_clusterwsrep_convert_LOCK_to_trx:将LOCK/UNLOCKTABLES转换成BEGIN/COMMIT,默认OFFwsrep_data_home_dir:galera会生成一些文件,默认使用mysql_data_dir,默认mysql_data_dirwsrep_node_name:节点名称wsrep_on:session/global,设置为OFF时,事务将不会复制到其他节点,默认ONwsrep_OSU_method:OnlineSchemaUpdate设置,TOI/RSU(MySQL>=5.5.17),默认TOIwsrep_provider:libgalera_smm.so的路径,若没有配置,galera复制不会启动,默认nonewsrep_provider_options:很长的字符串变量,可以配置很多groupcommunicationsystem相关参数,很长很长...wsrep_retry_autocommit:事务在冲突时重新尝试的次数,默认1wsrep_slave_threads:并行复制的slave线程数,默认4wsrep_sst_method:SnapshotStateTranster方法:mysqldump/rsync/xt,默认mysqldump

wsrep_provider_options该参数是一个字符串,包含了group communication system中很多参数设置,配置时使用分号隔开:wsrep_provider_options=”key_a=value_a;key_b=value_b;key_c=value_c”,点击查看详情

列举其中部分重要参数:

evs.send_window:节点一次可以发送的消息数目,默认4evs.user_send_window:其与evs.send_window之间的差别类似于max_connections与max_user_connection,默认2gcs.fc_factor:flowcontrol参数,默认0.5gcs.fc_limit:flowcontrol参数,默认16gcs.fc_master_slave:flowcontrol参数,默认NOgcs.recv_q_hard_limit:接收队列的占用的最大内存,默认LLONG_MAXgcs.recv_q_soft_limit:当接收队列占用内存超过(gcs.recv_q_hard_limit*gcs.recv_q_soft_limit),复制被延迟,默认0.25gmcast.listen_addr:节点用于接收其它节点消息的地址,默认tcp://0.0.0.0:4567pc.checksum:是否对发送的消息做checksum,默认truepc.ignore_sb:是否忽略splitbrain,默认false一个例子binlog_format=rowdefault-storage-engine=INNODBinnodb_autoinc_lock_mode=2innodb_locks_unsafe_for_binlog=1wsrep_provider=/u01/mariadb-galera/lib/libgalera_smm.sowsrep_cluster_address="gcomm://192.168.xxx.01"wsrep_cluster_name=galerawsrep_node_address=192.168.xxx.xxxwsrep_node_name=slavewsrep_sst_method=rsyncwsrep_slave_threads=16wsrep_provider_options="gcache.page_size=128M;gcache.size=2G;gcs.fc_limit=512;gcs.fc_factor=0.9;evs.send_window=256;evs.user_send_window=128"Galera status variables

Galera提供了很多以wsrep_开头状态参数监控mysql状态,通过show status like ‘wsrep%’可以查看:

wsrep_local_state_uuid:应该与wsrep_cluster_state_uuid一致,如363acc29-9160-11e2-0800-4316271a76e4wsrep_last_committed:已经提交事务数目,所有节点之间相差不大,可以用来计算延迟wsrep_replicated:从本地节点复制出去的writeset数目wsrep_replicated_bytes:从本地节点复制出去的writeset的总共字节数wsrep_received:本地节点接收来自其他节点的writeset数目wsrep_received_bytes:本地节点接收来自其他节点的writeset的总共字节数wsrep_local_commits:从本地节点发出的writeset被提交的数目,不超过wsrep_replicatedwsrep_local_cert_failures:certificationtest失败的数目wsrep_local_bf_aborts:certificationtest通过的writeset执行过程中回滚的与其冲突的本地事务wsrep_local_replays:事务被回滚(bfabort)重做的数目wsrep_local_send_queue:发送队列的长度wsrep_local_send_queue_avg:从上次查询状态到目前发送队列的平均长度,>0.0意味着复制过程被节流了wsrep_local_recv_queue:接收队列的长度wsrep_local_recv_queue_avg:从上次查询状态到目前接收队列的平均长度,>0.0意味着执行速度小于接收速度wsrep_flow_control_paused:从上次查询状态到目前处于flowcontrol的时间占比,如0.388129wsrep_flow_control_sent:从上次查询状态到目前节点发送出的FC_PAUSE消息数目,如1wsrep_flow_control_recv:从上次查询状态到目前及节点接收的FC_PAUSE消息数目,如1wsrep_cert_deps_distance:可以并行执行的writeset的最大seqno与最小seqno之间的平均差值,如1851.825751wsrep_apply_oooe:队列中事务并发执行占比,值越高意味着效率越高wsrep_commit_window:平均并发提交窗口大小wsrep_local_state:节点的状态,取值1-6wsrep_local_state_comment:节点的状态描述,比如Syncedwsrep_incoming_addresses:集群中其它节点的地址,多个地址之间用逗号分隔wsrep_cluster_conf_id:集群节点关系改变的次数(每次增加/删除都会+1)wsrep_cluster_size:集群节点个数wsrep_cluster_state_uuid:集群uuid,所有节点应该一样,如:363acc29-9160-11e2-0800-4316271a76e4wsrep_cluster_status:集群的目前状态,取值:PRIMARY(正常)/NON_PRIMARY(不一致)wsrep_connected:节点是否连接到集群,取值:ON/OFFwsrep_local_index:节点idwsrep_provider_name:默认Galerawsrep_provider_vendor:默认CodershipOywsrep_provider_version:wsrep版本,如:2.2(rXXXX)wsrep_ready:节点是否可以接受查询了,取值:ON/OFF一个截图:

如何检查节点是否加入到集群

1. wsrep_cluster_state_uuid应该与其它所有节点相同2. wsrep_cluster_conf_id应该与其它所有节点相同3. wsrep_cluster_size应该是所有节点的数目4. wsrep_cluster_status取值应该是:Primary5. wsrep_ready取值应该是ON6. 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 server2、galera (RTT: 0.5ms): 2-nodes galera cluster,单节点读写3、galera (RTT: 15.2ms): 2-nodes galera cluster,单节点读写

tpmC结果:TPS结果:

测试结论:

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.mysqlpe


分享给朋友:
您可能感兴趣的文章:
随机阅读: