前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MYSQL高可用架构MMM实现

MYSQL高可用架构MMM实现

作者头像
全栈工程师修炼指南
发布2022-09-28 21:32:03
9350
发布2022-09-28 21:32:03
举报

[TOC]

前言介绍

描述: MySQL的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架构图

WeiyiGeek.MySQL-MMM架构图
WeiyiGeek.MySQL-MMM架构图

WeiyiGeek.MySQL-MMM架构图

mysql-mmm运行机制 监听端口说明:

  • MMM-MONITOR: 9988 端口
  • MMMM-MONITOR: 9989 端口
WeiyiGeek.MMM运行机制
WeiyiGeek.MMM运行机制

WeiyiGeek.MMM运行机制

MMM环境安装

(1)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用户

(2)安装环境 分为真实IP和虚拟IP(VIP),还行进行以下配置

代码语言:javascript
复制
#以及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

#其他必须配置
1.关闭iptables (测试阶段需要)
2.同步时间
3.配置yum和epel源
WeiyiGeek.
WeiyiGeek.

WeiyiGeek.

(3)安装MySQL并配置 Step1.安装MySQL的文章请参考我博客里面说的比较详细了; Step2.编辑各个机器的MySQL配置文件/etc/my.cnf;

master-db1

代码语言:javascript
复制
[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

代码语言:javascript
复制
[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

代码语言:javascript
复制
[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

代码语言:javascript
复制
[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

Step3.重启上面四台mysql服务的机器: service mysqld restart Step4.在master-db1上创建mmm架构中需要的用户和权限

代码语言:javascript
复制
[root@master-db1 ~]# mysql
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';  /** 管理用户 **/

mysql> GRANT SUPER,REPLICATION CLIENT,PROCESS ON *.* TO 'mmm_agent'@'192.168.1.%' IDENTIFIED BY '123456';  /** 客户端用户 **/

mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'192.168.1.%' IDENTIFIED BY '123456';  /** 同步用户 **/


#查看二进制日志位置
mysql> FLUSH TABLES WITH READ LOCK;  #刷线bin-log表并且并索表
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      796 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

#重启shell进行数据库备份
mysqldump --all-databases > /tmp/database-backup.sql

mysql> UNLOCK TABLES;  #回到刚才mysql进程,进行解锁:
Query OK, 0 rows affected (0.05 sec)

Step5.将database-backup.sql文件复制到其他db节点:

代码语言:javascript
复制
[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
`

Step6.master-db,slave-db1,slave-db2三台主机导入sql文件并刷新权限:

代码语言:javascript
复制
mysql < /tmp/database-backup.sql
mysql -e "FLUSH PRIVILEGES;"

(4)设置MySQL主-从和主-主配置 Step1.设置MySQL主-从和主-主配置:

代码语言:javascript
复制
[root@master-db2 ~]# 
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  #主MySQL IP
                  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

#查看master-db2的master日志位置:
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |   636231 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

Step2.在master-db1上操作将master-db2设置为主 (即互为主从)

代码语言:javascript
复制
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;
mysql> start slave;
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

代码语言:javascript
复制
useradd -s /sbin/nologin mmmd #所有机器

2.查看mmm版本:

代码语言:javascript
复制
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上安装:

代码语言:javascript
复制
[root@mmm-monitor ~]# yum -y install mysql-mmm-monitor

4.在四台mysql服务器上安装mmm的客户端:

代码语言:javascript
复制
yum -y install mysql-mmm-agent

5.编写配置文件,五台主机必须一致:

代码语言:javascript
复制
[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.复制到其他服务器上

代码语言:javascript
复制
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

代码语言:javascript
复制
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 #只需要修改master-db1这里是哪台就改成哪台这里只给出master-db1的

8.配置mmm-monitor上的mmm_mon.conf(即IP:192.168.1.11)

代码语言:javascript
复制
[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.启动服务:

代码语言:javascript
复制
#在Master1启动mmm-monitor
[root@mmm-monitor ~]# chkconfig mysql-mmm-monitor on
[root@mmm-monitor ~]# service mysql-mmm-monitor start

#在所有mysql服务器上启动mmm-agent
chkconfig mysql-mmm-agent on
service mysql-mmm-agent start

高可用性测试

描述: 服务器读写采有VIP地址进行读写,出现故障时VIP会漂移到其它节点,由其它节点提供服务。

WeiyiGeek.
WeiyiGeek.

WeiyiGeek.

1.首先查看整个集群的状态,可以看到整个集群状态正常

代码语言:javascript
复制
[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宕机

代码语言:javascript
复制
[root@master-db1 ~]# service mysqld stop
Shutting down MySQL...                                     [确定]

3.mmm-monitor上查看集群状态

代码语言:javascript
复制
[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主机上,同时查看slave-db1和slave-db2主从状态

代码语言:javascript
复制
#slave-db1/slave-db2 都是一样
mysql> show slave status\G   
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.12  #切换了热备主 MASTER
                  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

4.启动master-db1的mysql服务主master节点将被恢复,但是此时可以看到主库启动不会接管主,直到现有的主再次宕机。

代码语言:javascript
复制
[root@master-db1 ~]# service mysqld start
Starting MySQL......                                       [确定]

再次查看集群状态(大概等待一分钟左右)

代码语言:javascript
复制
[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)

再次slave-db1和slave-db2主从状态

代码语言:javascript
复制
mysql> show slave status\G   #slave-db1/2
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.12  #任然是master-db2 不会改变
                  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 总结

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架构总结

代码语言:javascript
复制
(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进行多线程从复制,提高复制的性能。

参考文档:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言介绍
  • MMM环境安装
  • 安装MMM
  • 高可用性测试
  • MySQL-mmm 总结
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档