MMM介绍
MMM(Master-Master replication manager for MySQL)是一套支持双主故障切换和双主日常管理的脚本程序。MMM使用Perl语言开发,主要用来监控和管理MySQL Master-Master(双主)复制,可以说是mysql主主复制管理器。虽然叫做双主复制,但是业务上同一时刻只允许对一个主进行写入,另一台备选主上提供部分读服务,以加速在主主切换时刻备选主的预热,可以说MMM这套脚本程序一方面实现了故障切换的功能,另一方面其内部附加的工具脚本也可以实现多个slave的read负载均衡。关于mysql主主复制配置的监控、故障转移和管理的一套可伸缩的脚本套件(在任何时候只有一个节点可以被写入),这个套件也能对居于标准的主从配置的任意数量的从服务器进行读负载均衡,所以你可以用它来在一组居于复制的服务器启动虚拟ip,除此之外,它还有实现数据备份、节点之间重新同步功能的脚本。
MMM提供了自动和手动两种方式移除一组服务器中复制延迟较高的服务器的虚拟ip,同时它还可以备份数据,实现两节点之间的数据同步等。由于MMM无法完全的保证数据一致性,所以MMM适用于对数据的一致性要求不是很高,但是又想最大程度的保证业务可用性的场景。MySQL本身没有提供replication failover的解决方案,通过MMM方案能实现服务器的故障转移,从而实现mysql的高可用。对于那些对数据的一致性要求很高的业务,非常不建议采用MMM这种高可用架构。
从网上分享一个Mysql-MMM的内部架构图:
MySQL-MMM优缺点
1
2
|
优点:高可用性,扩展性好,出现故障自动切换,对于主主同步,在同一时间只提供一台数据库写操作,保证的数据的一致性。
缺点:Monitor节点是单点,可以结合Keepalived实现高可用。
|
MySQL-MMM工作原理
1
2
3
4
5
6
7
8
9
|
MMM(Master-Master replication managerfor Mysql,Mysql主主复制管理器)是一套灵活的脚本程序,基于perl实现,用来对mysql replication进行监控和故障迁移,
并能管理mysql Master-Master复制的配置(同一时间只有一个节点是可写的)。
mmm_mond:监控进程,负责所有的监控工作,决定和处理所有节点角色活动。此脚本需要在监管机上运行。
mmm_agentd:运行在每个mysql服务器上(Master和Slave)的代理进程,完成监控的探针工作和执行简单的远端服务设置。此脚本需要在被监管机上运行。
mmm_control:一个简单的脚本,提供管理mmm_mond进程的命令。
mysql-mmm的监管端会提供多个虚拟IP(VIP),包括一个可写VIP,多个可读VIP,通过监管的管理,这些IP会绑定在可用mysql之上,当某一台mysql宕机时,监管会将VIP迁移
至其他mysql。在整个监管过程中,需要在mysql中添加相关授权用户,以便让mysql可以支持监理机的维护。授权的用户包括一个mmm_monitor用户和一个mmm_agent用户,如果
想使用mmm的备份工具则还要添加一个mmm_tools用户。
|
MySQL-MMM高可用架构环境部署记录(自动切换读写分离)
0)机器配置信息
1
2
3
4
5
6
7
8
9
10
11
|
角色 ip地址 主机名字 server-
id
monitoring 182.48.115.233 mmm-monit -
master1 182.48.115.236 db-master1 1
master2 182.48.115.237 db-master2 2
slave1 182.48.115.238 db-slave 3
业务中的服务ip(vip)信息如下所示:
ip地址 角色 描述
182.48.115.234 write 应用程序连接该ip对主库进行写请求
182.48.115.235
read
应用程序连接该ip进行读请求
182.48.115.239
read
应用程序连接该ip进行读请求
|
1)配置/etc/hosts(所有机器都要操作)
1
2
3
4
5
6
|
[root@mmm-monit ~]
# cat /etc/hosts
.......
182.48.115.233 mmm-monit
182.48.115.236 db-master1
182.48.115.237 db-master2
182.48.115.238 db-slave
|
2)首先在3台主机上安装mysql,部署复制环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
其中:182.48.115.236和182.48.115.237互为主从,182.48.115.238为1182.48.115.236的从
........................................................................
mysql安装参考:http:
//www
.cnblogs.com
/kevingrace/p/6109679
.html
mysql主从/主主配置参考:http:
//www
.cnblogs.com
/kevingrace/p/6256603
.html
........................................................................
---------182.48.115.236的my.cnf添加配置---------
server-
id
= 1
log-bin = mysql-bin
log_slave_updates = 1
auto-increment-increment = 2
auto-increment-offset = 1
---------182.48.115.237的my.cnf添加配置---------
server-
id
= 2
log-bin = mysql-bin
log_slave_updates = 1
auto-increment-increment = 2
auto-increment-offset = 2
---------182.48.115.238的my.cnf添加配置---------
server-
id
= 3
log-bin = mysql-bin
log_slave_updates = 1
注意:
上面的server-
id
不一定要按顺序来,只要没有重复即可。
然后182.48.115.236和182.48.115.237相互授权连接;182.48.115.236授权给182.48.115.238连接。
最后通过
"change master...."
做对应的主主和主从复制,具体操作步骤在此省略,可以参考上面给出的文档。
|
3)安装MMM(所有机器上都要执行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
.......先安装MMM所需要的Perl模块.......
[root@db-master1 ~]
# vim install.sh //在所有机器上执行下面的安装脚本
#!/bin/bash
wget http:
//xrl
.us
/cpanm
--no-check-certificate
mv
cpanm
/usr/bin
chmod
755
/usr/bin/cpanm
cat
>
/root/list
<< EOF
install
Algorithm::Diff
install
Class::Singleton
install
DBI
install
DBD::mysql
install
File::Basename
install
File::stat
install
File::Temp
install
Log::Dispatch
install
Log::Log4perl
install
Mail::Send
install
Net::ARP
install
Net::Ping
install
Proc::Daemon
install
Thread::Queue
install
Time::HiRes
EOF
for
package
in
`
cat
/root/list
`
do
cpanm $package
done
[root@db-master1 ~]
# chmod 755 install.sh
[root@db-master1 ~]
# ./install.sh
.........下载mysql-mmm软件,在所有服务器上安装............
[root@db-master1 ~]
# wget http://mysql-mmm.org/_media/:mmm2:mysql-mmm-2.2.1.tar.gz
[root@db-master1 ~]
# mv :mmm2:mysql-mmm-2.2.1.tar.gz mysql-mmm-2.2.1.tar.gz
[root@db-master1 ~]
# tar -zvxf mysql-mmm-2.2.1.tar.gz
[root@db-master1 ~]
# cd mysql-mmm-2.2.1
[root@db-master1 mysql-mmm-2.2.1]
# make install
mysql-mmm安装后的主要拓扑结构如下所示(注意:yum安装的和源码安装的路径有所区别):
/usr/lib/perl5/vendor_perl/5
.8.8
/MMM
MMM使用的主要perl模块
/usr/lib/mysql-mmm
MMM使用的主要脚本
/usr/sbin
MMM使用的主要命令的路径
/etc/init
.d/ MMM的agent和monitor启动服务的目录
/etc/mysql-mmm
MMM配置文件的路径,默认所以的配置文件位于该目录下
/var/log/mysql-mmm
默认的MMM保存日志的位置
到这里已经完成了MMM的基本需求,接下来需要配置具体的配置文件,其中mmm_common.conf,mmm_agent.conf为agent端的配置文件,mmm_mon.conf为monitor端的配置文件。
|
4)配置agent端的配置文件,需要在db-master1 ,db-master2,db-slave上分别配置(配置内容一样)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
先在db-master1主机上配置agent的mmm_common.conf文件(这个在所有机器上都要配置,包括monitor机器)
[root@db-master1 ~]
# cd /etc/mysql-mmm/
[root@db-master1 mysql-mmm]
# cp mmm_common.conf mmm_common.conf.bak
[root@db-master1 mysql-mmm]
# vim mmm_common.conf
active_master_role writer
cluster_interface eth0
pid_path
/var/run/mmm_agentd
.pid
bin_path
/usr/lib/mysql-mmm/
replication_user slave
//
注意这个账号和下面一行的密码是在前面部署主主/主从复制时创建的复制账号和密码
replication_password slave@123
agent_user mmm_agent
agent_password mmm_agent
<
/host
>
ip 182.48.115.236
mode master
peer db-master1
<
/host
>
ip 182.48.115.237
mode master
peer db-master2
<
/host
>
ip 182.48.115.238
mode slave
<
/host
>
hosts db-master1, db-master2
ips 182.48.115.234
mode exclusive
<
/role
>
hosts db-master2, db-slave
ips 182.48.115.235, 182.48.115.239
mode balanced
<
/role
>
配置解释,其中:
replication_user 用于检查复制的用户
agent_user为agent的用户
mode标明是否为主或者备选主,或者从库。
mode exclusive主为独占模式,同一时刻只能有一个主
可以直接把mmm_common.conf从db-master1拷贝到db-master2、db-slave和mmm-monit三台主机的
/etc/mysql-mmm
下。
[root@db-master1 ~]
# scp /etc/mysql-mmm/mmm_common.conf db-master2:/etc/mysql-mmm/
[root@db-master1 ~]
# scp /etc/mysql-mmm/mmm_common.conf db-slave:/etc/mysql-mmm/
[root@db-master1 ~]
# scp /etc/mysql-mmm/mmm_common.conf mmm-monit:/etc/mysql-mmm/
分别在db-master1,db-master2,db-slave三台主机的
/etc/mysql-mmm
配置mmm_agent.conf文件,分别用不同的字符标识。注意这个文件的this db1这行内容要修改
为各自的主机名。比如本环境中,db-master1要配置this db-master1,db-master2要配置为this db-master2,而db-slave要配置为this db-slave。
在db-master1(182.48.115.236)上:
[root@db-master1 ~]
# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db-master1
在db-master2(182.48.115.237)上:
[root@db-master2 ~]
# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db-master2
在db-slave(182.48.115.238)上:
[root@db-slave ~]
# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db-slave
------------------------------------------------------------------------------------------------------
接着在mmm-monit(182.48.115.233)配置monitor的配置文件:
[root@mmm-monit ~]
# cp /etc/mysql-mmm/mmm_mon.conf /etc/mysql-mmm/mmm_mon.conf.bak
[root@mmm-monit ~]
# vim /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
ip 182.48.115.233
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 182.48.115.238,182.48.115.237,182.48.115.236
auto_set_online 10
//
发现节点丢失,则过10秒进行切换
<
/monitor
>
monitor_user mmm_monitor
monitor_password mmm_monitor
<
/host
>
debug 0
这里只在原有配置文件中的ping_ips添加了整个架构被监控主机的ip地址,而在
|
5)创建监控用户,这里需要创建3个监控用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
具体描述:
用户名 描述 权限
monitor user MMM的monitor端监控所有的mysql数据库的状态用户 REPLICATION CLIENT
agent user 主要是MMM客户端用于改变的master的read_only状态用户 SUPER,REPLICATION CLIENT,PROCESS
repl 用于复制的用户 REPLICATION SLAVE
在3台服务器(db-master1,db-master2,db-slave)进行授权,因为之前部署的主主复制,以及主从复制已经是ok的,所以这里在其中一台服务器执行就ok了,执行后
权限会自动同步到其它两台机器上。用于复制的账号之前已经有了,所以这里就授权两个账号。
在db-master1上进行授权操作:
mysql> GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO
'mmm_agent'
@
'182.48.115.%'
IDENTIFIED BY
'mmm_agent'
;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION CLIENT ON *.* TO
'mmm_monitor'
@
'182.48.115.%'
IDENTIFIED BY
'mmm_monitor'
;
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
然后在db-master2和db-slave两台机器上查看,发现上面在db-master1机器上授权的账号已经同步过来了!
|
6)启动agent和monitor服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
最后分别在db-master1,db-master2,db-slave上启动agent
[root@db-master1 ~]
# /etc/init.d/mysql-mmm-agent start //将start替换成status,则查看agent进程起来了没?
Daemon bin:
'/usr/sbin/mmm_agentd'
Daemon pid:
'/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Ok
[root@db-master2 ~]
# /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
[root@db-slave ~]
# /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
接着在mmm-monit上启动monitor程序
[root@mmm-monit ~]
# mkdir /var/run/mysql-mmm
[root@mmm-monit ~]
# /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
........................................................................................................
如果monitor程序启动出现如下报错:
Daemon bin:
'/usr/sbin/mmm_mond'
Daemon pid:
'/var/run/mmm_mond.pid'
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:
/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.
failed
解决办法:
[root@mmm-monit ~]
# perl -MCPAN -e shell
...............................................
如是执行这个命令后,有如下报错:
Can't
locate
CPAN.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
.).
BEGIN failed--compilation aborted.
解决:
[root@mmm-monit ~]
# rpm -q perl-CPAN
package perl-CPAN is not installed
[root@mmm-monit ~]
# yum install perl-CPAN
...............................................
执行上面的
"perl -MCPAN -e shell"
命令后,出现下面的安装命令
......
cpan[1]>
install
MIME::Entity
//
依次输入这些安装命令
cpan[2]>
install
MIME::Parser
cpan[3]>
install
Crypt::PasswdMD5
cpan[4]>
install
Term::ReadPassword
cpan[5]>
install
Crypt::CBC
cpan[6]>
install
Crypt::Blowfish
cpan[7]>
install
Daemon::Generic
cpan[8]>
install
DateTime
cpan[9]>
install
SOAP::Lite
或者直接执行下面的安装命令的命令也行:
[root@mmm-monit ~]
# perl -MCPAN -e 'install HTML::Template'
[root@mmm-monit ~]
# perl -MCPAN -e 'install MIME::Entity'
[root@mmm-monit ~]
# perl -MCPAN -e 'install Crypt::PasswdMD5'
[root@mmm-monit ~]
# perl -MCPAN -e 'install Term::ReadPassword'
[root@mmm-monit ~]
# perl -MCPAN -e 'install Crypt::CBC'
[root@mmm-monit ~]
# perl -MCPAN -e 'install Crypt::Blowfish'
[root@mmm-monit ~]
# perl -MCPAN -e 'install Daemon::Generic'
[root@mmm-monit ~]
# perl -MCPAN -e 'install DateTime'
[root@mmm-monit ~]
# perl -MCPAN -e 'install SOAP::Lite'
............................................................................................................
monitor进程启动后,如下查看,发现进程并没有起来!
[root@mmm-monit ~]
# /etc/init.d/mysql-mmm-monitor status
Daemon bin:
'/usr/sbin/mmm_mond'
Daemon pid:
'/var/run/mmm_mond.pid'
Checking MMM Monitor process: not running.
解决办法:
将mmm_mon.conf的debug模式开启设为1,即打开debug模式,然后执行:
[root@mmm-monit ~]
# /etc/init.d/mysql-mmm-monitor start
.......
open2:
exec
of
/usr/libexec/mysql-mmm/monitor/checker
ping_ip failed at
/usr/share/perl5/vendor_perl/MMM/Monitor/Checker
.pm line 143.
2017
/06/01
20:16:02 WARN Checker
'ping_ip'
is dead!
2017
/06/01
20:16:02 INFO Spawning checker
'ping_ip'
...
2017
/06/01
20:16:02 DEBUG Core: reaped child 17439 with
exit
65280
原因是mmm_mon.conf文件里check的bin_path路径写错了
[root@mmm-monit ~]
# cat /etc/mysql-mmm/mmm_mon.conf|grep bin_path
bin_path
/usr/libexec/mysql-mmm
将上面的bin_path改为
/usr/lib/mysql-mmm
即可解决!即:
[root@mmm-monit ~]
# cat /etc/mysql-mmm/mmm_mon.conf|grep bin_path
bin_path
/usr/lib/mysql-mmm
接着再次启动monitor进程
[root@mmm-monit ~]
# /etc/init.d/mysql-mmm-monitor start
.......
FATAL Couldn
't open status file '
/var/lib/mysql-mmm/mmm_mond
.status': Starting up without status inf
.......
Error
in
tempfile() using template
/var/lib/mysql-mmm/mmm_mond
.statusXXXXXXXXXX: Parent directory (
/var/lib/mysql-mmm/
) does not exist at
/usr/share/perl5/vendor_perl/MMM/Monitor/Agents
.pm line 158.
Perl exited with active threads:
6 running and unjoined
0 finished and unjoined
0 running and detached
原因是mmm_mon.conf文件里check的status_path路径写错了
[root@mmm-monit ~]
# cat /etc/mysql-mmm/mmm_mon.conf |grep status_path
status_path
/var/lib/mysql-mmm/mmm_mond
.status
将上面的status_path改为
/var/lib/misc//mmm_mond
.status 即可解决!即:
[root@mmm-monit ~]
# cat /etc/mysql-mmm/mmm_mon.conf|grep status_path
status_path
/var/lib/misc/mmm_mond
.status
然后再次启动monitor进程
[root@mmm-monit ~]
# /etc/init.d/mysql-mmm-monitor restart
........
2017
/06/01
20:57:14 DEBUG Sending
command
'SET_STATUS(ONLINE, reader(182.48.115.235), db-master1)'
to db-master2 (182.48.115.237:9989)
2017
/06/01
20:57:14 DEBUG Received Answer: OK: Status applied successfully!|UP:885492.82
2017
/06/01
20:57:14 DEBUG Sending
command
'SET_STATUS(ONLINE, writer(182.48.115.234), db-master1)'
to db-master1 (182.48.115.236:9989)
2017
/06/01
20:57:14 DEBUG Received Answer: OK: Status applied successfully!|UP:65356.14
2017
/06/01
20:57:14 DEBUG Sending
command
'SET_STATUS(ONLINE, reader(182.48.115.239), db-master1)'
to db-slave (182.48.115.238:9989)
2017
/06/01
20:57:14 DEBUG Received Answer: OK: Status applied successfully!|UP:945625.05
2017
/06/01
20:57:15 DEBUG Listener: Waiting
for
connection...
2017
/06/01
20:57:17 DEBUG Sending
command
'SET_STATUS(ONLINE, reader(182.48.115.235), db-master1)'
to db-master2 (182.48.115.237:9989)
2017
/06/01
20:57:17 DEBUG Received Answer: OK: Status applied successfully!|UP:885495.95
2017
/06/01
20:57:17 DEBUG Sending
command
'SET_STATUS(ONLINE, writer(182.48.115.234), db-master1)'
to db-master1 (182.48.115.236:9989)
2017
/06/01
20:57:17 DEBUG Received Answer: OK: Status applied successfully!|UP:65359.27
2017
/06/01
20:57:17 DEBUG Sending
command
'SET_STATUS(ONLINE, reader(182.48.115.239), db-master1)'
to db-slave (182.48.115.238:9989)
2017
/06/01
20:57:17 DEBUG Received Answer: OK: Status applied successfully!|UP:945628.17
2017
/06/01
20:57:18 DEBUG Listener: Waiting
for
connection...
.........
只要上面在启动过程中的check检查中没有报错信息,并且有successfully信息,则表示monitor进程正常了。
[root@mmm-monit ~]
# ps -ef|grep monitor
root 30651 30540 0 20:59 ? 00:00:00 perl
/usr/lib/mysql-mmm/monitor/checker
ping_ip
|