MySQL MHA 高可用架构

MySQL MHA	项目的地址:https://code.google.com/p/mysql-master-ha/,这个网站需要翻墙才能打开。MySQL MHA	是目前比较成熟的高可用解决方案。

在MySQL故障切换过程中,MHA(Master High Availability)能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

它由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序是完全透明的。

在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度地保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此它们彼此保持一致性。

目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台从当master,一台从当备用master,另一台从当slave,因为至少需要三台数据库,出于机器成本考虑,淘宝也在此基础上进行了改造,目前淘宝TMHA已经支持一主一从。

##准备工作
##在虚拟机里面安装4台主机,关闭防火墙、iptables、ip6tables、并在/etc/hosts里面加入如下配置:
10.10.10.10	manager
10.10.10.11	master
10.10.10.12	slave1
10.10.10.13	slave2

1、主机部署
manager:10.10.10.10
master:10.10.10.11
slave1:10.10.10.12(备用master)
slave2:10.10.10.13

2、首先用ssh-keygen实现4台主机之间相互免密匙登陆(4台机器都执行)
ssh-keygen -t rsa
ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
##最后测试:在每个节点上测试连接。验证当您再次运行以下命令时,系统是否不提示您输入口令。 
ssh manager date
ssh master date
ssh slave1 date
ssh slave2 date
##这一步一定要测试成功才能进行后面的安装!

3、安装MHA node
##MHA node 在4台机器都执行。在manager(10.10.10.10)上面也要安装MHA node。
##安装mha node之前需要先安装perl的DBD::mysql模块
# yum update
# yum -y install perl perl-devel cpan
# yum -y install perl-DBD-MySQL ncftp
# rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm
##mha node 安装完成后会在/usr/bin 下面生成以下四个脚本:(这些工具通常由mha manger的脚本触发,无需人工操作)
/usr/bin/save_binary_logs       ##保存和复制master的二进制日志
/usr/bin/apply_diff_relay_logs  ##识别差异的中继日志事件并将其差异的事件应用于其他slave
/usr/bin/filter_mysqlbinlog     ##去除不必要的ROLLBACK事件(MHA已经不再使用这个工具)
/usr/bin/purge_relay_logs       ##清除中继日志(不会阻塞SQL线程)

4、安装MHA manager
##MHA manager 只需要在manager(10.10.10.10)上面安装。
##安装mha manager也需要先安装一些perl模块
# yum update
# yum -y install perl perl-devel cpan
# yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes ncftp
# yum -y install perl-Config-IniFiles perl-Params-Validate perl-Test-Mock-LWP.noarch perl-LWP-Authen-Negotiate.noarch
# rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm
##mha manager 安装完成后会在/usr/bin 下面生成一些脚本:
/usr/bin/masterha_check_repl         ##检查mysql复制状况
/usr/bin/masterha_check_ssh          ##检查MHA的ssh配置状况
/usr/bin/masterha_check_status       ##检测当前MHA运行状态
/usr/bin/masterha_conf_host          ##添加或删除配置的server信息
/usr/bin/masterha_manager            ##启动MHA
/usr/bin/masterha_master_monitor     ##监测master是否宕机
/usr/bin/masterha_master_switch      ##控制故障转移(自动或手动)
/usr/bin/masterha_secondary_check    ##也是监测master是否宕机的脚本
/usr/bin/masterha_stop               ##关闭MHA

5、搭建主从复制环境
##由于我这里是在虚拟机里面刚新安装的mysql数据库,这里就没有备份、恢复的步骤了。master、slave1和slave2三台数据库的my.cnf配置一模一样,只是server-id分别为1、2、3。
[client]
port            = 3306
socket          = /mydata/data/3306/mysql_3306.sock
default-character-set=utf8
[mysqld]
port            = 3306
socket          = /mydata/data/3306/mysql_3306.sock
pid-file        = /mydata/data/3306/mysql.pid
user            = mysql
basedir        = /usr/local/mysql
datadir        = /mydata/data/3306
character_set_server=utf8
character_set_client=utf8
collation-server=utf8_general_ci
lower_case_table_names=1
log-bin=mysql-bin
server-id=1
relay-log=mysql-relay-bin
read-only=true
relay-log-purge=false
##master上操作:
mysql> show master status;
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY '123';  ##其实这个用户应该在每台数据库中都存在,因为切换之后说不定那台数据库就成为新的master。
mysql> flush privileges;
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
mysql> set global rpl_semi_sync_master_enabled=1;
mysql> set global rpl_semi_sync_master_timeout=30000;

##slave1和slave2上操作:
mysql> CHANGE MASTER TO
			MASTER_HOST='10.10.10.11',
			MASTER_PORT=3306,
			MASTER_USER='repl',
			MASTER_PASSWORD='123',
			MASTER_LOG_FILE='mysql-bin.000007',
			MASTER_LOG_POS=389;
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql> set global rpl_semi_sync_slave_enabled=1;
mysql> start slave;
##MySQL5.5引入了半同步复制,所以高可用架构一定要用半同步复制了。
##其实这个用户应该在每台数据库中都存在,因为切换之后说不定那台数据库就成为新的master。
mysql> GRANT ALL PRIVILEGES ON *.* TO 'mha_rep'@'%' IDENTIFIED BY '123';  ##在master上创建MHA监控所需的用户,会同步到slave端。
mysql> flush privileges;

