MariaDB Galera Cluster
Galera Cluster是MariaDB的一个双活多主集群,其可以使得MariDB的所有节点保持同步,Galera为MariaDB提供了同步复制(相对于原生的异步复制),因此其可以保证HA,且其当前仅支持XtraDB/InnoDB存储引擎(扩展支持MyISAM),并且只可在Linux下使用。
从MariaDB 10.1开始,在Galera Cluster中默认已经包含了wsrep API。在MariaDB 10.0和MariaDB 5.5时还是独立的,所以在安装部署上可能会有所不同,具体看MariaDB官方介绍。
Galera Cluster的特性:
● 真正的多主架构,任何节点都可以进行读写。
● 同步复制,各节点间无延迟且节点宕机不会导致数据丢失。
● 紧密耦合,所有节点均保持相同状态,节点间无不同数据。
● 无需主从切换操作或使用VIP。
● 热Standby,在Failover过程中无停机时间(由于不需要Failover)。
● 自动节点配置,无需手工备份当前数据库并拷贝至新节点。
● 支持InnoDB存储引擎。
● 对应于透明,无需更改应用或是进行极小的更改。
● 无需进行读写分离。
Galera Cluster的优势:
● 因为是多主,所以不存在Slavelag(延迟)。
● 不存在丢失事务的情况。
● 同时具有读和写的扩展能力。
● 更小的客户端延迟。
● 节点间数据是同步的,而Master/Slave模式是异步的,不同slave上的binlog可能是不同的。
Galera Cluster局限性:
● 目前的复制仅仅支持InnoDB存储引擎,任何写入其他引擎的表,包括mysql.*表将不会复制,但是DDL语句会被复制的,因此创建用户将会被复制,但是insert into mysql.user…将不会被复制的。
● DELETE操作不支持没有主键的表,没有主键的表在不同的节点顺序将不同,如果执行SELECT…LIMIT… 将出现不同的结果集。
● 在多主环境下LOCK/UNLOCK TABLES不支持,以及锁函数GET_LOCK(), RELEASE_LOCK()…。
● 查询日志不能保存在表中,如果开启查询日志,只能保存到文件中。
● 允许最大的事务大小由wsrep_max_ws_rows和wsrep_max_ws_size定义,任何大型操作将被拒绝,如大型的LOAD DATA操作。
● 由于集群是乐观的并发控制,事务commit可能在该阶段中止。如果有两个事务向在集群中不同的节点向同一行写入并提交,失败的节点将中止。对于集群级别的中止,集群返回死锁错误代码(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK))。
● XA事务不支持,由于在提交上可能回滚。
● 整个集群的写入吞吐量是由最弱的节点限制,如果有一个节点变得缓慢,那么整个集群将是缓慢的。为了稳定的高性能要求,所有的节点应使用统一的硬件。
● 集群节点建议最少3个。
● 如果DDL语句有问题将破坏集群。
Galera Cluster技术实现:
Galera集群的复制功能基于Galeralibrary实现,为了让MySQL与Galera library通讯,特别针对MySQL开发了wsrep API。
Galera插件保证集群同步数据,保持数据的一致性,靠的就是可认证的复制,工作原理如下图:
当客户端发出一个commit的指令,在事务被提交之前,所有对数据库的更改都会被write-set收集起来,并且将write-set纪录的内容发送给其他节点。
write-set将在每个节点进行认证测试,测试结果决定着节点是否应用write-set更改数据。
如果认证测试失败,节点将丢弃write-set;如果认证测试成功,则事务提交。
部署MariaDB Galera Cluster
一、部署前环境准备
安装MariaDB集群至少需要3台服务器(如果只有两台的话需要特殊配置,请参照官方文档)。
在这里,我列出三台试验机器的配置:
1 2 3 4 |
系统类型 主机名 IP地址 作用 CentOS7 - mc01 - 172.29.32.200 - MariaDB Galera Cluster Master node CentOS7 - mc02 - 172.29.32.200 - MariaDB Galera Cluster Master node CentOS7 - mc03 - 172.29.32.200 - MariaDB Galera Cluster Master node |
1)各个节点配置主机名
1 2 3 |
[root@mc01 ~]# hostname mc01 [root@mc02 ~]# hostname mc02 [root@mc03 ~]# hostname mc03 |
1 2 3 |
[root@mc01 ~]# echo "mc01" > /etc/hostname [root@mc02 ~]# echo "mc02" > /etc/hostname [root@mc03 ~]# echo "mc03" > /etc/hostname |
2)各个节点配置hosts实现本地解析
1 2 3 4 |
$ cat /etc/hosts 172.29.32.200 mc01 172.29.32.201 mc02 172.29.32.202 mc03 |
3)关闭各节点防火墙和SELINUX
1 2 3 4 |
$ systemctl stop firewalld.service $ systemctl disable firewalld.service $ systemctl status firewalld.service $ systemctl is-enabled firewalld.service |
1 2 3 |
$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux $ setenforce 0 $ getenforce |
注意:一定要关闭系统防火墙和SELINUX,如果需要防火墙,则参照官方网站增加防火墙信息设置,MariaDB Galera Cluster主机之间需要通信,防火墙默认是阻挡的,从而会导致你的MariaDB启动不了(启动时需要通信)。
4)配置NTP(chrony)
1 2 3 4 |
$ yum install chrony $ systemctl enable chronyd.service $ systemctl start chronyd.service $ systemctl status chronyd.service |
查看时间同步源状态
1 |
$ chronyc sourcestats -v |
PS:集群中的主机都需要时间同步,具体chrony如何使用自行查资料。
以上做完,系统初始化工作就搞定了,下面就开始来部署MariaDB Galera Cluster。
二、开始部署MariaDB Galera Cluster
自MariaDB 10.1版本开始 wsrep API已经集成在MariaDB中,配置比之前简便了许多,具体配置过程参考下文。
1)安装配置MariaDB Galera Cluster 10.1
部署MariaDB Galera Cluster 10.1版本有两种选择,一个是使用MariaDB官方,第二种是使用OpenStack源, OpenStack云平台很多核心组件都需要用到数据库服务(有些服务使用noSQL),OpenStack默认就使用MariaDB数据库,并且推荐使用MariaDB Galera Cluster。
这里我们使用OpenStack源安装MariaDB Galera Cluster,如果使用MariaDB官方源安装也一样,但在安装包上不太相同,具体看官方。配置上基本没有太大差别,除了个别配置文件的名称以及默认配置略有差别外。
先下载OpenStack源。
1 |
$ yum install centos-release-openstack-mitaka |
然后在各个节点上分别安装MariaDB集群相关软件包。
1 |
$ yum install -y mariadb mariadb-server-galera mariadb-galera-common galera rsync |
查看安装的软件包
1 2 3 4 5 6 7 8 |
$ rpm -qa | grep mariadb mariadb-errmsg-10.1.12-4.el7.x86_64 mariadb-galera-common-5.5.40-3.el7.x86_64 mariadb-server-galera-10.1.12-4.el7.x86_64 mariadb-common-10.1.12-4.el7.x86_64 mariadb-10.1.12-4.el7.x86_64 mariadb-server-10.1.12-4.el7.x86_64 mariadb-libs-5.5.44-2.el7.centos.x86_64 |
MariaDB基本配置(各个节点)
1 |
$ cat /etc/my.cnf.d/mariadb-server.cnf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[mysqld] ###默认配置### datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid ###新增配置### bind-address = 0.0.0.0 default-storage-engine = innodb innodb_file_per_table max_connections = 4096 collation-server = utf8_general_ci character-set-server = utf8 |
MariaDB Galera Cluster基本配置(各个节点)
1 |
$ cat /etc/my.cnf.d/galera.cnf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[mysqld] ###新增配置### wsrep_on=ON binlog_format=ROW default-storage-engine=innodb bind-address=0.0.0.0 wsrep_provider=/usr/lib64/galera/libgalera_smm.so wsrep_cluster_name="my_wsrep_cluster" wsrep_cluster_address="gcomm://mc01,mc02,mc03" wsrep_node_name=mc01 wsrep_node_address=172.29.32.200 wsrep_sst_method=rsync wsrep_sst_auth=root: ###默认配置### wsrep_slave_threads=1 innodb_autoinc_lock_mode=2 wsrep_certify_nonPK=1 wsrep_max_ws_rows=131072 wsrep_max_ws_size=1073741824 wsrep_debug=0 wsrep_convert_LOCK_to_trx=0 wsrep_retry_autocommit=1 wsrep_auto_increment_control=1 wsrep_drupal_282555_workaround=0 wsrep_causal_reads=0 wsrep_notify_cmd= |
可以在第一个节点配置完成后,将配置文件拷贝到其他节点,只需要修改如下两项为节点自己的参数即可
wsrep_node_name=[每个节点配置自己的主机名]
wsrep_node_address=[每个节点配置自己的IP地址]
重要参数解释:
wsrep_on=ON
#该配置项从10.1.1版本增加的,必须配置ON选项。
binlog_format=ROW
#二进制日志的格式必须为ROW格式。
default-storage-engine=innodb
#指定默认存储引擎为inodb。
bind-address=0.0.0.0
#指定Galera监听的地址。
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
#指定Galera的库。
wsrep_cluster_name=”my_wsrep_cluster”
#MariaDB集群的名称,一般不需要更改,名称最好不要带特殊字符,如”-“是MariaDB无法识别的。
wsrep_cluster_address=”gcomm://mc01,mc02,mc03″
#在之前的版本galera集群的第一个节点配置wsrep_cluster_address =”gcomm:// “,即空置,但是现在可以每个节点都配置一样了,在启动cluster的脚步会自动处理。
wsrep_node_name=mc01
#每个节点配置自己的主机名。
wsrep_node_address=172.29.32.200
#每个节点配置自己的IP地址。
wsrep_sst_method=rsync
#指定集群间通信的方式,默认使用rsync(在安装MariaDB时就安装了),通过tcp进行通信的,具体可以看MariaDB启动时的日志信息,默认在/var/log/mariadb/mariadb.log。
wsrep_sst_auth=root:
#集群间的身份验证,指不指定都行。
wsrep_slave_threads
#可以指定wsrep的线程数,提高复制效率。
2)启动MariaDB Galera Cluster
当各个节点都配置完后,这时候我们只需要在其中一个节点执行启动MariaDB Galera Cluster。并且要使用Galera自带的工具启动,如下:
1 |
[root@mc01 ~]# galera_new_cluster |
这里又需要注意,只有在第一次启动时需要使用该工具启动,并且只需要在一个节点上启动,它会生成一个集群ID。以后的每次启动使用systemctl start mariadb.service即可。
启动完成后检查日志是否有错误信息(/var/log/mariadb/mariadb.log),并逐一解决。也可以查看一下MariaDB是否正常启动:
1 2 3 |
[root@mc01 ~]# netstat -nplt | grep mysql tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 4762/mysqld tcp 0 0 0.0.0.0:4567 0.0.0.0:* LISTEN 4762/mysqld |
其中3306端口是MariaDB开启的端口,而4567端口是Galera启动的端口。
3)启动剩余节点MariaDB服务
1 2 |
[root@mc02 ~]# systemctl start mariadb.service [root@mc03 ~]# systemctl start mariadb.service |
如果都正常启动固然是好,如果启动报错,你可以一边启动一边去看MariaDB的启动日志,基本都有启动不了的原因。如下,我碰到的报错:
1 2 3 |
[ERROR] WSREP: gcs/src/gcs_core.c:gcs_core_open():202: Failed to open backend connection: -110 (Connection timed out) [ERROR] WSREP: gcs/src/gcs.c:gcs_open():1291: Failed to open channel 'my_wsrep_cluster' at 'gcomm://mc01,mc02,mc03': -110 (Connection timed out) [ERROR] WSREP: gcs connect failed: Connection timed out |
就是由于我的主机防火墙忘记关了导致各个节点之间无法探测。
当各个节点都启动完成后,此时MariaDB Galera Cluster应该就已经在工作了。
4)检查集群是否构建成功
1 |
[root@mc01 ~]# mysql -e "show status like 'wsrep_%'" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
+------------------------------+----------------------------------------------------------+ | Variable_name | Value | +------------------------------+----------------------------------------------------------+ | wsrep_apply_oooe | 0.000000 | | wsrep_apply_oool | 0.000000 | | wsrep_apply_window | 0.000000 | | wsrep_causal_reads | 0 | | wsrep_cert_deps_distance | 0.000000 | | wsrep_cert_index_size | 0 | | wsrep_cert_interval | 0.000000 | | wsrep_cluster_conf_id | 5 | | wsrep_cluster_size | 3 | | wsrep_cluster_state_uuid | 963cd314-7072-11e6-ac31-16d397a77e7e | | wsrep_cluster_status | Primary | | wsrep_commit_oooe | 0.000000 | | wsrep_commit_oool | 0.000000 | | wsrep_commit_window | 0.000000 | | wsrep_connected | ON | | wsrep_flow_control_paused | 0.000000 | | wsrep_flow_control_paused_ns | 0 | | wsrep_flow_control_recv | 0 | | wsrep_flow_control_sent | 0 | | wsrep_incoming_addresses | 172.29.32.200:3306,172.29.32.201:3306,172.29.32.202:3306 | | wsrep_last_committed | 0 | | wsrep_local_bf_aborts | 0 | | wsrep_local_cached_downto | 18446744073709551615 | | wsrep_local_cert_failures | 0 | | wsrep_local_commits | 0 | | wsrep_local_index | 0 | | wsrep_local_recv_queue | 0 | | wsrep_local_recv_queue_avg | 0.083333 | | wsrep_local_replays | 0 | | wsrep_local_send_queue | 0 | | wsrep_local_send_queue_avg | 0.000000 | | wsrep_local_state | 4 | | wsrep_local_state_comment | Synced | | wsrep_local_state_uuid | 963cd314-7072-11e6-ac31-16d397a77e7e | | wsrep_protocol_version | 5 | | wsrep_provider_name | Galera | | wsrep_provider_vendor | Codership Oy <info@codership.com> | | wsrep_provider_version | 3.5(rXXXX) | | wsrep_ready | ON | | wsrep_received | 12 | | wsrep_received_bytes | 1360 | | wsrep_repl_data_bytes | 0 | | wsrep_repl_keys | 0 | | wsrep_repl_keys_bytes | 0 | | wsrep_repl_other_bytes | 0 | | wsrep_replicated | 0 | | wsrep_replicated_bytes | 0 | | wsrep_thread_count | 2 | +------------------------------+----------------------------------------------------------+ |
具体参数含义解释
以下参数能对整个集群的做集群完整性检查、节点状态检查、复制健康状态检查、网络瓶颈检查、冲突或死锁检测等,具体参数如下:
wsrep_cluster_state_uuid
#此参数的值是集群的UUID,每个节点应该一致,可以由此看出节点是否还是集群的一员。
wsrep_cluster_status
#集群节点的状态, 正常应该返回primary,其他状态异常,说明出现”分区”或是”split-brain”状况。
wsrep_cluster_conf_id
#显示集群变更次数,所有节点应该一致, 反之说明有节点与集群断开了。
wsrep_cluster_size
#集群中节点的数量。
wsrep_incoming_addresses
#集群中成员的IP地址和端口。
wsrep_connected
#当前是否连接中,如果该值为Off,且wsrep_ready的值也为Off,则说明该节点没有连接到集群。
wsrep_flow_control_paused
#表示复制停止了多长时间,即表明集群因为Slave延迟而慢的程度,值为0~1,越靠近0越好。值为1表示复制完全停止,可优化wsrep_slave_threads的值来改善。
wsrep_flow_control_sent
wsrep_flow_control_sent
#表示该节点已经停止复制了多少次。
wsrep_last_committed
#最新提交事物的记录。
wsrep_local_commits
#本地SQL提交记录。
wsrep_local_cert_failures
#本地事物提交失败记录。
wsrep_local_bf_aborts
#本地事物回滚的次数。
wsrep_local_send_queue
wsrep_local_recv_queue
#本地发送和接收的队列。
wsrep_local_send_queue_avg
wsrep_local_recv_queue_avg
#表示slave事务队列的平均长度,slave瓶颈的预兆。
wsrep_local_state_comment
#是否在同步中,如果wsrep_connected为On,但wsrep_ready为OFF,则可以从该项查看原因。
wsrep_ready
#插件是否应用中。
wsrep_replicated
#随着复制发出的次数。
wsrep_replicated_bytes
#随着复制发出的字节数。
5)验证数据同步
我们可以使用初始化MariaDB的方式来验证数据同步,使用MariaDB自带的mysql_secure_installation工具增强MariaDB的安全性,这个工具会删除多余用户及测试库,然后会让你设置root密码。
在其中的一台主机上使用此工具,如下:
1 |
[root@mc01 ~]# mysql_secure_installation |
具体过程省略,当你设置密码后,如果登录各个节点都需要密码了,就证明主机之间开始同步了。
当然最简单的就是创建一个数据库,看看其他主机是否同步过去了。
MariaDB负载均衡
当MariaDB Galera Cluster集群搭建完成后,通过任意一个节点都可以连接进行数据操作。当然我们可以借助于haproxy或lvs来实现MySQL数据库集群之间的负载均衡,也很简单,有需要的自行查阅资料。
http://blog.sina.com.cn/s/blog_53b13d950102uxpw.html