MySQL高可用集群之MMM

一、MMM简介

MMM即Multi-Master Replication Manager for MySQL(mysql多主复制管理器),基于perl实现,关于mysql主主复制配置的监控、故障转移和管理的一套可伸缩的脚本套件(在任何时候只有一个节点可以被写入),MMM也能对从服务器进行读负载均衡,所以可以用它来在一组用于复制的服务器启动虚拟IP,除此之外,它还有实现数据备份、节点之间重新同步功能的脚本。MySQL本身没有提供replication failover的解决方案,通过MMM方案能实现服务器的故障转移,从而实现mysql的高可用。MMM不仅能提供浮动IP的功能,如果当前的主服务器挂掉后,会将你后端的从服务器自动转向新的主服务器进行同步复制,不用手工更改同步配置。这个方案是目前比较成熟的解决方案。详情请看官网:http://mysql-mmm.org

优点:

  • 高可用性,扩展性好,出现故障自动切换。
  • 对于主主同步,在同一时间只提供一台数据库写操作,保证的数据的一致性。
  • 当主服务器挂掉以后,另一个主立即接管,其他的从服务器能自动切换,不用人工干预。

缺点:

  • monitor节点是单点,不过这个也可以结合keepalived或者haertbeat做成高可用;
  • 至少三个节点,对主机的数量有要求,需要实现读写分离,还需要在前端编写读写分离程序。
  • 在读写非常繁忙的业务系统下表现不是很稳定,可能会出现复制延时、切换失效等问题。

MMM方案并不太适应于对数据安全性要求很高,并且读、写繁忙的环境中。 适用场景: MMM的适用场景为数据库访问量大,并且能实现读写分离的场景。

MMM主要功能由下面三个脚本提供:

1. mmm_mond:负责所有的监控工作的监控守护进程,决定节点的移除(mmm_mond进程定时心跳检测,失败则将write ip浮动到另外一台master)等等
2. mmm_agentd:运行在mysql服务器上的代理守护进程,通过简单远程服务集提供给监控节点
3. mmm_control:通过命令行管理mmm_mond进程 在整个监管过程中,需要在mysql中添加相关授权用户,授权的用户包括一个mmm_monitor用户和一个mmm_agent用户,如果想使用mmm的备份工具则还要添加一个mmm_tools用户。

二、部署实施

环境:

  • 操作系统:Cent OS 7.3
  • 数据库系统:mysql5.7
  • 关闭selinux,配置ntp同步时间
    # IT明星不是梦 # MySQL高可用集群之MMM_第1张图片
主机 操作系统 IP地址 Write VIP Read VIP
mysql-master1 CentOS 7.3 192.168.1.1 192.168.1.100 NULL
mysql-master2 CentOS 7.3 192.168.1.8 NULL 192.168.1.80
mysql-slave1 CentOS 7.3 192.168.1.9 NULL 192.168.1.90
mysql-slave2 CentOS 7.3 192.168.1.12 NULL 192.168.1.120
monitor CentOS 7.3 192.168.1.3 NULL NULL

每台mysql服务启动,以及其它主机:关闭防火墙、关闭selinux

systemctl start mysqld
systemctl stop firewalld
setenforce 0        //临时关闭,永久关闭需要在/etc/selinux/config文件中设置

1、在所有主机上配置为/etc/hosts文件,添加域名解析(5台主机都需要做)