6、管理机manager上配置MHA文件
# mkdir -p /masterha/app1
# mkdir -p /etc/masterha
# vim /etc/masterha/app1.cnf
[server default]
manager_log=/masterha/app1/manager.log   ##设置manager的日志
manager_workdir=/masterha/app1           ##设置manager的工作日志
user=mha_rep    ##监控用户
password=123    ##监控用户密码
ping_interval=1 ##设置监控主库,发送ping包的时间间隔,默认的是每隔3秒,尝试三次没有回应的时候自动failover
remote_workdir=/masterha/app1   ##设置远端mysql在发生切换时保存binlog的具体位置
repl_user=repl      ##设置复制用户
repl_password=123   ##设置复制用户密码
ssh_user=root       ##设置ssh的登录用户名
master_ip_failover_script=""         ##设置自动failover时候切换脚本
master_ip_online_change_script=""    ##设置手动failover时候切换脚本
shutdown_script=""                   ##设置故障发生后关闭故障主机脚本(防止发生脑裂)
##一旦MHA 到master 的监控之间网络出现问题,则将尝试从slave1 登陆到master
secondary_check_script=/usr/bin/masterha_secondary_check -s slave1 -s master --user=root --master_host=master --master_ip=10.10.10.11 --master_port=3306
[server1]
hostname=10.10.10.11
port=3306
master_binlog_dir=/mydata/data/3306      ##设置master默认保存binlog的位置,以便MHA可以找到master的日志
candidate_master=1  ##设置为候选master,如果设置该参数后,发生主从切换后会将此从库提升为主,即使这个库不是集群中最新的slave
check_repl_delay=0  ##在默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,此参数会忽略这个限制。
[server2]
hostname=10.10.10.12
port=3306
master_binlog_dir=/mydata/data/3306      ##设置master默认保存binlog的位置,以便MHA可以找到master的日志
candidate_master=1  ##设置为候选master,如果设置该参数后,发生主从切换后会将此从库提升为主,即使这个库不是集群中最新的slave
check_repl_delay=0  ##在默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,此参数会忽略这个限制。
[server3]
hostname=10.10.10.13
port=3306
master_binlog_dir=/mydata/data/3306      ##设置master默认保存binlog的位置,以便MHA可以找到master的日志
no_master=1         ##设置no_master=1使主机不能成为新master

7、验证(在manager上检查)
# masterha_check_ssh --conf=/etc/masterha/app1.cnf
# masterha_check_repl --conf=/etc/masterha/app1.cnf
# masterha_check_status --conf=/etc/masterha/app1.cnf

8、开启MHA监控(在manager上)
# nohup masterha_manager --conf=/etc/masterha/app1.cnf < /dev/null > /masterha/app1/manager.log 2>&1 &
# tail -f /masterha/app1/manager.log
# masterha_check_status --conf=/etc/masterha/app1.cnf

9、关闭MHA监控(在manager上,这里不执行)
# masterha_stop --conf=/etc/masterha/app1.cnf

10、测试自动failover
##在master上面停掉mysql数据库,现在slave1应该变为新的master了,然后在slave1上面查看:
mysql> show slave hosts;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         3 |      | 3306 |         2 | 91012b97-aed9-11e5-81b1-2053563b5ed8 |
+-----------+------+------+-----------+--------------------------------------+
1 row in set (0.00 sec)
##可以看见结果和我们预期的一样,现在在slave1上面插入一条数据,在slave2端也能看见。

11、恢复高可用架构
##failover成功之后,MHA就会停了,这时候是slave1 到slave2 的主从复制,假设10.10.10.11 数据库恢复了,那我们需要恢复高可用架构,让MHA启动。
##这是时候需要做的是,启动10.10.10.11 数据库,在manager上面执行以下命令,找到CHANGE MASTER 执行即可。
##10.10.10.10
[root@manager ~]# grep -i "All other slaves should start replication from here" /masterha/app1/manager.log 
Thu Dec 31 00:40:47 2015 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.10.10.12', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=529, MASTER_USER='repl', MASTER_PASSWORD='xxx';

##10.10.10.11
mysql> CHANGE MASTER TO 
    -> MASTER_HOST='10.10.10.12', 
    -> MASTER_PORT=3306, 
    -> MASTER_LOG_FILE='mysql-bin.000004', 
    -> MASTER_LOG_POS=529, 
    -> MASTER_USER='repl', 
    -> MASTER_PASSWORD='123';
Query OK, 0 rows affected, 2 warnings (0.04 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

##10.10.10.12
mysql> show slave hosts;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         1 |      | 3306 |         2 | c29a45e7-aed8-11e5-81ac-0050562dd34d |
|         3 |      | 3306 |         2 | 91012b97-aed9-11e5-81b1-2053563b5ed8 |
+-----------+------+------+-----------+--------------------------------------+
2 rows in set (0.00 sec)

##10.10.10.10
# rm -rf /masterha/app1/app1.failover.complete
# nohup masterha_manager --conf=/etc/masterha/app1.cnf < /dev/null > /masterha/app1/manager.log 2>&1 &
# masterha_check_status --conf=/etc/masterha/app1.cnf

猜你喜欢

转载自blog.csdn.net/zq9017197/article/details/50471370