MariaDB+Galera+Haproxy+Keepalived搭建集群
1.MariaDB Galera Cluster介绍
MariaDB Galera Cluster是MariaDB同步多主机集群,它仅支持XtraDB/InnoDB存储引擎,在MySQLInnoDB存储引擎基础上打了wrep(虚拟全同步复制)
MariaDB Galera Cluster主要功能:
同步复制;真正的multi-master,即所有节点可以同时读写数据库;
自动的节点成员控制,失效节点自动被清除;新节点加入数据自动复制;
真正的并行复制,行级;用户可以直接连接集群,使用感受上与MySQL完全一致.
缺点:
a.加入新节点时开销大,需要复制完整的数据;
b.不能有效地解决写扩展的问题,所有的写操作都发生在所有的节点;
c.有多少个节点,就有多少份重复的数据;
d.由于事务提交需要跨节点通信,即涉及分布式事务操作,因此写入会比主从复制慢很多,节点越多,写入越慢,死锁和回滚也会更加频繁;
e.对网络要求比较高,如果网络出现波动不稳定,则可能会造成两个节点失联,Galera Cluster集群会发生脑裂,服务将不可用.
还有一些地方存在局限:
f.仅支持InnoDB/XtraDB存储引擎,任何写入其他引擎的表,包括mysql.*表都不会被复制,DDL语句可以复制,但是insert into mysql.user(MyISAM存储引擎)之类的插入数据不会被复制;
g.Delete操作不支持没有主键的表,因为没有主键的表在不同的节点上的顺序不同,如果执行select … limit …将出现不同的结果集;
h.LOCK/UNLOCK TABLES,FLUSH TABLES WITH READ LOCKS不支持单表锁,以及锁函数GET_LOCK()、RELEASE_LOCK(),但FLUSH TABLES WITH READ LOCK支持全局表锁;
i.General Query Log日志不能保存在表中,如果开始查询日志,则只能保存到文件中;
j.不能有大事务写入,不能操作wsrep_max_ws_rows=131072(行),且写入集不能超过wsrep_max_ws_size=1073741824(1GB),否则客户端直接报错;
k.由于集群是乐观锁并发控制,因此,在commit阶段会有事务冲突发生,如果两个事务在集群中的不同节点上对同一行写入并提交,则失败的节点将回滚,客户端返回死锁报错;
l.XA分布式事务不支持Codership Galera Cluster,在提交时可能会回滚;
m.整个集群的写入吞吐量取决于最弱的节点限制,集群要使用同一的配置.
Galera集群的复制功能是基于认证的复制,其流程如下:
当客户端发出一个commit的指令,在事务被提交之前,所有对数据库的更改都会被write-set收集起来,并且将write-set记录的内容发送给其他节点,write-set 将在每个节点上使用搜索到的主键进行确认性认证测试,测试结果决定着节点是否应用write-set更改数据.如果认证测试失败,节点将丢弃 write-set;如果认证测试成功,则事务提交.
2.配置并启动集群
MariaDB Server:10.2.24,系统版本:CentOS7.4 # 修改主机名 hostnamectl set-hostname --static MariaDB-Galera-30 cat /etc/hosts 10.0.0.30 MariaDB-Galera-30 10.0.0.31 MariaDB-Galera-31 10.0.0.32 MariaDB-Galera-32 vim /etc/security/limits.conf * soft nofile 65536 * hard nofile 65536 vim /etc/sysctl.conf fs.file-max = 655350 net.ipv4.ip_local_port_range = 1025 65000 net.ipv4.tcp_tw_recycle = 1 sysctl -p # 同步时间,关闭防火墙、selinux ntpdate ntp.aliyun.com # 使用国内yum源 cat /etc/yum.repos.d/mariadb.repo [mariadb] name=MariaDB baseurl=http://mirrors.ustc.edu.cn/mariadb/yum/10.2/centos7-amd64/ gpgkey=http://mirrors.ustc.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB gpgcheck=1 yum源帮你解决依赖关系,并且给你移除了系统自带的mariadb-libs-5.5.60这个库 # MariaDB 10.0版本这么安装 yum -y install MariaDB-Galera-server MariaDB-client galera # MariaDB 10.1版本开始,Galera Cluster就被包含在MariaDB包里,不需要单独部署MariaDB-Galera-server和galera yum -y install MariaDB-server MariaDB-client galera # 配置MariaDB 初始化MariaDB,每个节点都需要初始化一次,除了改密码mariadb123456,其余步骤都按Y /etc/init.d/mysql start /usr/bin/mysql_secure_installation # 也可以使用mysqladmin设置密码 /usr/bin/mysqladmin -u root password 'new-password' /usr/bin/mysqladmin -u root -h MariaDB-Galera-31 password 'new-password'
当使用xtrabackup方式进行热备时,才需要配置数据同步账号,而rsync方式不需要,所有节点初始化完成之后,就停掉MySQL,去修改配置文件
/etc/init.d/mysql stop cp /etc/my.cnf.d/server.cnf{,.bak} vim /etc/my.cnf.d/server.cnf [server] [mysqld] server_id=30 bind-address = 10.0.0.30 skip-external-locking skip-name-resolve innodb_file_per_table = on max_connections = 4096 collation-server = utf8_general_ci character-set-server=utf8 innodb_flush_method = O_DIRECT wait_timeout = 28800 binlog_cache_size = 16M max_allowed_packet = 64M expire_logs_days = 30 sort_buffer_size = 128M innodb_buffer_pool_size = 512M [galera] wsrep_on=ON wsrep_provider="/usr/lib64/galera/libgalera_smm.so" wsrep_cluster_address="gcomm://10.0.0.30,10.0.0.31,10.0.0.32" wsrep_cluster_name=galera_cluster wsrep_node_address=10.0.0.30 wsrep_node_name=MariaDB-Galera-30 wsrep_slave_threads=1 wsrep_causal_reads=ON wsrep_certify_nonPK=ON wsrep_sst_method=rsync binlog_format=row default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 bind-address = 10.0.0.30 innodb_flush_log_at_trx_commit=0 [embedded] [mariadb] [mariadb-10.2]
配置文件在不同服务器上的不同之处有五个:[mysqld]部分的前两行;[galera]部分的wsrep_node_address、wsrep_node_name、bind-address
在10.0.0.30上使用--wsrep-new-cluster启动,第一次启动时才使用此参数,再次启动不需要加该参数
mysqld_safe --defaults-file=/etc/my.cnf.d/server.cnf --user=mysql --wsrep-new-cluster &
启动其他节点数据库
mysqld_safe --defaults-file=/etc/my.cnf.d/server.cnf --user=mysql &
3.测试
# 在10.0.0.30执行命令,查看效果 mysql -uroot -pmariadb123456 # 可以看到集群规模为3 show status like 'wsrep_cluster_size'; show global status like 'ws%'; wsrep_cluster_status为Primary,表示节点为主节点,正常读写; wsrep_ready为ON,表示集群正常运行; # 创建数据库测试,可以在其它两台数据库上看到,数据可以同步 create database GaleraTest_db;
上面配置使用的是rsync方式同步数据,如果要使用xtrabackup方式,生产上用的就是这种同步方式,需要授权一个同步账号,并在配置文件中开启如下两行设置:
wsrep_sst_auth=galera:123456
wsrep_sst_method=xtrabackup-v2
默认是rsync全量拷贝,但是需要在donor节点上执行全局读锁(flushtables with read lock),建议采用xtrabackup热备份方式,只有在备份.frm表结构文件才会锁表.grant all on *.* to 'galera'@'localhost' identified by '123456';
# 创建MyISAM表测试 use GaleraTest_db; create table myisam_tbl (id int,name text) ENGINE MyISAM; insert into myisam_tbl values(1,'hive'); 在其他节点看不到这个表中的数据,可以得出:MyISAM存储的表,Galera不支持同步的结论. # 模拟节点故障,停掉10.0.0.30的数据库 mysqladmin -uroot -p "shutdown" 此时集群自动将10.0.0.30故障节点剔除,并且正常提供服务,恢复失败的节点,会自动上线 # 模拟脑裂后的处理 在网络抖动发生丢包的情况下,两个节点失联导致脑裂 通过这个命令来强制恢复出现脑裂的节点 set global wsrep_provider_options="pc.bootstrap=true"; # 当所有节点都关闭后,怎么重启Cluster 最后离开集群/停止的数据库主机,要最启动,否则可能导致数据丢失 首先,在任意一台主机上编辑/var/lib/mysql/grastate.dat,修改seqno的值,将-1改为1; 然后,使用命令galera_new_cluster启动集群; 最后,通过/etc/init.d/mysql start启动其他节点.
4.搭建Haproxy+Keepalived
搭建成功后,前端只需要通过VIP连接数据库,由Haproxy担任负载均衡,Galera担任数据同步
10.0.0.28 Haproxy-28 10.0.0.29 Haproxy-29
yum -y install keepalived cat /etc/keepalived/keepalived.conf global_defs { router_id Haproxy28 } vrrp_script chk_haproxy { script "/etc/keepalived/chk_haproxy.sh" interval 1 weight 2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 201 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } track_script { chk_haproxy } virtual_ipaddress { 10.0.0.20/24 } track_interface { eth0 } } virtual_router_id:虚拟路由编号,主从要一致 与10.0.0.28相比,配置参数在10.0.0.29上有三个不同之处: router_id Haproxy29;state BACKUP;priority 99 # 这里我的网卡名是eth0,根据个人机器进行修改.先不要启动keepalived,最后再起 cat /etc/keepalived/chk_haproxy.sh #!/bin/bash chkha=`ps -C haproxy --no-header |wc -l` if [ $chkha -eq 0 ];then systemctl stop keepalived fi chmod +x /etc/keepalived/chk_haproxy.sh
搭建haproxy可参考:https://www.cnblogs.com/fawaikuangtu123/p/10356418.html
cat /etc/haproxy/haproxy.cfg global log 127.0.0.1 local2 chroot /usr/local/haproxy pidfile /usr/local/haproxy/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon spread-checks 3 tune.bufsize 32768 tune.maxrewrite 1024 tune.ssl.default-dh-param 2048 defaults log global log 127.0.0.1 local3 mode http option httplog option dontlognull retries 10 option redispatch timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen mariadb bind *:3306 mode tcp balance roundrobin server MariaDB-Galera-30 10.0.0.30:3306 weight 5 server MariaDB-Galera-31 10.0.0.31:3306 weight 5 server MariaDB-Galera-32 10.0.0.32:3306 weight 5 listen stats bind *:1080 mode http option httplog maxconn 10 stats enable stats refresh 30s stats uri /stats stats realm MaCluster\ Haproxy stats auth admin:admin stats hide-version stats admin if TRUE 10.0.0.28和10.0.0.29的haproxy.cfg是一样的,两台服务器先启动haproxy,再去启动keepalived systemctl start haproxy.service systemctl enable haproxy.service systemctl start keepalived.service systemctl enable keepalived.service
现在可以通过虚拟IP访问数据库了,先授权一个用户,拿10.0.0.29当客户端
# 在10.0.0.30上授权用户 grant all on *.* to 'remoteuser'@'10.0.0.%' identified by 'Mysql@123'; flush privileges;
10.0.0.29上现在没有虚拟IP,但是能访问到,说明达到了实验效果
MariaDB镜像设置:https://www.cnblogs.com/liujiacai/p/9042906.html
Galera集群搭建参考:https://blog.csdn.net/jiangshouzhuang/article/details/62468778
Galera排错博客:https://www.cnblogs.com/nulige/articles/8470001.html
haproxy+keepalived这一篇有详细注释:https://www.cnblogs.com/phpstudy2015-6/p/6706465.html
绿肥红瘦写的差不多但有点乱:https://www.cnblogs.com/xll970105/p/9881105.html
他的一篇OpenVPN看着像是那么回事:https://www.cnblogs.com/xll970105/p/10382638.html
集群主要参考--智林心语:https://www.andylouse.net/linux-galera-haproxy-keepalived-mariadb
他也有一篇OpenVPN:https://www.andylouse.net/linux-openvpn-server-and-client-configure