[root@mysql-master1 ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.1     mysql-master1
192.168.1.8     mysql-master2
192.168.1.9     mysql-slave1
192.168.1.12    mysql-slave2
192.168.1.3     monitor 

# IT明星不是梦 # MySQL高可用集群之MMM_第2张图片
将配置文件传到其他主机

[root@mysql-master1 ~]#for host in mysql-master2 mysql-slave1 mysql-slave2 monitor ; do scp /etc/hosts $host:/etc/hosts ; done

将mysql命令传到monitor

[root@mysql-master1 ~]# scp /usr/local/mysql/bin/mysql 192.168.1.3:/usr/local/sbin

在所有主机上安装依赖包

# yum -y install perl-* libart_lgpl.x86_64 rrdtool.x86_64 rrdtool-perl.x86_64
PS:使用centos7在线yum源安装

2、安装Perl的相关库(5台主机都需要做)

Perl的CPAN镜像使用管理的文章,安装perl下的很多模块文件时,比较快捷的方法是使用cpan工具。默认cpan shell使用的是cpan.org的源,在国内使用的话速度会非常的慢。如果更换为国内的如阿里或网易等公司的源的话,速度会明显提高。修改方法如下:

1)执行cpan命令确认存在该命令,如果没有使用yum -y install perl-CPAN或手动安装这个模块

# yum -y install perl-CPAN
# cpan      //一路回车

查看当前源配置

cpan[1]> o conf     

# IT明星不是梦 # MySQL高可用集群之MMM_第3张图片
增加源或移出源并提交

cpan[2]> o conf urllist push http://mirrors.aliyun.com/CPAN/
cpan[3]> o conf urllist ftp://mirrors.sohu.com/CPAN/ http://mirrors.163.com/cpan/

# IT明星不是梦 # MySQL高可用集群之MMM
查看源配置

cpan[4]> o conf

# IT明星不是梦 # MySQL高可用集群之MMM_第4张图片
例:移出一个源可以使用pop函数,如下(可以不做,知道方法就行)

cpan[5]>  o conf urllist pop http://mirrors.163.com/cpan/
cpan[6]> o conf

# IT明星不是梦 # MySQL高可用集群之MMM_第5张图片
查看当前源信息,并提交

cpan[7]> o conf

# IT明星不是梦 # MySQL高可用集群之MMM_第6张图片

cpan[8]> o conf commit
cpan[9]> exit

安装

[root@mysql-master1 ~]# cpan -i Algorithm::Diff Class::Singleton DBI DBD::mysql Log::Dispatch Log::Log4perl Mail::Send Net::Ping Proc::Daemon Time::HiRes Params::Validate Net::ARP     //过程比较慢

# IT明星不是梦 # MySQL高可用集群之MMM_第7张图片
配置NTP时间同步(在公司可以联通外网的话,可以直接上百度搜索国内常用的NTP服务器,也可以自己搭建一个NTP服务器)

[root@mysql-master1 ~]# vim /etc/chrony.conf

# IT明星不是梦 # MySQL高可用集群之MMM_第8张图片
在其他四个节点中的配置文件指向mysql-master1的IP地址,就可以和mysql-master1进行同步。
# IT明星不是梦 # MySQL高可用集群之MMM_第9张图片
配置完成后,重新启动chronyd服务,配置开机自启

# systemctl restart chronyd
# systemctl enable chronyd

可以使用timedatectl / timedatectl status(效果相同)来查看时间

[root@mysql-master1 ~]# timedatectl status

# IT明星不是梦 # MySQL高可用集群之MMM_第10张图片

3、在mysql-master1、mysql-master2、mysql-slave1、mysql-slave2主机上安装mysql5.7(已经安装完成)和配置主从复制。 mysql-master1和mysql-master2互为主从,mysql-slave1、mysql-slave2为master1的从。在每个mysql的配置文件/etc/my.cnf中加入以下内容, 注意server-id不能重复。

mysql-master1主机:

[root@mysql-master1 ~]# vim /etc/my.cnf
log-bin=mysql-bin   //二进制日志
binlog_format=mixed     //binlog日志格式,mysql默认采用statement,建议使用mixed
server-id=1
relay-log=relay-bin     //中继日志,存储所有主库TP过来的binlog事件
relay-log-index=slave-relay-bin.index
log-slave-updates=1     //将主的二进制日志导入中继日志的同时,也将操作写入二进制日志,切换到主,二进制日志也是相同的,保证数据完整性
auto-increment-increment=2
auto-increment-offset=1

