参考地址:mysql 高可用架构之 MHA,haproxy 实现读写分离详解
实验步骤:
ssh 证书户信任(ssh 的密钥验证)
ABB 架构
安装 mha_manager 、 mha_node
测试
IP 地址规划:
Mysql_manager(10.211.55.23)—需要是 64 位的系统
MySQL_A(10.211.55.20)
MySQL_B1(10.211.55.21)
MySQL_B2(10.211.55.22)
ssh 证书互信脚本---每台机器上都要操作
使用 ssh-kegen 生成公私钥(每台服务器上),下面是批量执行脚本:
ABB 搭建
Mysql 的安装(感觉下面的安装方法比较简单):
wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
yum install mysql-community-server
service mysqld restart
mysql -u root
mysql> set password for 'root'@'localhost' =password('youpassword');
所有的机器初始化 MySQL,设置 ABB 架构:
MYSQL_A(20)上的操作:
vim /etc/my.cnf
server_id=1 //设置优先级最高
log_bin=binlog //开启 binlog 日志
log_biin=binlog.index
注意:MYSQL_B1、MYSQL_B2 上的操作同 mysql_a 只是注意 server_id 的不同!
设置用户
在 msyql_a(20)中:因为前面已经开启二进制日志了,所以其他机器也能学到赋权语句!!故其他机器就不用再赋权了!
//给mha_manager用,因为其在failover时需要登陆上来,并且拷贝binlog到所有的slave上去
jdata1> grant all on *.* to 'root'@'%' identified by 'youpassword';
//复制专用用户
jdata1> grant replication slave on *.* to 'sky'@'%' identified by 'youpassword';
//刷新权限
jdata1> flush privileges;
//看一下binlog日志到第几个文件了
jdata1> show master status\G
在 mysql_b1(21)中:
mysql> stop slave;
mysql> change master to master_host='10.211.55.20',master_user='sky',master_password='yourpassword',master_log_file='mysql-bin.000003';
mysql> reset slave; (注意:如果之前因为同步数据的时候sql执行错误,这里要清除掉)
mysql> start slave;
mysql> show slave status\G //查看复制线程状态
在 mysql_b2(22)做 21 上同样的操作!
安装配置启动 mha_manager、mha_node
manager 机器上(23):cd /root/zing (mha4mysql-node 和 mha4mysql-manager rpm 文件,要保存这 2 个文件,这 2 个东西不好找,下面提供下载地址)
网盘链接:mha 软件下载
在管理节点安装 MHA 管理组件,先安装 node 再安装 manager 软件本身有依赖关系
yum install mha4mysql-node-0.56-0.el6.noarch.rpm
yum install mha4mysql-manager-0.56-0.el6.noarch.rpm
manager 需要一下包的依赖:
在 node 节点上,执行下面的命令:yum install perl-DBD-MySQL
*在 manager 节点上:
yum install perl-DBD-MySQL
yum install perl-Config-Tiny
yum install perl-Log-Dispatch
yum install perl-Parallel-ForkManager
yum install -y rrdtool perl-rrdtool rrdtool-devel perl-Params-Validate
坑点 1:发现 yum 不能安装 perl-Log-Dispatch 和 perl-Parallel-ForkManager:
下载并安装 EPEL
[root@localhost ~]# wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
[root@localhost ~]# rpm -ivh epel-release-latest-7.noarch.rpm
[root@localhost ~]# yum repolist ##检查是否已添加至源列表
OK,检查好已添加至源后就可以进行 yum 安装了。
最后,将 mha4mysql-node 包复制到集群中的所有节点:
for i in 1 2 3 ;
do
scp mha4mysql-node-0.56-0.el6.noarch.rpm 10.211.55.2$i:/usr/src;
done
mha_node: 安装到其他 node(所有其他机器)
[root@MHA_240 mha_soft]# yum install -y mha4mysql-node-0.54-0.el6.noarch.rpm
mha_manager: (MHA 20 上)
[root@MHA_240 mha]# cp -pr /usr/src/mha_soft/mha/ /etc/ //mha的配置文件和启动
文件(注意:这里我是没有找到 mha.cnf 和 mha_start,vi 创建 mha.cnf 文件)
配置如下:
[server default]
#mysql admin account and password
user=root
password=62661206
#mha workdir and worklog
manager_workdir=/etc/mha
manager_log=/etc/mha/manager.log
#mysql A/B account and pw
repl_user=sky
repl_password=62661206
#check_mha_node time
ping_interval=1
#ssh account
ssh_user=root
[server1]
hostname=10.211.55.20
ssh_port=22
master_binlog_dir=/var/lib/mysql
candidate_master=1
[server2]
hostname=10.211.55.21
ssh_port=22
master_binlog_dir=/var/lib/mysql
candidate_master=1
[server3]
hostname=10.211.55.22
ssh_port=22
master_binlog_dir=/var/lib/mysql
candidate_master=1
检测 ssh 互信有没有问题
[root@localhost src]# masterha_check_ssh --conf=/etc/mha/mha.cnf
Tue Jun 13 02:21:31 2017 - [info] All SSH connection tests passed successfully. 有这个表示成功
测 AB
[root@localhost src]# masterha_check_repl --conf=/etc/mha/mha.cnf
…
MySQL Replication Health is OK.
坑点 2:masterha_check_repl 检测没有通过,报下面错误:
MHA 报错:There is no alive slave. We can't do failover
关于该问题,比较靠谱的解释是:(我的问题是没有关防火墙)
MHA 默认去连接 MySQL 的端口是:3306
如果你的主机名解析,或者你写的 IP 都没问题**,防火墙也关闭了**,那么,剩下的原因是:
你的 MySQL,没有运行在默认端口上。
如果不能修改 MySQL 的端口为:3306。
那么你可以给 MHA,添加 PORT 描述。
vi /etc/mha/mha_start //编辑 mha 启动脚本,直接运行下面启动也可以
nohup masterha_manager --conf=/etc/mha/mha.cnf > /tmp/mha_manager.log 2>&1 &
测试
现在两个 slave 的 Master_Host 同为 241,把 241 干掉后,就会选举新的 master 了!
先在 mha_manager 上打开日志:
tail -f /etc/mha/manager.log
到 20 上关闭 MySQL 服务:
service mysqld stop
查看 mha_manager 日志输出:
----- Failover Report -----
mha: MySQL Master failover 10.211.55.20 to 10.211.55.21 succeeded
Master 10.211.55.21 is down!
Check MHA Manager logs at localhost.localdomain:/etc/mha/manager.log for details.
Started automated(non-interactive) failover.
The latest slave 10.211.55.21(10.211.55.21:3306) has all relay logs for recovery.
Selected 10.211.55.21 as a new master.
10.211.55.21: OK: Applying all logs succeeded.
10.211.55.21: This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
10.211.55.21: OK: Applying all logs succeeded. Slave started, replicating from 10.211.55.21.
10.211.55.21: Resetting slave info succeeded.
Master failover to 10.211.55.20(10.211.55.21:3306) completed successfully.
看来 21 变成了 master!~
可以去新主上创建个库或到 21 上查看一下 master.info 来验证!!
下面演示 old_master 回来,如何保证 old_master 同步 new_master 的新产生的数据:
当 old_master 服务宕掉后,去 mha_monitor 上执行:
[root@mha_master mha]# grep -i change /etc/mha/manager.log (-i 是不区分大小写)
**Tue Jun 13 02:30:23 2018 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.211.55.21', MASTER_PORT=3306, MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=106, MASTER_USER='sky', MASTER_PASSWORD='xxx';**
然后在 old_master 上执行:
mysql> slave stop;
mysql> change master to master_host='10.211.55.21', master_port=3306, master_log_file='binlog.000001', master_log_pos=106, master_user='sky', master_password='youpassword';(只需要修改密码即可)
mysql> slave start;
坑点 3:mysql 的密码忘记了,重置密码的解决方案:
重置密码解决 MySQL for Linux 错误 ERROR 1045 (28000)
方法如下:
vim /etc/my.cnf(注:windows下修改的是my.ini)
在文档内搜索 mysqld 定位到[mysqld]文本段:
/mysqld(在 vim 编辑状态下直接输入该命令可搜索文本内容)
保存文档并退出:
:wq
2.接下来我们需要重启 MySQL:
service mysqld restart
3.重启之后输入#mysql 即可进入 mysql。
4.接下来就是用 sql 来修改 root 的密码
mysql> use mysql;
mysql> update user set password=password("你的新密码") where user="root";
mysql> flush privileges;
mysql> quit
到这里 root 账户就已经重置成新的密码了。
5.编辑 my.cnf,去掉刚才添加的内容,然后重启 MySQL。大功告成。
坑点 4:&>/dev/null 表示的意思
用 /dev/null 2>&1 这样的写法.这条命令的意思是将标准输出和错误输出全部重定向到/dev/null 中,也就是将产生的所有信息丢弃.
MHA failover(master 故障)后 VIP 漂移
MHA 架构中,master 来承担写请求,但是如果发生了 failover,那么就应该让 new_master 来承担写请求,有哪些方式可以实现呢?
- 改变 master 的 IP:在 web 上修改 PHP 页面的代码(所有写请求修改成 new_master 的 IP)
- 使用虚拟 IP(VIP),将 VIP 漂移给 new_master
显然,第二种方案要更加容易实现、高效。
实现起来,大家可能会首当其冲的想到 keepalived,但是在这里不适用,因为我们不好判断哪一个 salve 会在 failover 后变成 master(在 keepalived 中,VIP 根据物理路由器的优先级来确定,万一漂到一台 slave 上那可如何是好!)。不过我们可以通过脚本的方式来实现将 VIP 绑定到 new_master 上。
脚本思路如下:
脚本(/etc/mha/check_mysql)运行在 manager 上,它来管理 VIP
判断谁是主,确保它有 VIP,并继续判断,如果 slave 有 VIP,则收回。
脚本名称:master_vip_drift.sh(如果不是 salve 的话,|grep -w 'Slave_IO_Running'应该是错误的不是 1)
参考链接 shell 脚本报错
shell 脚本报错:"[: =: unary operator expected"
究其原因,是因为如果变量 STATUS 值为空,那么就成了 [ = "OK"] ,显然 [ 和 "OK" 不相等并且缺少了 [ 符号,所以报了这样的错误。当然不总是出错,如果变量 STATUS 值不为空,程序就正常了,所以这样的错误还是很隐蔽的。
改成 if [[ $STATUS = "OK" ]];
分析 failover 日志—了解 MHA 工作流程
- tailf /etc/mha/manager.log
- 到 master 上关闭 MySQL 服务
- 查看日志并从头往下捋一遍
MySQL MHA 读写分离
Mysql_manager 和 HAProxy(10.211.55.23)
MySQL_A(10.211.55.20)
MySQL_B1(10.211.55.21)
MySQL_B2(10.211.55.22)
结构图说明:
a.MHA 对 abb 架构实行监控,发现 a 宕之后选出新 a(实现 VIP 漂移,仅 a 有 VIP)
b.haproxy 对 slave 集群实现负载均衡,承担读请求
c.web 集群请求后台数据,写请求传给 a(VIP),读请求传给 haproxy,haproxy 再对读请求实现分发达到负载均衡
安装 HAProxy(10.211.55.23)
网盘链接:mha 软件下载
yum install gcc -y
tar xf haproxy-1.5.3.tar
make TARGET=linux26 PREFIX=/usr/local/haproxy
make install PREFIX=/usr/local/haproxy
cp /usr/src/haproxy/haproxy-1.5.3/examples/haproxy.cfg /usr/local/haproxy/
cp /usr/src/haproxy/haproxy-1.5.3/examples/haproxy.init /etc/init.d/haproxy
chmod 755 /etc/init.d/haproxy
ln -s /usr/local/haproxy/sbin/* /usr/sbin/
mkdir /etc/haproxy
mkdir /usr/share/haproxy
ln -s /usr/local/haproxy/haproxy.cfg /etc/haproxy/
cd ..
设置配置文件
[root@HAProxy_247 haproxy]# cp haproxy.cfg /usr/local/haproxy/
编辑配置文件
[root@HAProxy_247 haproxy]# vim /usr/local/haproxy/haproxy.cfg
# this config needs haproxy-1.1.28 or haproxy-1.2.1
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096
chroot /usr/share/haproxy
uid 99
gid 99
daemon
#debug
#quiet
defaults
log global
mode http
#option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen MySQL 0.0.0.0:3306
mode tcp
maxconn 200
balance roundrobin
option mysql-check user root
server mysql_1 10.211.55.21:3306 inter 1s rise 2 fall 2
server mysql_2 10.211.55.22:3306 inter 1s rise 2 fall 2
listen admin_status
mode http
bind 0.0.0.0:8899
option httplog
log global
stats enable
stats refresh 10s
stats hide-version
stats realm Haproxy\ Statistics
stats uri /admin-status
stats auth admin:123456
stats admin if TRUE
启动 HAProxy 服务
[root@HAProxy_247 haproxy]# service haproxy start
访问 HAProxy 的网页(用户名密码查看配置文件舍子)
http://localhost:8899/admin-status
客户端测试:
mysql -uroot -pyoupassword -h 10.211.55.23
在 HAProxy 管理界面,可以看到那台 slave 响应的请求
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于