共计 13696 个字符,预计需要花费 35 分钟才能阅读完成。
一、MMM 简介
MMM(Master-Master replication manager for MySQL)是一套支持双主故障切换和双主日常管理的脚本程序。MMM 使用 Perl 语言开发,主要用来监控和管理 MySQL Master-Master(双主)复制,虽然叫做双主复制,但是业务上同一时刻只允许对一个主进行写入,另一台备选主上提供部分读服务,以加速在主主切换时刻备选主的预热,可以说 MMM 这套脚本程序一方面实现了故障切换的功能,另一方面其内部附加的工具脚本也可以实现多个 slave 的 read 负载均衡。
MMM 提供了自动和手动两种方式移除一组服务器中复制延迟较高的服务器的虚拟 ip,同时它还可以备份数据,实现两节点之间的数据同步等。由于 MMM 无法完全的保证数据一致性,所以 MMM 适用于对数据的一致性要求不是很高,但是又想最大程度的保证业务可用性的场景。对于那些对数据的一致性要求很高的业务,非常不建议采用 MMM 这种高可用架构。
优点:
1 稳定和成熟的开源产品,经过了时间的考验 核心技术是 mysql 自己的技术,只是使用脚本程序来控制,所以在原理上比较容易理解,而且管理能够更智能化。2 安装简单,配置简单,使用简单
3 功能强大(HA,failover,tools 套件,cluster 模式可以一个 monitor 管理多个 mmm 组)
缺点:
1 由于架构里只有一个写入点,所以扩展性是有限的,但是对一般中型企业够用了。 解决方案:对于大应用可以采取垂直拆分到多个 mmm 架构的方式,使用 mmm cluster 来管理。2 对于读写分离和读负载均衡还是要程序来开发或者使用其他工具完成。
二、架构及配置环境
MySQL-MMM 架构图:
mysql-mmm 运行机制:
mysql-mmm 安装需求
Server n+1:
N 台安装 mysql 的机器和 1 台安装 mmm monitor 的机器。2*(n+1)Ips:
每个主机一个固定 ip、一个虚拟 IP(reader role), 全局一个 writer role IP
Monitor User:
一个可以在 mmm monitor 机器上使用的并且拥有 REPLICATION,CLIENT 权限的 mysql 用户
Agent User:
一个可以在 mmm agent 机器上使用的并且拥有 super,replication,client,process 权限的 mysql 用户
Replication user:
一个 slaves 主机上可以使用的并且有用 replication slave 权限的用户
Tools user:
一个 mmm tools 主机可以使用的,并且有用 super,replication client,reload 权限的 mysql 用户
安装环境:
1. 角色:
2. 虚拟 ip 规划:
3.hosts 文件配置 (全部机器):
192.168.1.11 master-db1
192.168.1.12 master-db2
192.168.1.13 slave-db1
192.168.1.14 slave-db2
192.168.1.15 mmm-monitor
4. 其他:
1 关闭 iptables
2 同步时间
3 配置 yum 和 epel 源
三、安装 MySQL 并配置
1.mysql 安装
由于篇幅有限,安装步骤见小弟另一篇文章 http://www.linuxidc.com/Linux/2018-01/150365.htm
2. 编辑配置文件 /etc/my.cnf:
master-db1
[mysqld]
server-id = 1
datadir = /Data/apps/mysql-5.6.36/data
log-bin = /Data/apps/mysql-5.6.36/data/mysql-bin
binlog_format = ROW
relay_log = /Data/apps/mysql-5.6.36/data/relay-log
auto-increment-increment = 2
auto-increment-offset = 1
sync_binlog = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
max_binlog_size = 100M
log_slave_updates = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
master-db2
[mysqld]
server-id = 2
datadir = /Data/apps/mysql-5.6.36/data
log-bin = /Data/apps/mysql-5.6.36/data/mysql-bin
binlog_format = ROW
relay_log = /Data/apps/mysql-5.6.36/data/relay-log
auto-increment-increment = 2
auto-increment-offset = 2
sync_binlog = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
max_binlog_size = 100M
log_slave_updates = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
slave-db1
[mysqld]
server-id = 3
datadir = /Data/apps/mysql-5.6.36/data
log-bin = /Data/apps/mysql-5.6.36/data/mysql-bin
binlog_format = ROW
relay_log = /Data/apps/mysql-5.6.36/data/relay-log
sync_binlog = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
max_binlog_size = 100M
log_slave_updates = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
slave-db2
[mysqld]
server-id = 4
datadir = /Data/apps/mysql-5.6.36/data
log-bin = /Data/apps/mysql-5.6.36/data/mysql-bin
binlog_format = ROW
relay_log = /Data/apps/mysql-5.6.36/data/relay-log
sync_binlog = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
max_binlog_size = 100M
log_slave_updates = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
3. 重启以上四台 mysql 服务
service mysqld restart
4. 在 master-db1 上创建 mmm 架构中需要的用户和权限
[root@master-db1 ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.36-log MySQL Community Server (GPL)
.......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'192.168.1.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.19 sec)
mysql> GRANT SUPER,REPLICATION CLIENT,PROCESS ON *.* TO 'mmm_agent'@'192.168.1.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'192.168.1.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.01 sec)
5. 查看二进制日志位置
mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.07 sec)
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 796 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.05 sec)
6. 不要关闭这个 mysql 进程连接,避免锁失效,我们另起一个 ssh 连接 db1 服务器,进行数据库备份:
[root@master-db1 ~]# mysqldump --all-databases > /tmp/database-backup.sql
7. 回到刚才 mysql 进程,进行解锁:
mysql> UNLOCK TABLES;
Query OK, 0 rows affected (0.05 sec)
8. 将 database-backup.sql 文件复制到其他 db 节点:
[root@master-db1 ~]# scp /tmp/database-backup.sql master-db2:/tmp
[root@master-db1 ~]# scp /tmp/database-backup.sql slave-db1:/tmp
[root@master-db1 ~]# scp /tmp/database-backup.sql slave-db2:/tmp
9.master-db,slave-db1,slave-db2 三台主机导入 sql 文件,并刷新权限:
[root@master-db2 ~]# mysql < /tmp/database-backup.sql
[root@master-db2 ~]# mysql -e "FLUSH PRIVILEGES;"
四、设置 MySQL 主 - 从和主 - 主配置
1. 在其他三台 mysql 上将 master-db1 设为主服务器
[root@master-db2 ~]# mysql
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.11',MASTER_USER='replication',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=796;
Query OK, 0 rows affected, 2 warnings (0.11 sec)
mysql> start slave;
Query OK, 0 rows affected (0.11 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.11
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 796
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
2. 查看 master-db2 的 master 日志位置:
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 636231 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
3. 在 master-db1 上操作,将 master-db2 设置为主:
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.12',MASTER_USER='replication',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=636231;
Query OK, 0 rows affected, 2 warnings (0.03 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.12
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 636231
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
五、安装 MMM
1. 创建 Tools user
useradd -s /sbin/nologin mmmd #所有机器
2. 查看 mmm 版本:
yum list all|grep ^mysql-mmm
mysql-mmm.noarch 2.2.1-2.el6 @epel
mysql-mmm-agent.noarch 2.2.1-2.el6 @epel
mysql-mmm-monitor.noarch 2.2.1-2.el6 epel
mysql-mmm-tools.noarch 2.2.1-2.el6 epel
3. 在 mmm-monitor 上安装:
[root@mmm-monitor ~]# yum -y install mysql-mmm-monitor
4. 在四台 mysql 服务器上安装:
yum -y install mysql-mmm-agent
5. 编写配置文件,五台主机必须一致:
[root@mmm-monitor ~]# vim /etc/mysql-mmm/mmm_common.conf
active_master_role writer #积极的 master 角色的标示,所有的 db 服务器要开启 read_only 参数,对于 writer 服务器监控代理会自动将 read_only 属性关闭。<host default>
cluster_interface eth0 #群集的网络接口
pid_path /var/run/mysql-mmm/mmm_agentd.pid #pid 路径
bin_path /usr/libexec/mysql-mmm/ # 可执行文件路径
replication_user replication # 复制用户
replication_password 123456 # 复制用户密码
agent_user mmm_agent # 代理用户
agent_password 123456 # 代理用户密码
</host>
<host master-db1> #master-db1 的 host 名称
ip 192.168.1.11 #master-db1 的 ip
mode master #角色属性,master 代表是主
peer master-db2 #与 master-db1 对等的服务器的 host 名,也就是 master-db2 的服务器 host 名
</host>
<host master-db2> #和 master-db1 的概念一样
ip 192.168.1.12
mode master
peer master-db1
</host>
<host slave-db1> #从库的 host 名, 如果存在多个从库可以重复一样的配置
ip 192.168.1.13 # 从的 ip
mode slave #slave 的角色属性代表当前 host 是从
</host>
<host slave-db2> # 和 slave-db1 的概念一样
ip 192.168.1.14
mode slave
</host>
<role writer> #writer 角色配置
hosts master-db1, master-db2 # 能进行写操作的服务器的 host 名,如果不想切换写操作这里可以只配置 master, 这样也可以避免因为网络延时而进行 write 的切换,但是一旦 master 出现故障那么当前的 MMM 就没有 writer 了只有对外的 read 操作。
ips 192.168.1.250 # 对外提供的写操作的虚拟 IP
mode exclusive #exclusive 代表只允许存在一个主,也就是只能提供一个写的 IP
</role>
<role reader> #read 角色配置
hosts master-db1, master-db2, slave-db1, slave-db2 #对外提供读操作的服务器的 host 名, 当然这里也可以把 master 加进来
ips 192.168.1.251, 192.168.1.252, 192.168.1.253, 192.168.1.254 # 对外提供读操作的虚拟 ip,这三个 ip 和 host 不是一一对应的, 并且 ips 也 hosts 的数目也可以不相同,如果这样配置的话其中一个 hosts 会分配两个 ip
mode balanced #balanced 代表负载均衡
</role>
6. 复制到其他服务器上
scp /etc/mysql-mmm/mmm_common.conf 192.168.1.11:/etc/mysql-mmm/mmm_common.conf
scp /etc/mysql-mmm/mmm_common.conf 192.168.1.12:/etc/mysql-mmm/mmm_common.conf
scp /etc/mysql-mmm/mmm_common.conf 192.168.1.13:/etc/mysql-mmm/mmm_common.conf
scp /etc/mysql-mmm/mmm_common.conf 192.168.1.14:/etc/mysql-mmm/mmm_common.conf
7. 在所有的 MySQL 上修改 mmm_agent.conf,只需要修改 master-db1 这里,是哪台就改成哪台,这里只给出 master-db1 的:
vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
# The 'this' variable refers to this server. Proper operation requires
# that 'this' server (db1 by default), as well as all other servers, have the
# proper IP addresses set in mmm_common.conf.
this master-db1
8. 配置 mmm-monitor 上的 mmm_mon.conf:
[root@mmm-monitor ~]# vim /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
<monitor>
ip 192.168.1.15
pid_path /var/run/mysql-mmm/mmm_mond.pid
bin_path /usr/libexec/mysql-mmm
status_path /var/lib/mysql-mmm/mmm_mond.status
ping_ips 192.168.1.11, 192.168.1.12, 192.168.1.13, 192.168.1.14
auto_set_online 60
# The kill_host_bin does not exist by default, though the monitor will
# throw a warning about it missing. See the section 5.10 "Kill Host
# Functionality" in the PDF documentation.
#
# kill_host_bin /usr/libexec/mysql-mmm/monitor/kill_host
#
</monitor>
<host default>
monitor_user mmm_monitor
monitor_password 123456
</host>
debug 0
9. 启动服务:
在 mmm-monitor 启动:
[root@mmm-monitor ~]# chkconfig mysql-mmm-monitor on
[root@mmm-monitor ~]# service mysql-mmm-monitor start
在所有 mysql 服务器上启动
chkconfig mysql-mmm-agent on
service mysql-mmm-agent start
六、高可用性测试:
服务器读写采有 VIP 地址进行读写,出现故障时 VIP 会漂移到其它节点,由其它节点提供服务。
mysql-mmm 故障处理机制:
1. 首先查看整个集群的状态,可以看到整个集群状态正常
[root@mmm-monitor ~]# mmm_control show
master-db1(192.168.1.11) master/ONLINE. Roles: reader(192.168.1.251), writer(192.168.1.250)
master-db2(192.168.1.12) master/ONLINE. Roles: reader(192.168.1.254)
slave-db1(192.168.1.13) slave/ONLINE. Roles: reader(192.168.1.252)
slave-db2(192.168.1.14) slave/ONLINE. Roles: reader(192.168.1.253)
2. 关闭 master-db1 上的 mysql 服务,模拟 mysql 宕机
[root@master-db1 ~]# service mysqld stop
Shutting down MySQL... [确定]
3.mmm-monitor 上查看集群状态
[root@mmm-monitor ~]# mmm_control show
master-db1(192.168.1.11) master/HARD_OFFLINE. Roles:
master-db2(192.168.1.12) master/ONLINE. Roles: reader(192.168.1.254), writer(192.168.1.250)
slave-db1(192.168.1.13) slave/ONLINE. Roles: reader(192.168.1.251), reader(192.168.1.252)
slave-db2(192.168.1.14) slave/ONLINE. Roles: reader(192.168.1.253)
从显示结果可以看出 master-db1 的状态有 ONLINE 转换为 HARD_OFFLINE,写 VIP 转移到了 master-db2 主机上。
4. 查看 slave-db1 和 slave-db2 主从状态
mysql> show slave status\G #slave-db1
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.12
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 636231
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
mysql> show slave status\G #slave-db2
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.12
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 636231
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
可以看到写请求的 VIP 已经转移到 master-db2 上了,且从节点的主都指向了 master-db2
5. 启动 master-db1 的 mysql 服务
[root@master-db1 ~]# service mysqld start
Starting MySQL...... [确定]
6. 再次查看集群状态 (大概等待一分钟左右)
[root@mmm-monitor ~]# mmm_control show
master-db1(192.168.1.11) master/ONLINE. Roles: reader(192.168.1.252)
master-db2(192.168.1.12) master/ONLINE. Roles: reader(192.168.1.254), writer(192.168.1.250)
slave-db1(192.168.1.13) slave/ONLINE. Roles: reader(192.168.1.251)
slave-db2(192.168.1.14) slave/ONLINE. Roles: reader(192.168.1.253)
7. 再次 slave-db1 和 slave-db2 主从状态
mysql> show slave status\G #slave-db1
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.12
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 636231
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
mysql> show slave status\G #slave-db2
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.12
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 636231
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
可以看到主库启动不会接管主,直到现有的主再次宕机。
mysql-mmm 故障处理机制中总结:
1. 对外提供读写的虚拟 IP 是由 monitor 程序控制。如果 monitor 没有启动那么 db 服务器不会被分配虚拟 ip, 但是如果已经分配好了虚拟 ip,当 monitor 程序关闭了原先分配的虚拟 ip 不会立即关闭外部程序还可以连接访问(只要不重启网络),这样的好处就是对于 monitor 的可靠性要求就会低一些,但是如果这个时候其中的某一个 db 服务器故障了就无法处理切换,也就是原先的虚拟 ip 还是维持不变,挂掉的那台 DB 的虚拟 ip 会变的不可访问。2.agent 程序受 monitor 程序的控制处理 write 切换,从库切换等操作。如果 monitor 进程关闭了那么 agent 进程就起不到什么作用,它本身不能处理故障。3.monitor 程序负责监控 db 服务器的状态,包括 Mysql 数据库、服务器是否运行、复制线程是否正常、主从延时等;它还用于控制 agent 程序处理故障。4.monitor 会每隔几秒钟监控 db 服务器的状态,如果 db 服务器已经从故障变成了正常,那么 monitor 会自动在 60s 之后将其设置为 online 状态 (默认是 60s 可以设为其它的值),有监控端的配置文件参数“auto_set_online”决定,群集服务器的状态有三种分别是:HARD_OFFLINE→AWAITING_RECOVERY→online
5. 默认 monitor 会控制 mmm_agent 会将 writer db 服务器 read_only 修改为 OFF,其它的 db 服务器 read_only 修改为 ON, 所以为了严谨可以在所有的服务器的 my.cnf 文件中加入 read_only= 1 由 monitor 控制来控制 writer 和 read,root 用户和复制用户不受 read_only 参数的影响。
mysql-mmm 架构总结:
(1)master-db2 备选主节点宕机不影响集群的状态,就是移除了 master-db2 备选节点的读状态。(2)master-db1 主节点宕机,由 master-db2 备选主节点接管写角色,slave-db1,slave-db2 指向新 master2 主库进行复制,slave-db1,slave-db2 会自动 change master 到 master2.
(3) 如果 master-db1 主库宕机,master-db2 复制应用又落后于 master-db1 时就变成了主可写状态,这时的数据主无法保证一致性。如果 master-db2,slave-db1,slave-db2 延迟于 master-db1 主,这个时 master-db1 宕机,slave-db1,slave-db2 将会等待数据追上 master-db1 后,再重新指向新的主 master-db2 进行复制操作,这时的数据也无法保证同步的一致性。(4) 如果采用 MMM 高可用架构,主,主备选节点机器配置一样,而且开启半同步进一步提高安全性或采用 MariaDB/mysql5.7 进行多线程从复制,提高复制的性能。
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2018-01/150364.htm