MySQL复制主要有三种方式:

  • 基于SQL语句的复制(statement-based replication, SBR)
  • 基于行的复制(row-based replication, RBR)
  • 混合模式复制(mixed-based replication, MBR)

对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED。
1. STATEMENT模式(SBR)
每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
2. ROW模式(RBR)
不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table的时候会让日志暴涨。
3. MIXED模式(MBR)
以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。

mysql-master2主机:

log-bin=mysql-bin
binlog_format=mixed
server-id=2
relay-log=relay-bin
relay-log-index=slave-relay-bin.index
log-slave-updates=1     //将主的二进制日志导入中继日志的同时,也将操作写入二进制日志,切换到主,二进制日志也是相同的,保证数据完整性
auto-increment-increment=2
auto-increment-offset=2

mysql-slave1主机:

server-id=3
relay-log=relay-bin
relay-log-index=slave-relay-bin.index
read_only=1

mysql-slave2主机:

server-id=4
relay-log=relay-bin
relay-log-index=slave-relay-bin.index
read_only=1

在完成了对my.cnf的修改后,重新启动mysql服务

# systemctl restart mysqld 

4台数据库主机若要开启防火墙,要么关闭防火墙或者创建访问规则

    防火墙规则:
        firewall-cmd --permanent --add-port=3306/tcp
        firewall-cmd --reload
    或关闭:
        systemctl stop firewalld


主从配置(mysql-master1和mysql-master2配置成主主,mysql-slave1和mysql-slave2配置成mysql-master1的从):
在mysql-master1上授权:

[root@mysql-master1 ~]# mysql -uroot -p123.com
mysql> grant replication slave on *.* to rep@'192.168.1.%' identified by '123.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)

在mysql-master2上授权:

[root@mysql-master2 ~]# mysql -uroot -p123.com
mysql> grant replication slave on *.* to rep@'192.168.1.%' identified by '123.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)

把mysql-master2、mysql-slave1和mysql-slave2配置成mysql-master1的从库:
在mysql-master1上执行命令,获取binlog文件和Position点

mysql> show master status;

# IT明星不是梦 # MySQL高可用集群之MMM_第11张图片
在mysql-master2、mysql-slave1和mysql-slave2执行:

mysql> change master to master_host='192.168.1.1',master_port=3306,master_user='rep',master_password='123.com',master_log_file='mysql-bin.000001',master_log_pos=451;
mysql> start slave;

PS:如果是克隆的主机,那么会出现UUID重复的错误,需要到/usr/local/mysql/data/auto.cnf文件中将UUID删除并重启服务即可

验证主从复制:

mysql> show slave status\G

# IT明星不是梦 # MySQL高可用集群之MMM_第12张图片
Slave_IO_Running和Slave_SQL_Running都为yes,那么主从就已经配置OK了
把mysql-master1配置成mysql-master2的从库:
在mysql-master2上执行命令,获取binlog文件和Position点

mysql> show master status;

# IT明星不是梦 # MySQL高可用集群之MMM_第13张图片
在mysql-master1上执行:

mysql> change master to master_host='192.168.1.8',master_port=3306,master_user='rep',master_password='123.com',master_log_file='mysql-bin.000002',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

验证主从复制:

mysql-master1主机:
mysql> show slave status\G

# IT明星不是梦 # MySQL高可用集群之MMM_第14张图片
Slave_IO_Running和Slave_SQL_Running都为yes,那么主从就已经配置OK了

4、mysql-mmm配置:

在mysql-master1节点上创建用户,因为是主,会同步到其他DB:
创建代理账号:

mysql> grant super,replication client,process on *.* to 'mmm_agent'@'192.168.1.%' identified by '123.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)

创建监控账号:

mysql> grant replication client on *.* to 'mmm_monitor'@'192.168.1.%' identified by '123.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)

查看:

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

# IT明星不是梦 # MySQL高可用集群之MMM_第15张图片
检查mysql-master2和mysql-slave1、mysql-slave2三台db上是否都存在监控和代理账号:

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

