ttlsa教程系列之MySQL —- MySQL/Galera集群-多主高可用性负载均衡 Percona和MariaDB发布版本中,包含了Galera集群。据红帽峰会的消息,在今年下半年即将发布的 RHEL 7 中将不再包含 MySQL 数据库,而是用 MariaDB 替代之。这势必会引起RHEL的一些衍生版本跟随,例如centos。
MySQL 的手册已经修改了授权许可证,此举明显的显示出 Oracle 非常不友善的行为。新的许可证跟 GPL 差别巨大,并且明确表达不再使用 GPL 许可证。
一.部署前检查是否符合Galera要求
输出不符合使用Galera的表的信息,字段内容为:表,表引擎,是否无主键,是否有全文索引,是否有空间索引。
二.wsrep API(WriteSet Replication)
Wsrep
API定义了一系列应用回调和复制调用库,来实现事务数据库同步写集(writeset)复制以及相似应用。目的在于从应用细节上实现抽象的,隔离的复制。虽然这个接口的主要目标是基于认证的多主复制,但同样适用于异步和同步的主从复制。
应用回调提供管理事务写集:
1.在发送端,填充写集
2.在接收端,应用写集
接收端通过高优先级事务来应用写集。来确保集群中的每个数据库服务器以相同的顺序,不间断的处理SQL语句,以保持数据的一致性。
三.GTID(Global Transaction ID)
wsrep
API描述了下面的复制模型。应用程序比如数据库服务器有一个被客户修改过的状态比如是数据库内容。这种改变的状态表示为一系列的原子变化。集群中的所有节点通过同步复制具有相同的状态并以相同的顺序应用这些状态。
wsrep API引入GTID目的:
1.标识状态的改变
2.标识状态本身最后状态改变ID
GTID组成部分:
1.状态UUID,唯一性的状态标识和序列变化经历
2.有序的序列号来表示序列中的位置变化
因此,GTID允许比较应用程序的状态,建立有序的状态变化,判断变化是否应用和是否所有节点都有应用。GTID像这样的45eec521-2f34-11e0-0800-2a36050b826b:94530586304。
四.Galera wsrep提供者
Galera是一个wsrep提供者,实现真正的多主几乎同步复制。主要功能有:
1.几乎同步:一个节点上提交的事务确保集群内其他所有节点都提交。没有提交的事务是在某个节点发生故障时丢失。
2.真正的多主:在集群所有节点上可以同时修改同一个表。因此无需主节点故障转移。
3.真正的并行应用:从0.8版本开始
4.没有单点故障
五.Galera集群
Galera集群建立在专有组通讯系统层之上的来实现虚拟同步QoS.虚拟同步统一数据传输和集群成员服务,使的消息传递语义明确。还提供从多个来源的消息总序,非常方便的建立多主集群全局事务ID。Galera集群传输层是一个完整的对称的无向图,因此每个节点由一个单一的TCP连接集群的其他每个节点。默认情况下TCP用于消息复制和集群成员服务,从0.8版本开始,UDP组播可以用于LAN复制。
六.节点存活检测
Galera集群每个节点通过keepalive消息来监控其他节点存活。可以调整keepalive的检测频率和灵敏度来忍受不可靠的网络。
七.主组件(Primary Component)
除了单节点故障,由于网络故障集群可以分割成几个组件。一个组件是一组节点彼此连接不是来自其他组件的节点。在这种情况下只有一个组件可以续集修改状态以避免历史分歧。这就是PC。当集群分区时,Galera调用特殊群体算法选择一个PC来确保集群只有一个PC。
八.脑裂(Split-brain)
像任何基于法定人数系统,当选择PC仲裁算法失败时,Galera集群发生了脑裂。这是可能发生的,例如,在一个没有备份交换机集群中,如果主交换机故障了。最有可能发生脑裂情景是在两个节点的集群中当有单个节点故障时。因此强烈建议Galera集群最低配置3个节点。
九.流量控制
虚拟同步保证一致性,但是没有时间同步,流畅的多主操作是普遍的期望和要求。为了此目的,Galera实现其自己的时间流量控制来保持节点在下一秒同步。可在运行时配置,放宽的主从设置。
十.多主操作
Galera支持多主操作,在这个意义上,所有节点可以同时更改同一个表,并能仍然保持一致性。Galera通过认证算法来检测冲突和回滚事务。多主复制的效率取决于冲突率,而这又依赖于应用程序的负载分布,负载均衡策略和集群节点数。在某些情况下,减少节点数量,可以同时接受写入,可以提高性能。
十一.并行应用
由于galera可以检测writesets冲突,还能检测那些writesets可以同时应用。
十二. 配置参数
Parameter Default Description
protonet.backend asio 传输后端使用。当前只支持ASIO
protonet.version 0
socket.ssl_cert 指定SSL验证路径
socket.ssl_key 指定私钥路径
socket.ssl_compression yes SSL连接是否压缩
socket.ssl_cipher “AES128-SHA” 对称密码使用
gmcast.listen_addr tcp://0.0.0.0:4567 Galera监听地址,用来与其他节点连接
gmcast.mcast_addr
如果设置,UDP组播将用于复制。gmcast.mcast_addr=239.192.0.11。所有节点要设置为一样
gmcast.mcast_ttl 1 组播报存活时间
gmcast.peer_timeout PT3S 初始化消息的中继连接超时
gmcast.time_wait PT5S Time to wait until allowing peer declared
outside of stable view to reconnect.
gmcast.version 0
evs.causal_keepalive_period 供开发人员使用。默认evs.keepalive_period。
evs.consensus_timeout PT30S 集群成员达成共识超时时间
evs.debug_log_mask 0×1 控制EVS调试日志记录,当wsrep_debug开启时有效
evs.inactive_check_period PT1S 检测间隔时间
evs.inactive_timeout PT15S 节点多少间隔无响应,宣告down
evs.info_log_mask 0 控制额外的的EVS信息日志。0X1 ? 额外的视图变化信息;0X2 ?
额外的状态变化信息;0×4 ? 统计;0×8 ? 剖析(仅适用于构建与分析启用)
evs.install_timeout PT15S 等待安装消息确认超时时间
evs.join_retrans_period PT1S 发送EVS加入消息的频率
evs.keepalive_period PT1S 发送存活消息频率
evs.max_install_timeouts 1 尝试多少次后放弃
evs.send_window 4
同时复制最大数据包。对于WAN可以设置高些,如512.必须不低于evs.user_send_window
evs.stats_report_period PT1M 控制EVS统计报告期
evs.suspect_timeout PT5S
非活动期之后,节点将是死的。如果所有剩余节点上达成一致,在到达evs.inactive_timeout前将被丢弃
evs.use_aggregate true 聚合小的数据包
evs.user_send_window 2 同时复制的最大数据包。对于WAN可以设置高些,如512
evs.view_forget_timeout PT5M Drop past views from view history
after that timeout.
evs.version 0
pc.bootstrap 将它设置为true,将NON-PRIMARY组件转变为PRIMARY
pc.checksum true 复制信息校验和
pc.ignore_sb false
即使在脑裂情况下,允许处理更新吗?在多主下这是一个危险的设置,应简化为主从集群,尤其是适用2个节点
pc.ignore_quorum false 完全无视法定人数计算
pc.linger PT2S PC控制等待EVS中止间隔
pc.npvo false 如果设置为true,在冲突情况下更近的PC会覆盖旧的
pc.wait_prim false
如果设置为true,节点将永远等待PC。用来绑定一个NON-PRIMARY组件。pc.bootstrap来设置PC
pc.weight 1 2.4版本,节点权重用来仲裁
pc.version 0
gcs.fc_debug 0 调试统计关于SST流控制的writesets
gcs.fc_factor 0.5 Resume replication after recv queue drops below
that fraction of gcs.fc_limit.
gcs.fc_limit 16 如果接受队列writesets超过将暂停复制
gcs.fc_master_slave NO 假定组中只有一个master
gcs.max_packet_size 32616 所有的writesets超过该值,将成碎片
gcs.max_throttle 0.25
在转移过程中节流多少复制率(避免内存耗尽)。为了完成状态转移,如果停止复制可以接受的,设置该值为0.0
gcs.recv_q_hard_limit LLONG_MAX
允许最大的recv队列。通常为(RAM+SWAP)/2。如果超过此限制,服务器将中止
gcs.recv_q_soft_limit 0.25
gcs.sync_donor NO
集群内其他成员与donor保持同步?”yes”意味着如果donor阻塞状态转移,整个集群将阻塞它
ist.recv_addr 增量状态转移监听。默认为
十三. 状态参数
Status Variable Example Value Description
wsrep_local_state_uuid e2c9a15e-5485-11e0-0800-6bbb637e7211
当前节点的状态UUID
wsrep_last_committed 409745 上次提交事务的序列号
wsrep_replicated 16109 writesets复制的总数(发送到其他节点)
wsrep_replicated_bytes 6526788 Writesets复制总大小
wsrep_received 17831 从其他节点接收到的writesets复制总数
wsrep_received_bytes 6526788 从其他节点接收到的writesets复制总大小
wsrep_local_commits 14981 本地提交事务的总数量
wsrep_local_cert_failures 333 本地事务认证测试失败总数
wsrep_local_bf_aborts 960 从执行事务中止的本地事务总数量
wsrep_local_replays 0 由于asymmetric lock granularity事务重放的总数
wsrep_local_send_queue 1 当前发送队列长度
wsrep_local_send_queue_avg 0.145000
发送队列长度与上次状态查询的平均间隔。值大于0.0说明复制节流或网络吞吐量问题
wsrep_local_recv_queue 0 当前接收队列长度
wsrep_local_recv_queue_avg 3.3
接收队列长度与上次状态查询的平均间隔。值大于0.0说明节点应用writesets比接收的慢,并会产生大量的复制节流
wsrep_flow_control_paused 0.18 由于节流控制复制被暂停时间(与上次状态查询对比)
wsrep_flow_control_sent 7 自上次状态查询发送的FC_PAUSE事件的数目
wsrep_flow_control_recv 11 自上次状态查询收到的FC_PAUSE事件的数目
wsrep_cert_deps_distance 23.88889 可能并行应用的最高和最低的序列号之间的距离
wsrep_apply_oooe 0.671120 Writesets应用频率(并行效率)
wsrep_apply_oool 0.195248
wsrep_apply_window 5.163966 最高和最低的同时应用SEQNO之间的平均距离
wsrep_commit_oooe 0.0000 顺序提交事务的频率
wsrep_commit_oool 0.0000 无意义
wsrep_commit_window 0.0000 最高和最低同时提交SEQNO之间的平均距离
wsrep_local_state 4 内部Galera FSM状态编号
wsrep_local_state_comment Synced 人类可理解的状态
wsrep_incoming_addresses 10.0.0.1:3306,10.0.0.2:3306,undefined
以逗号分隔的传入服务器地址列表
wsrep_cluster_conf_id 33 集群成员发生变化的总数
wsrep_cluster_size 3 当前集群中的成员个数
wsrep_cluster_state_uuid e2c9a15e-5485-11e0-0800-6bbb637e7211
集群状态UUID
wsrep_cluster_status Primary 集群组件状态:PRIMARY/NON_PRIMARY
wsrep_local_index 1 这个节点在集群中的索引值(基数为0)
wsrep_ready ON 服务器是否准备好接受查询。如果此值为OFF,几乎所有的查询将失败ERROR 1047 (08S01)
Unknown Command除非wsrep_on会话变量设置为0
十四. MySQL/Galera集群
MySQL-wsrep是MySQL
RDBMS的补丁,使其能够使用wsrep。搭配Galera以创建MySQL/Galera集群,来实现:
1.高可用性
2.无单点故障
3.无与伦比的性能
4.应用程序兼容性
5.易用性
目前MySQL/Galera集群只支持InnoDB存储引擎。
十五. SWAP大小要求
MySQL/Galera在正常工作情况下与普通的MySQL服务器相比不需要消耗更多内存。额外的内存消耗在认证指标和未提交的writesets,但是通常这不应该是明显的一个典型应用。有一个例外:状态转移期间的writesets缓存。当一个节点接收到状态转移,它不能处理和应用传入的writesets,因为没有状态应用到。根据状态转移机制发送状态可能也无法应用writesets。因此,在追赶阶段需要缓存这些writesets。当前writesets缓存在内存中,如果超过系统内存,状态转移将失败或集群将阻塞等待状态转移。为了控制writesets缓存内存的使用情况,可配置gcs.recv_q_hard_limit,
gcs.recv_q_soft_limit, gcs.max_throttle参数。
十六. 创建新集群
要引导一个新的集群,需要启动一个空的集群地址URL的 mysqld服务器。
# mysqld ?wsrep_cluster_address=gcomm://
这意味着服务器没有集群可以连接,将创建一个新的历史UUID。
重新启动相同配置的服务器,将导致它再次创建新的历史UUID,不会重新连接到旧的集群。
添加另一个节点到集群
一旦有一个集群在运行,你想添加或重新连接到另一个节点,必须提供一个集群成员之一的URL地址。例如如果集群中第一个节点地址是192.168.0.1,然后添加第二个节点将是:
# mysqld ?wsrep_cluster_address=gcomm://192.168.0.1
新的节点只需要连接到现有成员之一,就会自动检索集群地图和重新连接到其他节点。
十七. 状态快照转移(SST)
有两个概念,从一台MySQL服务器的状态转移到另一台的不同方式:
1.使用mysqldump。这需要接收服务器在转移前完全初始化和准备接收连接。此方法是通过定义阻塞,阻止修改自身状态转移的持续时间。这也是最慢的方式,可能会带来高负载的问题。自0.7版本支持此方式。
2.直接拷贝数据文件。要求接收服务器初始化后转移。rsync,xtrabackup等方法都属于这类。这些方法比mysqldump快,但有一定的局限性,发送和接收服务器配置参数需要高度相似。像xtrabackup可以无阻塞发送端。这种方法从0.8版本开始通过脚本界面支持。当前MySQL/Galera带有以下SST脚本:
a).mysqldump
默认的方法。这个脚本只能运行在发送端,通过管道输出到mysql客户端连接到接收服务器。
b). rsync/rsync_wan (starting with 0.8)
这可能是服务器状态快照转移到另一台上的最快方式。脚本运行在发送和接收端上。在接收端,开启rsync服务模式,等待发送端连接。在发送端,开启rsync客户端模式,发送mysql数据目录内容到连接节点。这种方法也会阻塞,但是比mysqldump快。rsync_wan方法是优化通过WAN传输,减少数据传输量。
当前MySQL-wsrep补丁包含以下SST方法:
1.mysqldump
2.rsync
3.xtrabackup
Method Speed Blocks the donor Can be done on live node?
logical/physical Requires root access to MySQL server?
mysqldump slow yes yes logical both donor and joiner
rsync fastest yes no physical none
xtrabackup fast for a very short time no physical donor only
Logical/physical区别比较:
1.Physical state snapshot:
优点:速度最快的,不涉及任何一端服务器,物理数据从一个节点磁盘复制到其他节点磁盘上。不依赖加入的节点处在工作状态,以写入来恢复损坏的数据。
缺点:需要两端服务器有相同的数据目录规划和相同的存储引擎。如每个innoDB引擎表空间,压缩,日志文件大小等相似配置。接收端需要重启服务来初始化存储引擎。mysql客户端无法访问直到SST完成。
2.Logical state snapshot
优点:正在运行的服务器(完全初始化后)可以接收逻辑状态转移。不需要双方相同的配置参数。
缺点:很慢
十八. 状态转移失败
通常是接受节点不可用。因此,如果故障被检测到,将中止。mysqldump方法失败后要重新启动节点,可能需要人工恢复管理表。
rsync方法没有这个问题,因为它不需要服务器处于工作状态。
十九. 最小集群大小
为了避免脑裂情况的发生,推荐集群节点最少为3.需要最少3个节点的另一理由是阻塞状态转移,以便某个节点故障服务的可用性。虽然连个成员可以进行状态转移,剩余成员可以维持客户请求服务。
二十. 配置
需要强制设置的参数:
1. wsrep_provider Galera库路径
2. wsrep_cluster_address 集群连接URL
3. binlog_format=ROW
4. innodb_autoinc_lock_mode=2
5. default_storage_engine=InnoDB
6. innodb_locks_unsafe_for_binlog=1
7. innodb_doublewrite=1
可选设置:
1. innodb_flush_log_at_trx_commit=2
my.cnf配置实例如下:
[mysqld]
# 1. Mandatory settings: these settings are REQUIRED for proper
cluster operation
# 2. Optional mysqld settings: your regular InnoDB tuning and such
datadir=/mnt/mysql/data# 3. wsrep provider configuration: basic wsrep options
wsrep_provider=/usr/lib64/galera/libgalera_smm.so# 4. additional “frequently used” wsrep settings
wsrep_node_incoming_address='192.168.10.2'
配置技巧:
1.并行应用需要配置以下两个参数
innodb_autoinc_lock_mode=2
innodb_locks_unsafe_for_binlog=1
2.WAN复制
wsrep_provider_optiOns= “evs.keepalive_period = PT3S;
evs.inactive_check_period = PT10S; evs.suspect_timeout = PT30S;
evs.inactive_timeout = PT1M; evs.install_timeout = PT1M”
3. Multi-Master
客户端同时写操作多主,认证冲突的概率就高,可能会引起不良的回滚操作和性能衰减。在这种情况下,就应减少主。
4. Master-Slave
wsrep_provider_optiOns= “gcs.fc_limit = 256; gcs.fc_factor = 0.99;
gcs.fc_master_slave = yes”
减少流量控制事件率这可能在一定程度上提高复制性能。
二十一. 监控
mysql> SHOW STATUS LIKE 'wsrep_%';
二十二. MySQL/Galera集群数据备份
Galera集群的备份和普通的MySQL备份相同。所有节点都是一样的,备份一个节点就相当于备份整个集群。但是会有两个潜在的问题:
1.没有与它们相关联的全局事务ID,是很好的恢复数据,但是不能用来恢复Galera节点。
2.在备份期间可能会阻塞整个集群的操作
在备份时,要关联全局事务ID和避免影响集群,可通过:
# /usr/bin/garbd ?address gcomm://
二十三. 局限性
1.当前只支持InnoDB存储引擎,其他任何类型包含系统表(mysql.*)都不会复制。然而,DDL语句是以语句级别复制,因此更改mysql.*表结构将会复制。可以放心的执行CREATE
USER…,GRANT… 。INSERT INTO mysql.user不会复制。通常,非事务引擎不支持多主复制。
2.在不同节点上查询没有主键的表返回的数据顺序可能不同。SELECT…LIMIT…可能返回不同的结果集。
3.不支持的查询
a.LOCK/UNLOCK TABLES不支持多主复制
b.锁函数(GET_LOCK(),RELEASE_LOCK()…)
4.查询日志不能直接存入表中。如果要启用查询日志,只能指定到文件log_output = FILE
5.由于可能的回滚提交不支持XA事务
6.事务大小。Galera没有明确限制事务大小,由于writesets需要驻留在内存缓存中处理,非常大的事务会对性能产生影响。为了避免这种情况,系统默认设置wsrep_max_ws_rows=128k和wsrep_max_ws_size=1Gb来限制事务。
二十四. 部署实例
10.1.1.182
【10.1.1.182】
[mysqld]
SST使用xtrabackup所需的用户权限
mysql> CREATE USER 'sst'@'localhost' IDENTIFIED BY 'rootpa$$';
【10.1.1.191】
[mysqld]
【10.1.1.202】
[mysqld]
测试复制:
mysql@node-202> create database xuhh;测试myisam引擎表:
mysql@node-182> create table test_2 (node_id int primary key auto_increment, node_name varchar(10)) engine=myisam;Myisam表引擎的内容没有复制过来。
mysql@node-202> set global wsrep_replicate_myisam=1;
设置wsrep_replicate_myisam=1后,myisam引擎表是可以复制的。node-191会报错 [ERROR]
Slave SQL: Error ‘Duplicate entry ’1′ for key ‘PRIMARY” on query.
Default database: ‘xuhh’. Query: ‘insert into xuhh.test_2 values
(1,’myisam’)', Error_code: 1062
[Warning] WSREP: RBR event 1 Query apply warning: 1, 14
[Warning] WSREP: Ignoring error for TO isolated action: source:
1f0a4ece-ccf9-11e2-0800-bd825e760a16 version: 2 local: 0 state:
APPLYING flags: 65 conn_id: 203 trx_id: -1 seqnos (l: 26, g: 14, s:
13, d: 13, ts: 1370396261855962000)
HAProxy配置:
# rpm -Uvh http://mirrors.yun-idc.com/epel/5/i386/epel-release-5-4.noarch.rpm# vim haproxy.cfg
global在每个节点上执行以下操作:
mysql> grant process on *.* to ‘clustercheck’@’127.0.0.1’ identified by ‘clusterpassword!’;
# yum install xinetd
# vim /etc/services
# vim /etc/xinetd.d/mysqlchk
# default: on# vim /usr/bin/clustercheck
#!/bin/bash二十五. 备份与还原
# innobackupex-1.5.1 --defaults-file=/data/3306/my.cnf --galera-info --user=root --socket=/tmp/mysql.sock --password=$PASSWORD /backup/mysql/3306