MMM是Multi-Master Replication Manager for MySQL的缩写,它是MySQL提供的一个多主复制管理器,其核心是使用perl语言编写的一组脚本。实际上MMM是比较早期甚至有点老的一种用于构建高可用MySQL架构的方式,但因其还有一定的应用场景,所以本文将会演示一下如何搭建一个MMM架构。
MMM 由两个组件组成:
monitor
:监控集群内数据库的状态,在出现异常时发布切换命令,一般和数据库分开部署agent
:运行在每个 MySQL 服务器上的代理进程,monitor
命令的执行者,完成监控的探针工作和具体服务设置,例如设置 VIP、指向新同步节点MMM的主要作用:
MMM提供了什么功能:
MMM对于主备切换后如何让从库同步日志点:
本文要搭建的MMM架构如下:
以上述架构为例,描述一下故障转移的流程,现在假设 Master1 宕机:
read_only=1
select master_pos_wait()
等待同步完毕read_only=0
从整个流程可以看到,如果主节点出现故障,MMM 会自动实现切换,不需要人工干预,同时我们也能看出一些问题,就是数据库挂掉后,只是做了切换,不会主动补齐丢失的数据,所以 MMM 会有数据不一致性的风险。
搭建MMM架构所需的资源说明:
名称 | 数量 | 说明 |
---|---|---|
Master服务器 | 2 | 用于主备模式的主主复制配置 |
Slave服务器 | 0-N | 可以配置0台或多台从服务器,但不建议太多 |
监控服务器 | 1 | 安装MMM用于监控MySQL复制集群 |
IP地址 | 2*(n+1) | n为MySQL服务器的数量 |
监控用户 | 1 | 用于监控数据库状态的MySQL用户(至少拥有replication client 权限) |
代理用户 | 1 | 用于MMM代理的MySQL用户(至少拥有super 、replication client 、process 权限) |
复制用户 | 1 | 用于配置MySQL主从复制的用户(至少拥有replication slave 权限) |
本文中所使用的机器说明:
名称 | IP | 角色 |
---|---|---|
master-01 | 192.168.190.146 | 主库 |
master-02 | 192.168.190.148 | 备库 |
slave-01 | 192.168.190.149 | 从库 |
manager | 192.168.190.147 | 集群管理器(MMM) |
环境版本说明:
另外的说明:
1、在master-01
和master-02
上使用如下语句分别创建用于主主复制的MySQL用户:
create user 'repl'@'%' identified with mysql_native_password by 'Abc_123456';
grant replication slave on *.* to 'repl'@'%';
flush privileges;
2、修改master-01
上的MySQL配置文件:
[root@master-01 ~]# vim /etc/my.cnf
[mysqld]
# 设置节点的id
server_id=101
# 开启binlog,并指定binlog文件的名称
log_bin=mysql_bin
# 开启relay_log,并指定relay_log文件的名称
relay_log=relay_bin
# 将relaylog的同步内容记录到binlog中
log_slave_updates=on
在master-02
的配置文件中也是添加一样配置,只不过server_id
不一样:
[root@master-02 ~]# vim /etc/my.cnf
[mysqld]
server_id=102
log_bin=mysql_bin
relay_log=relay_bin
log_slave_updates=on
接着是配置slave-01
,由于该节点不是作为备库存在,而只是单独的从库角色,所以不需要开启log_slave_updates
参数:
[root@slave-01 ~]# vim /etc/my.cnf
[mysqld]
server_id=103
log_bin=mysql_bin
relay_log=relay_bin
完成以上配置文件的修改后,分别重启这三个节点上的MySQL服务:
[root@master-01 ~]# systemctl restart mysqld
[root@master-02 ~]# systemctl restart mysqld
[root@slave-01 ~]# systemctl restart mysqld
master-02
对master-01
的主从关系进入master-01
的MySQL命令行终端,通过如下语句查询master-01
当前正在使用的二进制日志及当前执行二进制日志位置:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
记录其中的File
和Position
的值,然后进入master-02
的MySQL命令行终端,分别执行如下语句:
mysql> stop slave; -- 停止主从同步
mysql> change master to master_host='192.168.190.146', master_port=3306, master_user='repl', master_password='Abc_123456', master_log_file='mysql_bin.000001', master_log_pos=155; -- 配置master-01节点的连接信息,以及从哪个binlog文件的哪个位置开始复制
mysql> start slave; -- 启动主从同步
配置完主从关系后,使用show slave status\G;
语句查看主从同步状态,Slave_IO_Running
和Slave_SQL_Running
的值均为Yes
才能表示主从同步状态是正常的:
master-01
对master-02
的主从关系为了实现主主复制,master-01
和master-02
需要互为主从关系,所以还需要配置master-01
对master-02
的主从关系。进入master-02
的MySQL命令行终端,通过如下语句查询master-02
当前正在使用的二进制日志及当前执行二进制日志位置:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
记录其中的File
和Position
的值,然后进入master-01
的MySQL命令行终端,分别执行如下语句:
mysql> stop slave;
mysql> change master to master_host='192.168.190.148', master_port=3306, master_user='repl', master_password='Abc_123456', master_log_file='mysql_bin.000001', master_log_pos=155;
mysql> start slave;
同样配置完成后,使用show slave status\G;
语句查看主从同步状态,Slave_IO_Running
和Slave_SQL_Running
的值均为Yes
才能表示主从同步状态是正常的:
slave-01
对master-01
的主从关系接着就是配置从库对主库的主从关系了,这里与master-02
是一样的,除非期间对master-01
上的数据做了修改才需要重新获取日志点:
mysql> stop slave;
mysql> change master to master_host='192.168.190.146', master_port=3306, master_user='repl', master_password='Abc_123456', master_log_file='mysql_bin.000001', master_log_pos=155;
mysql> start slave;
1、在所有的机器上安装 epel
源:
yum install -y epel-release
2、在所有的主从节点上安装MMM代理客户端:
yum install -y mysql-mmm-agent
3、在 manager
节点上安装所有的MMM包:
yum install -y mysql-mmm*
4、然后在master-01
上创建用于监控和代理的MySQL用户:
-- 监控用户
create user 'mmm_monitor'@'%' identified with mysql_native_password by 'Abc_123456';
grant replication client on *.* to 'mmm_monitor'@'%';
-- 代理用户
create user 'mmm_agent'@'%' identified with mysql_native_password by 'Abc_123456';
grant super, replication client, process on *.* to 'mmm_agent'@'%';
flush privileges;
由于配置了主从的原因,此时其他两个数据库节点也会同步这些新建的用户。在另外两个节点执行如下语句就可以查询到:
mysql> use mysql;
mysql> select host,user,plugin from user;
+-----------+------------------+-----------------------+
| host | user | plugin |
+-----------+------------------+-----------------------+
| % | mmm_agent | mysql_native_password |
| % | mmm_monitor | mysql_native_password |
| % | repl | mysql_native_password |
| localhost | mysql.infoschema | caching_sha2_password |
| localhost | mysql.session | caching_sha2_password |
| localhost | mysql.sys | caching_sha2_password |
| localhost | root | caching_sha2_password |
+-----------+------------------+-----------------------+
5、编辑所有节点包括监控节点上的mmm_common.conf
配置文件,主要是配置当前节点和集群中其他节点的信息。这里以master-01
节点为例,其配置内容如下:
[root@master-01 ~]# vim /etc/mysql-mmm/mmm_common.conf
active_master_role writer
<host default>
cluster_interface ens32 # 当前节点的网卡名称,用于绑定虚拟IP,可以ip addr命令查询
pid_path /run/mysql-mmm-agent.pid # pid文件存放的路径
bin_path /usr/libexec/mysql-mmm/ # 可执行文件存放的路径
replication_user repl # 用于复制的MySQL用户
replication_password Abc_123456 # repl用户的密码
agent_user mmm_agent # 用于代理的MySQL用户
agent_password Abc_123456 # mmm_agent用户的密码
</host>
# 配置master-01的ip地址和角色
<host db1>
ip 192.168.190.146
mode master
peer db2
</host>
# 配置master-02的ip地址和角色
<host db2>
ip 192.168.190.148
mode master
peer db1
</host>
# 配置slave-01的ip地址和角色
<host db3>
ip 192.168.190.149
mode slave
</host>
# 配置负责写操作的库
<role writer>
hosts db1, db2 # 指定可写的库,这里是上面host标签中定义的名称
ips 192.168.190.90 # 配置写虚拟IP,可以有多个使用逗号分隔
mode exclusive # 表示同一时刻只有一个主库提供服务
</role>
# 配置负责读操作的库
<role reader>
hosts db1, db2, db3 # 指定可读的库
ips 192.168.190.91,192.168.190.92,192.168.190.93 # 配置读虚拟IP
mode balanced # 表示将读请求负载均衡到以上所配置的db上
</role>
其他三个节点也按照相同的方式进行配置即可,除了网卡名称可能会不同外,其它的参数都应该是一致的。
6、然后配置各个节点的mmm_agent.conf
文件,声明当前节点在host
标签中所定义的名称。master-01
节点的配置如下:
[root@master-01 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1
master-02
节点的配置如下:
[root@master-02 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1
slave-01
节点的配置如下:
[root@slave-01 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db3
7、接着配置监控节点上的mmm_mon.conf
文件,配置内容如下:
[root@manager ~]# vim /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
<monitor>
ip 127.0.0.1
pid_path /run/mysql-mmm-monitor.pid
bin_path /usr/libexec/mysql-mmm
status_path /var/lib/mysql-mmm/mmm_mond.status
ping_ips 192.168.190.146,192.168.190.148,192.168.190.149 # 配置集群中各个节点的IP
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>
# 配置用于监控的MySQL用户和密码
monitor_user mmm_monitor
monitor_password Abc_123456
</host>
debug 0
8、启动所有主从节点的MMM代理服务:
[root@master-01 ~]# systemctl start mysql-mmm-agent
[root@master-02 ~]# systemctl start mysql-mmm-agent
[root@slave-01 ~]# systemctl start mysql-mmm-agent
agent
服务默认会监听9989
端口,如果开启了防火墙则需要开放该端口:
firewall-cmd --zone=public --add-port=9989/tcp --permanent
firewall-cmd --reload
9、启动监控节点上的监控服务:
[root@manager ~]# systemctl start mysql-mmm-monitor
10、完成以上所有步骤后,在监控节点上使用mmm_control show
命令就可以查看到集群中各个节点的状态及其分配的虚拟IP,如下示例:
[root@manager ~]# mmm_control show
db1(192.168.190.146) master/ONLINE. Roles: reader(192.168.190.91), writer(192.168.190.90)
db2(192.168.190.148) master/ONLINE. Roles: reader(192.168.190.93)
db3(192.168.190.149) slave/ONLINE. Roles: reader(192.168.190.92)
[root@manager ~]#
到此为止,我们就已经完成了MMM高可用架构的搭建,接下来我们对其进行一些简单的测试。例如,测试下是否能正常ping
通虚拟IP,毕竟应用端访问数据库时连接的是虚拟IP,所以首先得确保虚拟IP是能够被访问的。如下:
能ping
通之后,使用Navicat等远程连接工具测试下能否正常连接上:
确定了各个虚拟IP都能正常访问后,测试下MMM是否能正常进行故障转移,首先将master-01
上的MySQL服务给停掉:
[root@master-01 ~]# systemctl stop mysqld
正常情况下,此时到监控节点上使用mmm_control show
命令可以看到master-01
节点已经处于脱机状态,而用于写的虚拟IP正常的切换到了master-02
节点上:
[root@manager ~]# mmm_control show
db1(192.168.190.146) master/HARD_OFFLINE. Roles:
db2(192.168.190.148) master/ONLINE. Roles: reader(192.168.190.93), writer(192.168.190.90)
db3(192.168.190.149) slave/ONLINE. Roles: reader(192.168.190.91), reader(192.168.190.92)
[root@manager ~]#
接着进入slave-01
节点上的MySQL终端。之前我们配置slave-01
的主库是master-01
,现在已经将master-01
停掉后,可以看到slave-01
的主库被MMM切换成了master-02
:
经过以上测试后,可以看到我们搭建的MMM架构是能够正常运行的,已经使得Replication集群拥有了基本的高可用能力,即便主库下线后也能正常切换到备库上,也正确建立了从库与新主库的关系。
综合优缺点可以得知:MMM仅适用于对数据一致性要求不高,允许丢失少量数据的场景下,例如评论、资讯类等数据
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。