或者使用:

mysql> show grants for 'mmm_agent'@'192.168.1.%';
mysql> show grants for 'mmm_monitor'@'192.168.1.%';

# IT明星不是梦 # MySQL高可用集群之MMM_第16张图片

  • mmm_monitor用户:MMM监控用于对mysql服务器进程健康检查
  • mmm_agent用户:MMM代理用来更改只读模式,复制的主服务器等

5、mysql-mmm安装

在monitor主机(192.168.1.3) 上安装监控程序

[root@monitor ~]# cd /usr/local/
[root@monitor local]# wget http://pkgs.fedoraproject.org/repo/pkgs/mysql-mmm/mysql-mmm-2.2.1.tar.gz/f5f8b48bdf89251d3183328f0249461e/mysql-mmm-2.2.1.tar.gz
[root@monitor local]# tar -zxf mysql-mmm-2.2.1.tar.gz 
[root@monitor local]# cd mysql-mmm-2.2.1/
[root@monitor mysql-mmm-2.2.1]# make install

在4台DB安装代理:

[root@mysql-master1 ~]# cd /usr/local/
[root@mysql-master1 local]# wget http://pkgs.fedoraproject.org/repo/pkgs/mysql-mmm/mysql-mmm-2.2.1.tar.gz/f5f8b48bdf89251d3183328f0249461e/mysql-mmm-2.2.1.tar.gz
[root@mysql-master1 local]# tar -zxf mysql-mmm-2.2.1.tar.gz 
[root@mysql-master1 local]#  cd mysql-mmm-2.2.1/
[root@mysql-master1 mysql-mmm-2.2.1]# make install

6、配置MMM

编写配置文件,五台主机必须一致:
完成安装后,所有的配置文件都放到了/etc/mysql-mmm/下面。
管理服务器和数据库服务器上都要包含一个共同的文件mmm_common.conf,内容如下:

active_master_role      writer      //积极的master角色的标示,所有的db服务器要开启read_only参数,对于writer服务器监控代理会自动将read_only属性关闭。


        cluster_interface               ens33   //群集的网络接口

        pid_path                                /var/run/mmm_agentd.pid //pid路径
        bin_path                                /usr/lib/mysql-mmm/ //可执行文件路径

    replication_user        rep     //复制用户
    replication_password    123.com     //复制用户密码

        agent_user                              mmm_agent   //代理用户
        agent_password                  123.com     //代理用户密码


    //mysql-master1的主机名
        ip                                              192.168.1.1 //mysql-master1的IP地址
        mode                                    master      //角色属性,master代表是主
        peer                                    mysql-master2   //与mysql-master1对等的服务器的host名,也就是mysql-master2的服务器host名


    //和mysql-master1的概念一样
        ip                                              192.168.1.8
        mode                                    master
        peer                                    mysql-master1


 //从库的host名,如果存在多个从库可以重复一样的配置
        ip                                              192.168.1.9 //从的ip
        mode                                    slave   // slave的角色属性代表当前host是从


 和mysql-slave1的概念一样
        ip                                              192.168.1.12
        mode                                    slave


   // writer角色配置
        hosts                                   mysql-master1, mysql-master2    //能进行写操作的服务器的host名,如果不想切换写操作这里可以只配置master,这样也可以避免因为网络延时而进行write的切换,但是一旦master出现故障那么当前的MMM就没有writer了只有对外的read操作。
        ips                                             192.168.1.100   //对外提供的写操作的虚拟IP
        mode                                    exclusive   // exclusive代表只允许存在一个主,也就是只能提供一个写的IP


   // read角色配置
        hosts                                   mysql-master2, mysql-slave1, mysql-slave2   //对外提供读操作的服务器的host名,当然这里也可以把master加进来
        ips                                             192.168.1.80, 192.168.1.90, 192.168.1.120       //对外提供读操作的虚拟ip,这三个ip和host不是一一对应的,并且ips也hosts的数目也可以不相同,如果这样配置的话其中一个hosts会分配两个ip
        mode                                    balanced    // balanced代表负载均衡

