千家信息网

MySQL 5.6通过MMM实现读写分离的高可用架构

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,上一篇博文我们使用keepalived+主从同步搭建了一个简单的MySQL高可用架构(详见https://blog.51cto.com/jiangjianlong/1981994),今天再分享下通过M
千家信息网最后更新 2026年11月03日MySQL 5.6通过MMM实现读写分离的高可用架构

上一篇博文我们使用keepalived+主从同步搭建了一个简单的MySQL高可用架构(详见https://blog.51cto.com/jiangjianlong/1981994),今天再分享下通过MMM搭建的实现MySQL读写分离的高可用群集。MMM (Master-Master Replication Manager for MySQL)是使用perl开发的MySQL主主复制管理器,可实现读写分离的高可用架构,对主库实现写请求的高可用,对从库实现读请求的负载均衡。本文的架构示意图如下:

一、部署环境

二、环境准备

1、配置好IP地址、主机名,关闭防火墙和selinux

2、分别为mysql-master01、mysql-master02、mysql-slave01、mysql-slave02安装MySQL 5.6,安装方法请参见本文之前的博文《MySQL 5.6.38在RedHat 6.5上通过RPM包安装》,需要注意的是要安装Mysql-devel的rpm包。

3、为5台服务器配置好hosts解析:

192.168.10.81 mysql-master01

192.168.10.82 mysql-master02

192.168.10.83 mysql-slave01

192.168.10.84 mysql-slave02

192.168.10.85 mysql-monitor

4、将RedHat 6.5的介质配置成本地yum源


三、配置两台master互为主从

1、编辑mysql-master01和mysql-master02的/etc/my.cnf文件并重启mysql服务:

mysql-master01:

[mysqld] server-id=1              #每台设置不同log-bin=mysql-bin[mysqld_safe]auto_increment_increment=2  #字段一次递增多少 auto_increment_offset=1    #自增字段的起始值,master02需设置为2 replicate-do-db=all        #同步的数据库,多个用逗号隔开 log-slave_updates        #当一个主故障,另一个立即接管 sync-binlog=1            #每条自动更新,安全性高,默认是0 log-error = /var/log/mysqld.logread_only = 1

mysql-master02:

[mysqld] server-id=2              #每台设置不同 log-bin=mysql-bin [mysqld_safe]auto_increment_increment=2  #字段一次递增多少auto_increment_offset=2    #自增字段的起始值,master02需设置为2replicate-do-db=all        #同步的数据库,多个用逗号隔开log-slave_updates       #当一个主故障,另一个立即接管sync-binlog=1            #每条自动更新,安全性高,默认是0log-error = /var/log/mysqld.logread_only = 1


2、在mysql-master01上创建用于同步的账户repl,密码为123456,并查询master状态,记下file名称和posttion数值

mysql> GRANT REPLICATION SLAVE ON *.* to 'repl'@'%' identified by '123456';

mysql> show master status;


3、在mysql-master02上登录mysql,执行以下语句开启从服务器

mysql> change master to master_host='192.168.10.81',master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=318;

mysql> start slave;

mysql> show slave status\G



4、然后在mysql-master02上也创建用于同步的账户repl,密码为123456,并查询master状态,记下file名称和posttion数值

mysql> GRANT REPLICATION SLAVE ON *.* to 'repl'@'%' identified by '123456';

mysql> show master status;


5、在mysql-master01上登录mysql执行以下语句开启从服务器,注意这里master_host要填写mysql-master02的IP

mysql> change master to master_host='192.168.10.82',master_user='repl',master_password='123456',master_log_file='mysql-bin.000006',master_log_pos=318;

mysql> start slave;

mysql> show slave status\G


6、这样两台master的互为主从就配置好了,下面我们来测试一下,先做mysql-master01上执行以下语句创建一个数据库、一个表并插入一行数据

mysql> create database names_test;

mysql> use names_test;

mysql> create table names(id int(5),name char(15));

mysql> insert into names values (01,'jiangjianlong');

mysql> select * from names;

7、然后到mysql-master02上查询一下,发现已经同步完成了,说明mysql-master02作为mysql-master01的从库复制正常

8、在mysql-master02上也创建一个数据库、一个表并插入一行数据

mysql> create database blogs_test;

mysql> use blogs_test;

mysql> create table blogs(id int(5),name char(35));

mysql> insert into blogs values (01,'jiangjianlong.blog.51cto.com');

mysql> select * from names;

9、在mysql-master01上查询一下,发现数据也已经同步过来,说明mysql-master01作为mysql-master02的从库也是复制正常


四、配置两台slave作为master01的从库

1、mysql-slave01和mysql-slave02分别使用以下my.cnf

mysql-slave01:

[mysqld]server-id=3              #每台设置不同log-bin=mysql-bin [mysqld_safe]replicate-do-db=all         log-error = /var/log/mysqld.logread_only = 1

mysql-slave02:

[mysqld]server-id=4             #每台设置不同log-bin=mysql-bin [mysqld_safe]replicate-do-db=all         log-error = /var/log/mysqld.logread_only = 1

2、根据在mysql-master01上执行show master status查出来的结果,在mysql-slave01和mysql-slave02上分别执行以下sql语句,开启从服务器:

mysql> change master to master_host='192.168.10.81',master_user='repl',master_password='123456',master_log_file='mysql-bin.000004',master_log_pos=120;

mysql> start slave;

mysql> show slave status\G


五、安装MMM要求的Perl模块

1、MMM对所有MySQL节点所要求的Perl模块如下:

2、以下以mysql-master01为例进行perl模块的安装,另外3台MySQL服务器同理。首先查看一下这些perl模块还有哪些没装:

perldoc -l Algorithm::Diff DBI DBD::mysql File::Basename File::stat Log::Dispatch Log::Log4perl Mail::Send Net::ARP Proc::Daemon Time::HiRes

3、部分缺失的perl模块在Redhat6.5的介质中有,可以通过本地yum源的方式安装

[root@mysql-master01 ~]# yum install perl-DBI perl-DBD-mysql perl-MailTools perl-Time-HiRes perl-CPAN -y

4、使用以下命令再查看一下安装结果

perldoc -l Algorithm::Diff DBI DBD::mysql File::Basename File::stat Log::Dispatch Log::Log4perl Mail::Send Net::ARP Proc::Daemon Time::HiRes


5、剩下的几个perl模块安装起来稍微麻烦一点,可以使用源码包编译安装,也可以使用cpan在线自动下载安装,并能处理各模块间的依赖关系。我一开始是尝试去下载源码包后手动进行编译安装,然而我在编译到Log::Dispatch时我直接放弃这种方式了,因为它依赖于很多个其它的perl模块,而这些模块可能又依赖于别的多个模块!如下图:

6、所以我决定使用cpan在线自动安装的方式,但需要服务器能连外网。由于使用cpan安装Algorithm::Diff时会告警提示YAML没有安装,因此我先使用cpan安装YAML,而安装YAML时会把它所依赖的Algorithm::Diff给装上

7、接着执行cpan Log::Dispatch安装Log::Dispatch,没想到在自动下载安装了50多个依赖模块后还是报错提示有多个依赖的模块缺失,如下图:

8、解决办法:依次使用cpan安装上图所示的缺少的模块,然后再执行cpan Log::Dispatch就能成功安装上,如果cpan安装Params::ValidationCompiler时报错,就单独下载这个模块的源码包进行编译安装

9、执行cpan Log::Log4perl安装Log::Log4perl模块、执行cpan Net::ARP安装Net::ARP模块、执行cpan Proc::Daemon安装Proc::Daemon模块

10、再来查看下所需perl模块的安装结果,这下已经全部都装好了

11、monitor服务器也对perl模块有要求,如下图:

12、同样是使用cpan安装这些模块,在此不再赘述。4台mysql服务器和monitor服务器的perl模块都安装完成后,我们就可以来安装配置MMM了


六、MySQL-MMM安装配置

1、MMM对MySQL用户的要求如下:

2、由于本文未使用到MMM tools,因此只需创建前3个用户,由于前面已经做好了主从同步,因此只需要在mysql-master01上创建即可同步到另外3台MySQL服务器

GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'192.168.10.%' IDENTIFIED BY 'monitor';

GRANT SUPER,REPLICATION CLIENT,PROCESS ON *.* TO 'mmm_agent'@'192.168.10.%' IDENTIFIED BY'agent';

GRANT REPLICATION SLAVE ON *.* TO 'mmm_repl'@'192.168.10.%' IDENTIFIED BY'repl';

注:其实用户mmm_repl可以不用建,因为前面我们配置主从同步时已经建了一个repl用户可供使用

3、使用以下语句检查另外3台MySQL服务器是否已同步了这3个用户,可以看到都已经有了

select user,host from mysql.user where user in ('mmm_monitor','mmm_agent','mmm_repl');

4、在4台MySQL服务器和monitor服务器上编译安装MMM,下面以mysql-master01为例

[root@mysql-master01 ~]# tar -zxf mysql-mmm-2.2.1.tar.gz -C /usr/

[root@mysql-master01 ~]# cd /usr/mysql-mmm-2.2.1/

[root@mysql-master01 mysql-mmm-2.2.1]# make install

5、安装完成后,所有的配置文件都放到了/etc/mysql-mmm/下面。monitor服务器和MySQL服务器上都要包含一个共同的文件mmm_common.conf,内容如下:

[root@mysql-master01 mysql-mmm-2.2.1]# cat /etc/mysql-mmm/mmm_common.confactive_master_role        writer  cluster_interface                eth0 pid_path                                /var/run/mmm_agentd.pidbin_path                                /usr/lib/mysql-mmm/     replication_user        mmm_repl    replication_password    repl agent_user                            mmm_agentagent_password                        agent ip                                          192.168.10.81mode                                        masterpeer                                        mysql-master02 ip                                          192.168.10.82mode                                        masterpeer                                        mysql-master01 ip                                          192.168.10.83mode                                        slave         ip                                   192.168.10.84        mode                                 slave hosts                                        mysql-master01, mysql-master02ips                                          192.168.10.91mode                                        exclusive hosts                                        mysql-slave01, mysql-slave02ips                                          192.168.10.93, 192.168.10.94mode                                        balanced[root@mysql-master01 mysql-mmm-2.2.1]#

6、在mysql-master01上编辑好该文件后,通过scp传输到另外4台服务器


7、4台MySQL服务器还有一个mmm_agent.conf文件需要修改主机名

8、在4台MySQL服务器的 /etc/init.d/mysql-mmm-agent的脚本文件的#!/bin/sh下面,加入如下内容

source /root/.bash_profile,下面以mysql-master01为例

9、分别将4台MySQL服务器的mmm_agent启动脚本添加成系统服务并设置为自启动,下面以mysql-master01为例

#chkconfig --add mysql-mmm-agent

#chkconfig mysql-mmm-agent on

10、分别将4台MySQL服务器的mmm_agent启动,如果前面的Perl模块没有装好,可能会报错启动不了

/etc/init.d/mysql-mmm-agent start或service mysql-mmm-agent start


11、配置monitor服务器上的mmm_mon.conf文件

[root@mysql-monitor mysql-mmm]# cat/etc/mysql-mmm/mmm_mon.conf includemmm_common.conf         ip                  127.0.0.1        pid_path               /var/run/mmm_mond.pid        bin_path               /usr/lib/mysql-mmm/        status_path              /var/lib/misc/mmm_mond.status        ping_ips               192.168.10.81,192.168.10.82,192.168.10.83,192.168.10.84         monitor_user                  mmm_monitor        monitor_password                monitor        check_period   5       trap_period   10       timeout       3       max_backlog   86400 debug 0


12、在monitor服务器的 /etc/init.d/mysql-mmm-monitor的脚本文件的#!/bin/sh下面,加入如下内容

source /root/.bash_profile

13、将mysql-mmm-monitor添加成系统服务并设置为自启动

#chkconfig --add mysql-mmm-monitor

#chkconfigmysql-mmm-monitor on

14、启动monitor服务器的mysql-mmm-monitor服务

15、在monitor服务器执行命令列出客户端状态,发现都是AWAITING状态

16、在monitor服务器执行命令mmm_control set_online mysql-master01,将mysql-master01上线,过一会再看它就变成online状态了

17、这时观察mysql-master01的IP发现已经成功添加了Write VIP

18、依次将mysql-master02和mysql-slave01以及mysql-slave02设置为online,查看slave的IP也发现Read VIP也加上了。MMM到此已配置完成,下面将进行高可用测试


七、MySQL-MMM主库高可用测试

1、将mysql-master01的mysql服务停止,模拟主库宕机,再查看IP会发现Write VIP已被自动移除

2、观察monitor服务器上的日志可以发现MMM检测到mysql-maste01故障并将Write VIP切换到了mysql-master02上

3、查看mysql-master02的IP,发现Write VIP确实已添加上了

4、这时两台slave之前配置的主库已经宕机并且主库已切换,那它们是否会自动将Master Host也切换为mysql-master02呢?查看下它们的slave状态,发现已自动切换

5、在monitor服务器上查看下客户端的状态,mysql-master01确实已离线,并且是能Ping通而mysql连接失败

6、再次启动master01的mysql服务,并设置为online,可以看到Write VIP并不会回切(除非当前的主库再次宕机)

7、观察到monitor服务器的日志如下:

8、再检查下客户端,已恢复正常


八、MySQL-MMM从库高可用测试

1、将mysql-slave01的mysql服务停止,模拟从库宕机,再查看IP会发现其上的Read VIP已被自动移除


2、观察到monitor服务器上的日志发现mysql-slave01的Read VIP已被切换到mysql-slave02上:

3、在monitor服务器上查看客户端状态,发现mysql-slave02确实绑定了2个Read VIP

4、检查mysql-slave02的IP,确实如此

5、将mysql-slave01的mysql服务恢复启动,并在monitor服务器将其设置为online,可以看到切换回去的Read VIP并不是最开始的那个VIP,Read VIP并非固定不变

6、观察monitor服务器的日志内容如下:

7、两个slave的IP信息现在如下:

至此,MySQL-MMM读写分离的高可用架构经简单测试均OK!以下是小结:

1、若master01主节点宕机,由master02备选主节点接管写角色,slave1,slave2指向新master2主库进行复制,slave01,slave02会自动change master到master02。

2、若master01主节点宕机,而master02同步又落后于master01时就变成了主可写状态,则这时的数据主无法保证一致性。

3、若master02,slave01,slave02延迟于master01主,而这个时master01宕机,slave01,slave02将会等待数据追上master01后,再重新指向新的主master02进行复制操作,这时的数据也无法保证同步的一致性。

4、对外提供读写的虚拟IP是由monitor程序控制。如果monitor没有启动那么db服务器不会被分配虚拟ip,但是如果已经分配好了虚拟ip,当monitor程序关闭了,则原先分配的虚拟ip不会关闭,只要不重启网络,外部程序还可以连接访问,这样能对monitor的可靠性要求降低一些,但是如果这时其中的某一个db服务器故障了就无法处理切换。因为agent程序受monitor程序的控制,处理主库切换、从库切换等操作。如果monitor进程关闭了那么agent进程就起不到什么作用,它本身不能处理故障。

5、monitor程序负责监控db服务器的状态,包括Mysql数据库、服务器是否运行、复制线程是否正常、主从延时等,以及控制agent程序处理故障。因此monitor是这个高可用架构中的核心角色,同时也是单点故障的风险点,应该能通过keepalived等方式将monitor也做成高可用,等以后有时间我再进行测试。

6、monitor监控端的配置文件参数"auto_set_online"可以让从故障中恢复的节点自动online,待有空测试下。群集中节点服务器的状态有三种分别是:HARD_OFFLINE→AWAITING_RECOVERY→online

7、默认monitor会控制mmm_agent会将writer db服务器read_only修改为OFF,其它的db服务器read_only修改为ON,所以为了严谨可以在所有的服务器的my.cnf文件中加入read_only=1,由monitor控制writer和read,root用户和复制用户不受read_only参数的影响。

本文出自江健龙的技术博客,转载请注明出处 https://blog.51cto.com/jiangjianlong/2073744

服务 服务器 模块 配置 同步 数据 状态 文件 切换 故障 用户 程序 测试 主从 节点 架构 多个 数据库 语句 处理 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网高科技 互联网科技公司税收优惠 互联网科技金融 中国 科技 互联网 善班互联网科技有限公司 长亮科技 互联网金融 佩信高科技互联网 中国最先进互联网科技公司 阿大互联网科技有限公司 哈尔滨屹滨互联网科技有限公司 开一家科技互联网公司需要多少钱 深圳市罗太互联网科技有限公司 工业互联网等科技实现智能化赋能 爱医互联网络科技 半导体行业属于互联网高科技类吗 工业互联网科技创业 中国新注册互联网科技 互联网科技机房 玉溪新华互联网科技怎么选 上海旺乐尼互联网科技有限公司 互联网科技公司起名 互联网公司 科技公司 易互联网科技有限公司 猫创互联网科技 哈尔滨新华互联网科技学院 智腾互联网科技有限公司 科技类公司包括互联网吗 内蒙古九一互联网科技 群盈汇互联网科技有限公司 工业互联网展湾科技股份有限公司
0