MariaDB+Galera+Haproxy+Keepalived搭建集群

时间:2023-03-08 23:55:07
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
weight
} vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id
priority
advert_int
authentication {
auth_type PASS
auth_pass
}
track_script {
chk_haproxy
}
virtual_ipaddress {
10.0.0.20/
}
track_interface {
eth0
}
} virtual_router_id:虚拟路由编号,主从要一致
与10.0.0.28相比,配置参数在10.0.0.29上有三个不同之处:
router_id Haproxy29;state BACKUP;priority
# 这里我的网卡名是eth0,根据个人机器进行修改.先不要启动keepalived,最后再起
cat /etc/keepalived/chk_haproxy.sh
#!/bin/bash
chkha=`ps -C haproxy --no-header |wc -l`
if [ $chkha -eq ];then
systemctl stop keepalived
fi chmod +x /etc/keepalived/chk_haproxy.sh

在10.0.0.28上操作,搭建keepalived

搭建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
user haproxy
group haproxy
daemon
spread-checks
tune.bufsize
tune.maxrewrite
tune.ssl.default-dh-param defaults
log global
log 127.0.0.1 local3
mode http
option httplog
option dontlognull
retries
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 listen mariadb
bind *:
mode tcp
balance roundrobin
server MariaDB-Galera- 10.0.0.30: weight
server MariaDB-Galera- 10.0.0.31: weight
server MariaDB-Galera- 10.0.0.32: weight listen stats
bind *:
mode http
option httplog
maxconn
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..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

haproxy配置文件

现在可以通过虚拟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+Galera+Haproxy+Keepalived搭建集群

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