基于半同步复制的MHA高可用MySql集群架构搭建实战
一、什么是MHA架构
1. 简介
MHA(Master High Availability)是一套比较成熟的 MySQL 高可用方案,也是一款优秀的故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。MHA还支持在线快速将Master切换到其他主机,通常只需0.5-2秒。
目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器。
2. MHA组成部分
MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。
MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。负责检测master是否宕机、控制故障转移、检查MySQL复制状况等。
MHA Node运行在每台MySQL服务器上,不管是Master角色,还是Slave角色,都称为Node,是被监控管理的对象节点,负责保存和复制master的二进制日志、识别差异的中继日志事件并将其差异的事件应用于其他的slave、清除中继日志。
MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master,整个故障转移过程对应用程序完全透明。
MHA架构图如下
3.MHA故障处理机制:
把宕机master的binlog保存下来
根据binlog位置点找到最新的slave
用最新slave的relay log修复其它slave
将保存下来的binlog在最新的slave上恢复
将最新的slave提升为master
将其它slave重新指向新提升的master,并开启主从复制
4. MHA优点:
自动故障转移快
主库崩溃不存在数据一致性问题
性能优秀,支持半同步复制和异步复制
一个Manager监控节点可以监控多个集群
二、MHA架构搭建
1. 集群环境(4台主机,1主、2从、1 MHA)
机器名称 | IP | 用途 | 备注 |
---|---|---|---|
master | 192.168.2.201 | 主数据库 | centos7 已安装mysql5.7版本 |
slave1 | 192.168.2.202 | 从数据库 | centos7已安装mysql5.7版本 |
slave2 | 192.168.2.203 | 从数据库 | centos7 已安装mysql5.7版本 |
manager | 192.168.2.204 | MHA manager | centos7 初始环境,未安装任何软件 |
2. MySql主从复制集群搭建
2.1 配置主数据库
修改配置文件并增加如下配置
[root@localhost ~]# vim /etc/my.cnf
# 开启二进制文件日志
log_bin=mysql-bin
# 服务id 不同主机不能重复
server-id=1
#可选 每次执行写日志操作都与磁盘进行同步
sync-binlog=1
#可选 不进行数据同步的数据库
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
# 可选 需要进行同步的数据库
binlog-do-db=database
重启数据库服务
[root@localhost ~]# systemctl restart mysqld
登录mysql数据库并进行授权
[root@localhost ~]# mysql -uroot -p
mysql> use mysql;
mysql>grant replication slave on *.* to 'root'@'%' identified by '123456';
mysql>grant all privileges on *.* to 'root'@'%' identified by '123456';
注意:
若授权时有报错
Your password does not satisfy the current policy requirements
此时为密码 不符合安全策略, 我们需要调整mysql的密码安全级别
查看密码策略
mysql> show variables like 'validate_password%';
+--------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------+-------+
| validate_password_check_user_name | OFF |
| validate_password_dictionary_file | |
| validate_password_length | 8 |
| validate_password_mixed_case_count | 1 |
| validate_password_number_count | 1 |
| validate_password_policy |MEDIUM |
| validate_password_special_char_count | 1 |
+--------------------------------------+-------+
可以看到此时mysql的密码策略较高, 我们需要调低
mysql> set global validate_password_policy=0;
mysql> set global validate_password_length=1;
然后在进行授权操作就可以了
授权成功后, 我们查看下master状态
mysql> show master status
注意图中红框中的内容, 配置从节点同步数据时需要用到此内容
2.2 从数据库配置
同样编辑配置文件添加如下配置
# 注意与主库和其他从库区别
server-id=2
# 中继日志名称 不指定为默认值
relay_log=mysql-relay-bin
#只读
read_only=1
重启后查看从库状态
mysql>show slave status;
Empty set (0.00 sec) # 表明为第一次设置从库 若有信息 需要 drop slave
指定需要同步的主库信息
# 注意切换到mysql数据库
mysql>use mysql;
mysql>change master to master_host='192.168.2.201',master_port=3306,master_user='root',master_password='123456',master_log_file='mysql-bin.00002',master_log_pos=869;
master_host #主库host地址
master_port #主库端口
master_user #登录主库的用户名
master_password #密码
master_log_file #需要同步的主库日志文件, 此处为查看主库状态时file 列对应的值
master_log_pos #同步起始位置 此处为查看主库状态时position 列对应的值
启动从库
mysql>start slave;
3. 开启半同步复制功能
半同步复制需要 semi 模块的支持, 我们当前安装的mysql5.7版本未安装semi插件, 所以需要我们手动安装semi模块
先查看是否支持动态插件安装
mysql>select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES |
+------------------------+
1 row in set (0.00 sec)
安装semi插件 并命名"semisync_master.so" (同 maradb)
# 主库需要安装master模块
mysql>install plugin rpl_semi_sync_master soname 'semisync_master.so';
# 从库安装slave模块
mysql>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
修改semi 参数
# 查看semi相关参数
mysql>show variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.02 sec)
主库参数修改
# 开启semi插件
mysql>set global rpl_semi_sync_master_enabled=1;
# 设置超时时间
mysql>set global rpl_semi_sync_master_timeout=1000;
从库参数修改
# 开启semi插件
mysql>set global rpl_semi_sync_slave_enabled=1;
重启slave
mysql>stop slave;
mysql>start slave;
4. 基于主从复制搭建MHA高可用集群
4.1 修改数据库配置
MHA slave节点都需要开启二进制日志和中继日志, 且需要关闭relay log的自动清除功能, 同时指定需要同步的数据库配置必须和主库一致, 所以需要修改slave的配置文件, 增加如下配置信息
# 开启二进制日志
log-bin=mysql-bin
# 是否自动清空不再需要中继日志
relay_log_purge=0
# 指定忽略的数据库, 与master配置一致
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
MHA在发生切换的过程中,从库的恢复过程中依赖于relay log的相关信息,所以这里要将relay log的自动清除设置为OFF,采用手动清除relay log的方式。在默认情况下,从服务器上的中继日志会在SQL线程执行完毕后被自动删除。但是在MHA环境中,这些中继日志在恢复其他从服务器时可能会被用到,因此需要禁用中继日志的自动删除功能。定期清除中继日志需要考虑到复制延时的问题。在ext3的文件系统下,删除大的文件需要一定的时间,会导致严重的复制延时。为了避免复制延时,需要暂时为中继日志创建硬链接,因为在Linux系统中通过硬链接删除大文件速度会很快。
4.2 开启各个主机间 的 ssh免密码登录
MHA集群中的各节点彼此之间均需要基于ssh互信通信,以实现远程控制及数据管理功能。简单起见,可在Manager节点生成密钥对儿,并设置其可远程连接本地主机后, 将私钥文件及authorized_keys文件复制给余下的所有节点即可。
注意:下面操作在所有节点上操作
[root@localhost ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): // 回车
Enter passphrase (empty for no passphrase): // 回车
Enter same passphrase again: // 回车
当前主机为: 192.168.2.204
[root@localhost ~]# ssh-copy-id 192.168.2.201
[root@localhost ~]# ssh-copy-id 192.168.2.203
[root@localhost ~]# ssh-copy-id 192.168.2.204
当四台机器都进行了上述操作以后,我们可以在 manager 机器上看到如下文件:
[root@localhost ~]# cd .ssh/
[root@localhost .ssh]# ls
authorized_keys id_rsa id_rsa.pub known_hosts
[root@localhost .ssh]# cat authorized_keys
此时,我们也可以在机器上实验一下,看看 ssh 是否还需要输入密码。本步骤完成。
4.3 MHA 安装
在本步骤中, Manager节点需要另外多安装一个包。具体需要安装的内容如下:
四个节点都需安装:mha4mysql-node-0.58-0.el7.centos.noarch.rpm
Manager 节点另需要安装:mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
将下载好的rmp安装包上传到各个主机, 执行如下命令进行安装
先切换到rmp所在目录, 我上传时就直接上传到了root目录下了
[root@localhost ~]# mha4mysql-node-0.58-0.el7.centos.noarch.rpm
# manager节点需要单独安装
[root@localhost ~]# mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
4.4 定义 MHA 管理配置文件
Manager 节点需要为每个监控的 master/slave 集群提供一个专用的配置文件,而所有的 master/slave 集群也可共享全局配置。全局配置文件默认为/etc/masterha_default.cnf
,其为可选配置。如果仅监控一组 master/slave 集群,也可直接通过 application 的配置来提供各服务器的默认配置信息。而每个 application 的配置文件路径为自定义。
创建mha配置文件并添加如下配置内容
文件路径及名称可以自己定义, 我的配置文件及路径是: /etc/mha_master/mha.cnf
# 通用配置 适用于server1,2,3 三个server的配置
[server default]
# 配置mha管理用户的用户名和密码
# 设置监控用户root
user=root
# 设置MySQL中root用户的密码,这个密码是前文中创建监控用户的那个密码
password=123456
#mha manager的工作路径
manager_workdir=/data/mha_manager/app1
#mha manager日志存放路径
manager_log=/data/mha_manager/app1/log/manager.log
# 远程主机工作目录 即 设置远端mysql在发生切换时binlog的保存位置
remote_workdir=/data/mha_manager/app1
# 设置ssh的登录用户名
ssh_user=root
# slave数据库用户名及密码
repl_user=root
repl_password=123456
# 设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover
ping_interval=1
[server1]
hostname=192.168.2.201
port=3306
# 设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库。
candidate_master=1
[server2]
hostname=192.168.2.202
port=3306
candidate_master=1
[server3]
hostname=192.168.2.203
port=3306
candidate_master=1
# no_master=1 此配置可以指定server3永远不能称为主节点
[root@localhost log]#
4.5 SSH 有效性验证
[root@localhost ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf
若未能测试成功,
再重新配置一遍ssh认证即可
此时表明ssh连通性没有问题
4.6 集群复制的有效性验证
[root@localhost ~]# masterha_check_repl --conf=/etc/mha_master/mha.cnf
踩的坑
配置的mha管理用户必须是经过授权的
slave节点需要开启二进制日志
slave节点需要开启中继日志
slave节点库同步配置信息要与master节点一致
否则在此步
会报错!
会报错!
会报错!
解决了一系列问题后, 终于看到我想看到了的
注意:验证成功的话会自动识别出所有服务器和主从状况!!!
4.7 启动 manager
[root@localhost ~]# masterha_manager --conf=/etc/mha_master/mha.cnf
注意:在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会用&在程序结尾来让程序自动运行。比如我们要运行mysql在后台:/usr/local/mysql/bin/mysqld_safe –user=mysql&。可是有很多程序并不想mysqld一样,这样我们就需要nohup命令,
nohup masterha_manager –conf=/etc/mha_master/mha.cnf > /data/mha_manager/app1/mha_manager.log &1 &
4.8 模拟故障,检测状态转移
我们停掉master节点后, 来看一下manager日志
cat /data/mha_manager/app1/log/manager.log #此路径是我在mha.cnf中配置的manager日志存放路径
可以看到, mha已经识别到master已经挂掉, 并且成功的将主节点从192.168.2.201 转移到了 192.168.2.202上。
4.9 故障恢复
停掉的原master节点, 再次上线后也会作为slave节点, 若要重新设置为master节点需要进行一下几个步骤
在mha manager节点上删除app1.failover.complete文件
cd /data/mha_manager/app1 //此目录为配置文件mha.cnf我设置的mha工作目录
rm -f app1.failover.complete // 删除此文件启动原master主节点mysql服务
此时若验证集群复制的有效性会报错
查看现在的slave1上的信息
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000010
Position: 120
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)配置原master节点mysql为新的slave,并启动同步进程
mysql> change master to master_host='192.168.2.202',
master_user='root',
master_password='123456',
master_log_file='mysql-bin.000010',
master_log_pos=120;
mysql> start slave;注意:按如上步骤操作后,此时201节点作为slaver已加入到集群中,但是宕机这段时间202、203中新产生的数据在201中没有,所以还需要先从主节点备份导入最新的数据再启动同步
启动MHA
nohup masterha_manager –conf=/etc/mha_master/mha.cnf > /data/mha_manager/app1/mha_manager.log &1 &
同样的道理,以上步骤配置无问题的话停止当前master的MySQL进程,MHA可直接切换master至原节点
切换过程中需要关注的几个问题
切换过程会自动把read_only关闭
切换之后需要删除手工删除/masterha/app1/app1.failover.complete,才能进行第二次测试
一旦发生切换管理进程将会退出,无法进行再次测试,需将故障数据库加入到MHA环境中来
原主节点重新加入到MHA时只能设置为slave,在
change master to master_host='192.168.56.122',
master_user='repl',
master_password='repl',
master_log_file='mysql-bin.000010',
master_log_pos=120;
之前需要先 reset slave
注意:二级从服务器需要将log_slave_updates打开
通过设置no_master=1可以让某一个节点永远不成为新的主节点