同时将这个文件拷贝到其它的服务器,配置不变

[root@mysql-master1 ~]# for host in mysql-master2 mysql-slave1 mysql-slave2 monitor ; do scp /etc/mysql-mmm/mmm_common.conf $host:/etc/mysql-mmm/ ; done 

# IT明星不是梦 # MySQL高可用集群之MMM_第17张图片

7、代理文件配置(四台DB)

编辑 4台mysql节点机上的/etc/mysql-mmm/mmm_agent.conf 在数据库服务器上,还有一个mmm_agent.conf需要修改,其内容是:

# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this mysql-master1

PS:这个配置只配置db服务器,监控服务器不需要配置,this后面的host名改成当前服务器的主机名。

启动代理进程 (四台DB)
在/etc/init.d/mysql-mmm-agent的脚本文件的#!/bin/sh下面,加入如下内容

# vim /etc/init.d/mysql-mmm-agent
source /root/.bash_profile

# IT明星不是梦 # MySQL高可用集群之MMM_第18张图片
添加成系统服务并设置为自启动(四台DB)

# chkconfig --add mysql-mmm-agent
# chkconfig mysql-mmm-agent on
# /etc/init.d/mysql-mmm-agent start
Daemon bin: '/usr/sbin/mmm_agentd'
Daemon pid: '/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Ok

PS:添加source /root/.bash_profile目的是为了mysql-mmm-agent服务能启机自启。 自动启动和手动启动的唯一区别,就是激活一个console 。那么说明在作为服务启动的时候,可能是由于缺少环境变量 服务启动失败,报错信息如下:

