MMM介紹
MMM是Multi-Master Replication Manager for MySQL的縮寫,它是MySQL提供的一個(gè)多主復(fù)制管理器方椎,其核心是使用perl語(yǔ)言編寫的一組腳本钧嘶。實(shí)際上MMM是比較早期甚至有點(diǎn)老的一種用于構(gòu)建高可用MySQL架構(gòu)的方式有决,但因其還有一定的應(yīng)用場(chǎng)景,所以本文將會(huì)演示一下如何搭建一個(gè)MMM架構(gòu)新荤。
MMM 由兩個(gè)組件組成:
-
monitor
:監(jiān)控集群內(nèi)數(shù)據(jù)庫(kù)的狀態(tài)迟隅,在出現(xiàn)異常時(shí)發(fā)布切換命令励七,一般和數(shù)據(jù)庫(kù)分開部署 -
agent
:運(yùn)行在每個(gè) MySQL 服務(wù)器上的代理進(jìn)程掠抬,monitor
命令的執(zhí)行者,完成監(jiān)控的探針工作和具體服務(wù)設(shè)置瞳步,例如設(shè)置 VIP腰奋、指向新同步節(jié)點(diǎn)
MMM的主要作用:
- 監(jiān)控和管理MySQL的主主復(fù)制拓?fù)淞臃唬⒃诋?dāng)前的主服務(wù)器發(fā)生故障時(shí),進(jìn)行主和主備服務(wù)器之間的主從切換和故障轉(zhuǎn)移等工作
MMM提供了什么功能:
- MMM可以監(jiān)控MySQL主從復(fù)制健康情況测蘑,包括mysql服務(wù)器的狀態(tài)碳胳、從庫(kù)拷貝活動(dòng)的狀態(tài)等
- 可以在主庫(kù)出現(xiàn)宕機(jī)時(shí)進(jìn)行故障轉(zhuǎn)移沫勿,并自動(dòng)配置其他從庫(kù)對(duì)新主庫(kù)的復(fù)制
- 為主庫(kù)提供了一個(gè)寫虛擬IP味混,在主從服務(wù)器出現(xiàn)問(wèn)題時(shí)可以自動(dòng)遷移虛擬IP
- 當(dāng)配置多個(gè)從庫(kù)時(shí)惜傲,可配置多個(gè)虛擬讀IP,配合第三方負(fù)載均衡軟件(如LVS)时甚,實(shí)現(xiàn)負(fù)載均衡功能
MMM對(duì)于主備切換后如何讓從庫(kù)同步日志點(diǎn):
- MMM對(duì)于這方面的處理并不安全荒适,只是簡(jiǎn)單粗暴地讓從庫(kù)同步新主庫(kù)的當(dāng)前日志點(diǎn),所以在一個(gè)繁忙的系統(tǒng)中使用MMM很有可能會(huì)對(duì)數(shù)據(jù)造成丟失的情況
動(dòng)手搭建MMM架構(gòu)
本文要搭建的MMM架構(gòu)如下:
以上述架構(gòu)為例,描述一下故障轉(zhuǎn)移的流程陕壹,現(xiàn)在假設(shè) Master1 宕機(jī):
- Monitor 檢測(cè)到 Master1 連接失敗
- Monitor 發(fā)送 set_offline 指令到 Master1 的 Agent
- Master1 Agent 如果存活糠馆,下線寫 VIP,嘗試把 Master1 設(shè)置為
read_only=1
- Moniotr 發(fā)送 set_online 指令到 Master2
- Master2 Agent 接收到指令九昧,執(zhí)行
select master_pos_wait()
等待同步完畢 - Master2 Agent 上線寫 VIP铸鹰,把 Master2 節(jié)點(diǎn)設(shè)為
read_only=0
- Monitor 發(fā)送更改同步對(duì)象的指令到各個(gè) Slave 節(jié)點(diǎn)的 Agent
- 各個(gè) Slave 節(jié)點(diǎn)向新 Master 同步數(shù)據(jù)
從整個(gè)流程可以看到皂岔,如果主節(jié)點(diǎn)出現(xiàn)故障凤薛,MMM 會(huì)自動(dòng)實(shí)現(xiàn)切換,不需要人工干預(yù)速兔,同時(shí)我們也能看出一些問(wèn)題涣狗,就是數(shù)據(jù)庫(kù)掛掉后,只是做了切換穗熬,不會(huì)主動(dòng)補(bǔ)齊丟失的數(shù)據(jù)丁溅,所以 MMM 會(huì)有數(shù)據(jù)不一致性的風(fēng)險(xiǎn)窟赏。
搭建MMM架構(gòu)所需的資源說(shuō)明:
名稱 | 數(shù)量 | 說(shuō)明 |
---|---|---|
Master服務(wù)器 | 2 | 用于主備模式的主主復(fù)制配置 |
Slave服務(wù)器 | 0-N | 可以配置0臺(tái)或多臺(tái)從服務(wù)器,但不建議太多 |
監(jiān)控服務(wù)器 | 1 | 安裝MMM用于監(jiān)控MySQL復(fù)制集群 |
IP地址 | 2*(n+1) | n為MySQL服務(wù)器的數(shù)量 |
監(jiān)控用戶 | 1 | 用于監(jiān)控?cái)?shù)據(jù)庫(kù)狀態(tài)的MySQL用戶(至少擁有replication client 權(quán)限) |
代理用戶 | 1 | 用于MMM代理的MySQL用戶(至少擁有super 、replication client 拷况、process 權(quán)限) |
復(fù)制用戶 | 1 | 用于配置MySQL主從復(fù)制的用戶(至少擁有replication slave 權(quán)限) |
本文中所使用的機(jī)器說(shuō)明:
名稱 | IP | 角色 |
---|---|---|
master-01 | 192.168.190.146 | 主庫(kù) |
master-02 | 192.168.190.148 | 備庫(kù) |
slave-01 | 192.168.190.149 | 從庫(kù) |
manager | 192.168.190.147 | 集群管理器(MMM) |
環(huán)境版本說(shuō)明:
- 操作系統(tǒng)版本:CentOS 7
- MySQL版本:8.0.19
- MMM版本:2.2.1
另外的說(shuō)明:
- 會(huì)來(lái)了解MMM架構(gòu)的小伙伴們想必都已經(jīng)掌握了MySQL的安裝方式粟誓,而且介紹MySQL的安裝也有很多文章起意,所以本文為了減少不必要的篇幅就不演示MySQL的安裝了杜恰,文中所用到的機(jī)器都已經(jīng)提前安裝好了MySQL。
配置主主復(fù)制及主從同步集群
1舔涎、在master-01
和master-02
上使用如下語(yǔ)句分別創(chuàng)建用于主主復(fù)制的MySQL用戶:
create user 'repl'@'%' identified with mysql_native_password by 'Abc_123456';
grant replication slave on *.* to 'repl'@'%';
flush privileges;
- Tips:創(chuàng)建好賬戶后逗爹,最好使用該賬戶在兩個(gè)節(jié)點(diǎn)互相登錄一下掘而,以確保賬戶是可用的
2、修改master-01
上的MySQL配置文件:
[root@master-01 ~]# vim /etc/my.cnf
[mysqld]
# 設(shè)置節(jié)點(diǎn)的id
server_id=101
# 開啟binlog知染,并指定binlog文件的名稱
log_bin=mysql_bin
# 開啟relay_log控淡,并指定relay_log文件的名稱
relay_log=relay_bin
# 將relaylog的同步內(nèi)容記錄到binlog中
log_slave_updates=on
在master-02
的配置文件中也是添加一樣配置,只不過(guò)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
辫诅,由于該節(jié)點(diǎn)不是作為備庫(kù)存在炕矮,而只是單獨(dú)的從庫(kù)角色者冤,所以不需要開啟log_slave_updates
參數(shù):
[root@slave-01 ~]# vim /etc/my.cnf
[mysqld]
server_id=103
log_bin=mysql_bin
relay_log=relay_bin
完成以上配置文件的修改后,分別重啟這三個(gè)節(jié)點(diǎn)上的MySQL服務(wù):
[root@master-01 ~]# systemctl restart mysqld
[root@master-02 ~]# systemctl restart mysqld
[root@slave-01 ~]# systemctl restart mysqld
配置master-02
對(duì)master-01
的主從關(guān)系
進(jìn)入master-01
的MySQL命令行終端譬嚣,通過(guò)如下語(yǔ)句查詢master-01
當(dāng)前正在使用的二進(jìn)制日志及當(dāng)前執(zhí)行二進(jìn)制日志位置:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
記錄其中的File
和Position
的值,然后進(jìn)入master-02
的MySQL命令行終端钞它,分別執(zhí)行如下語(yǔ)句:
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節(jié)點(diǎn)的連接信息拜银,以及從哪個(gè)binlog文件的哪個(gè)位置開始復(fù)制
mysql> start slave; -- 啟動(dòng)主從同步
配置完主從關(guān)系后,使用show slave status\G;
語(yǔ)句查看主從同步狀態(tài)遭垛,Slave_IO_Running
和Slave_SQL_Running
的值均為Yes
才能表示主從同步狀態(tài)是正常的:
配置master-01
對(duì)master-02
的主從關(guān)系
為了實(shí)現(xiàn)主主復(fù)制尼桶,master-01
和master-02
需要互為主從關(guān)系锯仪,所以還需要配置master-01
對(duì)master-02
的主從關(guān)系泵督。進(jìn)入master-02
的MySQL命令行終端,通過(guò)如下語(yǔ)句查詢master-02
當(dāng)前正在使用的二進(jìn)制日志及當(dāng)前執(zhí)行二進(jìn)制日志位置:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
記錄其中的File
和Position
的值庶喜,然后進(jìn)入master-01
的MySQL命令行終端小腊,分別執(zhí)行如下語(yǔ)句:
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;
語(yǔ)句查看主從同步狀態(tài)久窟,Slave_IO_Running
和Slave_SQL_Running
的值均為Yes
才能表示主從同步狀態(tài)是正常的:
配置slave-01
對(duì)master-01
的主從關(guān)系
接著就是配置從庫(kù)對(duì)主庫(kù)的主從關(guān)系了秩冈,這里與master-02
是一樣的,除非期間對(duì)master-01
上的數(shù)據(jù)做了修改才需要重新獲取日志點(diǎn):
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;
搭建MMM服務(wù)
1斥扛、在所有的機(jī)器上安裝 epel
源:
yum install -y epel-release
2入问、在所有的主從節(jié)點(diǎn)上安裝MMM代理客戶端:
yum install -y mysql-mmm-agent
3、在 manager
節(jié)點(diǎn)上安裝所有的MMM包:
yum install -y mysql-mmm*
4稀颁、然后在master-01
上創(chuàng)建用于監(jiān)控和代理的MySQL用戶:
-- 監(jiān)控用戶
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;
由于配置了主從的原因芬失,此時(shí)其他兩個(gè)數(shù)據(jù)庫(kù)節(jié)點(diǎn)也會(huì)同步這些新建的用戶。在另外兩個(gè)節(jié)點(diǎn)執(zhí)行如下語(yǔ)句就可以查詢到:
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匾灶、編輯所有節(jié)點(diǎn)包括監(jiān)控節(jié)點(diǎn)上的mmm_common.conf
配置文件棱烂,主要是配置當(dāng)前節(jié)點(diǎn)和集群中其他節(jié)點(diǎn)的信息。這里以master-01
節(jié)點(diǎn)為例阶女,其配置內(nèi)容如下:
[root@master-01 ~]# vim /etc/mysql-mmm/mmm_common.conf
active_master_role writer
<host default>
cluster_interface ens32 # 當(dāng)前節(jié)點(diǎn)的網(wǎng)卡名稱垢啼,用于綁定虛擬IP窜锯,可以ip addr命令查詢
pid_path /run/mysql-mmm-agent.pid # pid文件存放的路徑
bin_path /usr/libexec/mysql-mmm/ # 可執(zhí)行文件存放的路徑
replication_user repl # 用于復(fù)制的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>
# 配置負(fù)責(zé)寫操作的庫(kù)
<role writer>
hosts db1, db2 # 指定可寫的庫(kù),這里是上面host標(biāo)簽中定義的名稱
ips 192.168.190.90 # 配置寫虛擬IP芭析,可以有多個(gè)使用逗號(hào)分隔
mode exclusive # 表示同一時(shí)刻只有一個(gè)主庫(kù)提供服務(wù)
</role>
# 配置負(fù)責(zé)讀操作的庫(kù)
<role reader>
hosts db1, db2, db3 # 指定可讀的庫(kù)
ips 192.168.190.91,192.168.190.92,192.168.190.93 # 配置讀虛擬IP
mode balanced # 表示將讀請(qǐng)求負(fù)載均衡到以上所配置的db上
</role>
其他三個(gè)節(jié)點(diǎn)也按照相同的方式進(jìn)行配置即可锚扎,除了網(wǎng)卡名稱可能會(huì)不同外,其它的參數(shù)都應(yīng)該是一致的馁启。
6驾孔、然后配置各個(gè)節(jié)點(diǎn)的mmm_agent.conf
文件,聲明當(dāng)前節(jié)點(diǎn)在host
標(biāo)簽中所定義的名稱惯疙。master-01
節(jié)點(diǎn)的配置如下:
[root@master-01 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1
master-02
節(jié)點(diǎn)的配置如下:
[root@master-02 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1
slave-01
節(jié)點(diǎn)的配置如下:
[root@slave-01 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db3
7翠勉、接著配置監(jiān)控節(jié)點(diǎn)上的mmm_mon.conf
文件,配置內(nèi)容如下:
[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 # 配置集群中各個(gè)節(jié)點(diǎn)的IP
auto_set_online 60 # 設(shè)置當(dāng)節(jié)點(diǎn)宕機(jī)恢復(fù)后自動(dòng)上線的時(shí)間霉颠,單位為秒
# 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>
# 配置用于監(jiān)控的MySQL用戶和密碼
monitor_user mmm_monitor
monitor_password Abc_123456
</host>
debug 0
8对碌、啟動(dòng)所有主從節(jié)點(diǎn)的MMM代理服務(wù):
[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
服務(wù)默認(rèn)會(huì)監(jiān)聽9989
端口,如果開啟了防火墻則需要開放該端口:
firewall-cmd --zone=public --add-port=9989/tcp --permanent
firewall-cmd --reload
9蒿偎、啟動(dòng)監(jiān)控節(jié)點(diǎn)上的監(jiān)控服務(wù):
[root@manager ~]# systemctl start mysql-mmm-monitor
10朽们、完成以上所有步驟后,在監(jiān)控節(jié)點(diǎn)上使用mmm_control show
命令就可以查看到集群中各個(gè)節(jié)點(diǎn)的狀態(tài)及其分配的虛擬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 ~]#
測(cè)試
到此為止骑脱,我們就已經(jīng)完成了MMM高可用架構(gòu)的搭建,接下來(lái)我們對(duì)其進(jìn)行一些簡(jiǎn)單的測(cè)試苍糠。例如叁丧,測(cè)試下是否能正常ping
通虛擬IP,畢竟應(yīng)用端訪問(wèn)數(shù)據(jù)庫(kù)時(shí)連接的是虛擬IP岳瞭,所以首先得確保虛擬IP是能夠被訪問(wèn)的拥娄。如下:
能ping
通之后,使用Navicat等遠(yuǎn)程連接工具測(cè)試下能否正常連接上:
確定了各個(gè)虛擬IP都能正常訪問(wèn)后瞳筏,測(cè)試下MMM是否能正常進(jìn)行故障轉(zhuǎn)移条舔,首先將master-01
上的MySQL服務(wù)給停掉:
[root@master-01 ~]# systemctl stop mysqld
正常情況下,此時(shí)到監(jiān)控節(jié)點(diǎn)上使用mmm_control show
命令可以看到master-01
節(jié)點(diǎn)已經(jīng)處于脫機(jī)狀態(tài)乏矾,而用于寫的虛擬IP正常的切換到了master-02
節(jié)點(diǎn)上:
[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 ~]#
接著進(jìn)入slave-01
節(jié)點(diǎn)上的MySQL終端孟抗。之前我們配置slave-01
的主庫(kù)是master-01
,現(xiàn)在已經(jīng)將master-01
停掉后钻心,可以看到slave-01
的主庫(kù)被MMM切換成了master-02
:
經(jīng)過(guò)以上測(cè)試后凄硼,可以看到我們搭建的MMM架構(gòu)是能夠正常運(yùn)行的,已經(jīng)使得Replication集群擁有了基本的高可用能力捷沸,即便主庫(kù)下線后也能正常切換到備庫(kù)上摊沉,也正確建立了從庫(kù)與新主庫(kù)的關(guān)系。
MMM架構(gòu)的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 使用Perl腳本語(yǔ)言開發(fā)并且完全開源痒给,開發(fā)者可以根據(jù)自己的需求進(jìn)行二次開發(fā)
- 提供了從服務(wù)器的延遲監(jiān)控以及讀寫VIP(虛擬IP)说墨,使服務(wù)器角色的變更對(duì)前端應(yīng)用透明骏全。并且在從庫(kù)出現(xiàn)大量的主從延遲或主從復(fù)制鏈路中斷時(shí),可以把這臺(tái)從庫(kù)上的讀虛擬IP尼斧,漂移到集群中其他正常的可讀節(jié)點(diǎn)上
- 提供了當(dāng)主庫(kù)故障轉(zhuǎn)移后姜贡,從庫(kù)對(duì)新主庫(kù)的重新同步功能,所以很容易對(duì)發(fā)生故障的主庫(kù)重新上線棺棵,讓Replication集群具備高可用性
缺點(diǎn):
- MMM屬于一個(gè)比較老的工具了楼咳,其最后發(fā)布的版本也是好幾年前了,所以會(huì)存在一些小bug烛恤,并且不支持MySQL 5.6+版本中新增的基于GTID的復(fù)制母怜,只支持基于日志點(diǎn)的復(fù)制
- 沒有提供讀負(fù)載均衡的功能,需要額外引入LVS等工具來(lái)實(shí)現(xiàn)
- 在進(jìn)行主從切換時(shí)缚柏,容易造成數(shù)據(jù)丟失或事務(wù)的重復(fù)提交苹熏。因?yàn)镸MM不會(huì)對(duì)比多個(gè)從庫(kù)的日志點(diǎn),而是直接選擇備庫(kù)進(jìn)行切換币喧。由于Replication集群是異步復(fù)制的轨域,當(dāng)備庫(kù)的同步延遲比較大時(shí),可能會(huì)出現(xiàn)從庫(kù)的日志點(diǎn)比備庫(kù)的要更新粱锐。所以當(dāng)主庫(kù)意外下線時(shí),MMM強(qiáng)制切換成備庫(kù)就有可能會(huì)導(dǎo)致數(shù)據(jù)的丟失或從庫(kù)重復(fù)提交事務(wù)
- MMM沒有提供相關(guān)的高可用功能扛邑,所以監(jiān)控節(jié)點(diǎn)自身存在單點(diǎn)故障怜浅,而Replication集群的高可用依賴于監(jiān)控節(jié)點(diǎn),當(dāng)監(jiān)控節(jié)點(diǎn)掛掉Replication集群也就不再具備高可用性了蔬崩。但我們可以引入第三方工具來(lái)對(duì)監(jiān)控節(jié)點(diǎn)做雙機(jī)熱備恶座,例如Keepalived
綜合優(yōu)缺點(diǎn)可以得知:MMM僅適用于對(duì)數(shù)據(jù)一致性要求不高,允許丟失少量數(shù)據(jù)的場(chǎng)景下沥阳,例如評(píng)論跨琳、資訊類等數(shù)據(jù)