Daemon bin: '/usr/sbin/mmm_agentd'
Daemon pid: '/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Can't locate Proc/Daemon.pm in @INC (@INC contains:
/usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at
/usr/sbin/mmm_agentd line 7.
BEGIN failed--compilation aborted at /usr/sbin/mmm_agentd line 7.
failed

解决方法:

# cpan Proc::Daemon   //安装perl库可能有的库没有安装上,有的可以看集群状态来查看出缺少哪个perl库
# cpan Log::Log4perl    
# /etc/init.d/mysql-mmm-agent start
Daemon bin: '/usr/sbin/mmm_agentd'
Daemon pid: '/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Ok

查看端口是否启动(四台DB)

# ss -anplt |grep mmm_agent
LISTEN     0      10     192.168.1.1:9989                     *:*                   users:(("mmm_agentd",pid=3150,fd=3))

关于代理的防火墙配置:

    配置策略:
        firewall-cmd --permanent --add-port=9989/tcp
        firewall-cmd --reload
    或关闭:
        systemctl stop firewalld

编辑 monitor主机上的/etc/mysql-mmm/mmm_mon.conf

[root@monitor ~]# vim /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf


        ip                                              127.0.0.1   //为了安全性,设置只在本机监听,mmm_mond默认监听9988
        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.1.1, 192.168.1.8, 192.168.1.9, 192.168.1.12 //用于测试网络可用性 IP 地址列表,只要其中有一个地址 ping 通,就代表网络正常,这里不要写入本机地址
        auto_set_online                         0   //设置自动online的时间,默认是超过60s就将它设置为online,默认是60s,这里将其设为0就是立即online




        check_period    5   //描述:检查周期默认为5s 默认值:5s
        trap_period     10  //描述:一个节点被检测不成功的时间持续trap_period秒,就慎重的认为这个节点失败了。默认值:10s
        timeout         2   //描述:检查超时的时间 默认值:2s
        restart_after   10000   //描述:在完成restart_after次检查后,重启checker进程默认值:10000
        max_backlog     86400   //描述:记录检查rep_backlog日志的最大次数默认值:60



        monitor_user                    mmm_monitor     //监控db服务器的用户
        monitor_password                123.com     //监控db服务器的密码


debug 0     debug 0正常模式,1为debug模式

启动监控进程: 在 /etc/init.d/mysql-mmm-agent的脚本文件的#!/bin/sh下面,加入如下内容

[root@monitor ~]# vim /etc/init.d/mysql-mmm-agent
source /root/.bash_profile

# IT明星不是梦 # MySQL高可用集群之MMM_第19张图片
添加成系统服务并设置为自启动

[root@monitor ~]# chkconfig --add mysql-mmm-monitor
[root@monitor ~]# chkconfig mysql-mmm-monitor
[root@monitor ~]# /etc/init.d/mysql-mmm-monitor start

启动报错:

Starting MMM Monitor daemon: Base class package "Class::Singleton" is empty.
    (Perhaps you need to 'use' the module which defines that package first,
    or make that module available in @INC (@INC contains: /root/perl5/lib/perl5/5.16.3/x86_64-linux-thread-multi /root/perl5/lib/perl5/5.16.3 /root/perl5/lib/perl5/x86_64-linux-thread-multi /root/perl5/lib/perl5 /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .).
 at /usr/share/perl5/vendor_perl/MMM/Monitor/Agents.pm line 2.
BEGIN failed--compilation aborted at /usr/share/perl5/vendor_perl/MMM/Monitor/Agents.pm line 2.
Compilation failed in require at /usr/share/perl5/vendor_perl/MMM/Monitor/Monitor.pm line 15.
BEGIN failed--compilation aborted at /usr/share/perl5/vendor_perl/MMM/Monitor/Monitor.pm line 15.
Compilation failed in require at /usr/sbin/mmm_mond line 28.
BEGIN failed--compilation aborted at /usr/sbin/mmm_mond line 28.

解决方法:安装下列perl的库

[root@monitor ~]# cpan Proc::daemon
[root@monitor ~]# cpan Log::Log4perl
[root@monitor ~]# cpan Class::Singleton

[root@monitor ~]# /etc/init.d/mysql-mmm-monitor start
Daemon bin: '/usr/sbin/mmm_mond'
Daemon pid: '/var/run/mmm_mond.pid'
Starting MMM Monitor daemon: Ok
[root@monitor ~]# ss -anplt|grep 9988

# IT明星不是梦 # MySQL高可用集群之MMM

PS:无论是在db端还是在监控端如果有对配置文件进行修改操作都需要重启代理进程和监控进程。MMM启动顺序:先启动monitor,再启动 agent 检查集群状态:
# IT明星不是梦 # MySQL高可用集群之MMM

启动之后,如果出现上面的状态,查看日志

[root@monitor mysql-mmm-2.2.1]# tail -f /var/log/mysql-mmm/mmm_mond.log

# IT明星不是梦 # MySQL高可用集群之MMM_第20张图片
使用mmm_control checks all命令查看信息:

[root@monitor mysql-mmm-2.2.1]#   mmm_control checks all

# IT明星不是梦 # MySQL高可用集群之MMM_第21张图片

安装上面所需要的perl库(5台)

# cpan DBD::mysql
# yum install perl-DBD-mysql

再查看状态

[root@monitor mysql-mmm-2.2.1]# mmm_control show

# IT明星不是梦 # MySQL高可用集群之MMM
如果服务器状态是AWAITING_RECOVERY,就需要手动将服务器上线:

[root@monitor mysql-mmm-2.2.1]# mmm_control set_online mysql-master1
[root@monitor mysql-mmm-2.2.1]# mmm_control set_online mysql-master2
[root@monitor mysql-mmm-2.2.1]# mmm_control set_online mysql-slave1
[root@monitor mysql-mmm-2.2.1]# mmm_control set_online mysql-slave2
[root@monitor mysql-mmm-2.2.1]# mmm_control show

# IT明星不是梦 # MySQL高可用集群之MMM_第22张图片
从上面的显示可以看到,写请求的VIP在mysql-master1上,所有从节点也都把mysql-master1当做主节点。
查看是否启用vip:
mysql-master1:

[root@mysql-master1 mysql-mmm-2.2.1]# ip a

# IT明星不是梦 # MySQL高可用集群之MMM_第23张图片
mysql-master2:

[root@mysql-master2 mysql-mmm-2.2.1]# ip a

# IT明星不是梦 # MySQL高可用集群之MMM_第24张图片
mysql-slave1:

[root@mysql-slave1 mysql-mmm-2.2.1]# ip a

# IT明星不是梦 # MySQL高可用集群之MMM_第25张图片
mysql-slave2:

[root@mysql-slave2 mysql-mmm-2.2.1]# ip a

# IT明星不是梦 # MySQL高可用集群之MMM_第26张图片
在mysql-master2,mysql-slave1,mysql-slave2主机上查看主mysql的指向:

# mysql -uroot -p123.com
mysql> show slave status\G;

# IT明星不是梦 # MySQL高可用集群之MMM_第27张图片
通过VIP访问mysql(测试,任何授权的用户都可以):

[root@monitor mysql-mmm-2.2.1]# mysql -ummm_monitor -p123.com -P3306 -h192.168.1.100

# IT明星不是梦 # MySQL高可用集群之MMM_第28张图片

8、MMM高可用性测试:

服务器读写采有VIP地址进行读写,出现故障时VIP会漂移到其它节点,由其它节点提供服务。
首先查看整个集群的状态,可以看到整个集群状态正常

[root@monitor mysql-mmm-2.2.1]# mmm_control show

# IT明星不是梦 # MySQL高可用集群之MMM
模拟mysql-master1宕机,手动停止mysql服务

[root@mysql-master1 mysql-mmm-2.2.1]# systemctl stop mysqld

观察monitor日志,mysql-master1的日志如下:

[root@monitor mysql-mmm-2.2.1]# tail -f /var/log/mysql-mmm/mmm_mond.log

# IT明星不是梦 # MySQL高可用集群之MMM_第29张图片
查看群集的最新状态

[root@monitor mysql-mmm-2.2.1]# mmm_control show

# IT明星不是梦 # MySQL高可用集群之MMM
从显示结果可以看出mysql-master1的状态有ONLINE转换为HARD_OFFLINE,写VIP转移到了mysql-master2主机上。
检查所有的db服务器群集状态

[root@monitor mysql-mmm-2.2.1]# mmm_control checks all

# IT明星不是梦 # MySQL高可用集群之MMM_第30张图片
从上面可以看到mysql-master1能ping通,说明只是服务死掉了。
查看mysql-master2主机的ip地址:

[root@mysql-master2 mysql-mmm-2.2.1]# ip a

# IT明星不是梦 # MySQL高可用集群之MMM_第31张图片
查看mysql-slave1,mysql-slave2的主从复制状态

mysql> show slave status\G;

# IT明星不是梦 # MySQL高可用集群之MMM_第32张图片
会发现主服务器自动变成了mysql-master2

依然可以通过VIP访问:

[root@monitor mysql-mmm-2.2.1]# mysql -ummm_monitor -p123.com -P3306 -h192.168.1.100

# IT明星不是梦 # MySQL高可用集群之MMM_第33张图片
启动master1主机的mysql服务:

[root@mysql-master1 mysql-mmm-2.2.1]# systemctl start mysqld

观察monitor日志,master1的日志如下:

[root@monitor mysql-mmm-2.2.1]# tail -f /var/log/mysql-mmm/mmm_mond.log

# IT明星不是梦 # MySQL高可用集群之MMM_第34张图片
从上面可以看到mysql-master1的状态由HARD_OFFLINE改变为AWAITING_RECOVERY状态
用如下命令将服务器上线,并查看集群状态:

[root@monitor mysql-mmm-2.2.1]# mmm_control set_online mysql-master1
[root@monitor mysql-mmm-2.2.1]# mmm_control show

# IT明星不是梦 # MySQL高可用集群之MMM
可以看到mysql-master1启动不会接管主,直到现有的主再次宕机。

总结

  1. mysql-master2备选主节点宕机不影响集群的状态,就是移除了mysql-master2备选节点的读状态。
  2. mysql-master1主节点宕机,由mysql-master2备选主节点接管写角色,mysql-slave1, mysql-slave2指向新mysql-master2主库进行复制,mysql-slave1, mysql-slave2会自动change master到mysql-master2.
  3. 如果mysql-master1主库宕机,mysql-master2复制应用又落后于mysql-master1时就变成了主可写状态,这时的数据主无法保证一致性。 如果mysql-master2, mysql-slave1, mysql-slave2延迟于mysql-master1主,这个时mysql-master1宕机,mysql-slave1, mysql-slave2将会等待数据追上db1后,再重新指向新的主node2进行复制操作,这时的数据也无法保证同步的一致性。
  4. 如果采用MMM高可用架构,主,主备选节点机器配置一样,而且开启半同步进一步提高安全性或采用MariaDB/mysql5.7进行多线程从复制,提高复制的性能。

三、服务文件及命令用法

1、日志文件:

日志文件往往是分析错误的关键,所以要善于利用日志文件进行问题分析。

db端:/var/log/mysql-mmm/mmm_agentd.log
监控端:/var/log/mysql-mmm/mmm_mond.log

2、命令文件:

  • mmm_agentd:db代理进程的启动文件
  • mmm_mond:监控进程的启动文件
  • mmm_backup:备份文件
  • mmm_restore:还原文件
  • mmm_control:监控操作命令文件

db服务器端只有mmm_agentd程序,其它的都是在monitor服务器端。

3、mmm_control用法

mmm_control程序可以用于监控群集状态、切换writer、设置online\offline操作等。

[root@monitor mysql-mmm-2.2.1]# mmm_control --help
Invalid command '--help'

Valid commands are:
    help   - show this message  //帮助信息
    ping   - ping monitor       //ping当前的群集是否正常
    show   - show status        //群集在线状态检查
    checks [|all [|all]] - show checks status  //执行监控检查操作
    set_online   - set host  online     //将host设置为online
    set_offline  - set host  offline    //将host设置为offline
    mode   - print current mode.    //打印输出当前的mode
    set_active   - switch into active mode.     //切换到激活模式
    set_manual   - switch into manual mode.     //切换到手动模式
    set_passive  - switch into passive mode.        //切换到被动模式
    move_role [--force]   - move exclusive role  to host (Only use --force if you know what you are doing!) //移除writer服务器为指定的host服务器
    set_ip    - set role with ip  to host   //检查所有的db服务器群集状态
[root@monitor mysql-mmm-2.2.1]# mmm_control checks all
检查项包括:ping、mysql是否正常运行、复制线程是否正常等 检查群集环境在线状况:

# IT明星不是梦 # MySQL高可用集群之MMM_第35张图片

[root@monitor mysql-mmm-2.2.1]# mmm_control show

# IT明星不是梦 # MySQL高可用集群之MMM

对指定的host执行offline操作:

[root@monitor mysql-mmm-2.2.1]# mmm_control set_offline 主机

对指定的host执行onine操作:

[root@monitor mysql-mmm-2.2.1]# mmm_control set_online 主机

四、其它问题处理

如果不想让writer从master切换到backup(包括主从的延时也会导致写VIP的切换),那么可以在配置/etc/mysql-mmm/mmm_common.conf时,去掉中的backup #writer角色配置 hosts master1#这里只配置一个Hosts ips 192.168.1.100#对外提供的写操作的虚拟IP mode exclusive #exclusive代表只允许存在一个主,也就是只能提供一个写的IP 这样的话当master1出现故障了writer写操作不会切换到master2服务器,并且slave也不会指向新的master,此时当前的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参数的影响。