基於MMM搭建MySQL Replication集羣高可用架構

MMM介紹

MMM是Multi-Master Replication Manager for MySQL的縮寫,它是MySQL提供的一個多主複製管理器,其核心是使用perl語言編寫的一組腳本。實際上MMM是比較早期甚至有點老的一種用於構建高可用MySQL架構的方式,但因其還有一定的應用場景,所以本文將會演示一下如何搭建一個MMM架構。

MMM 由兩個組件組成:

  • monitor:監控集羣內數據庫的狀態,在出現異常時發佈切換命令,一般和數據庫分開部署
  • agent:運行在每個 MySQL 服務器上的代理進程,monitor 命令的執行者,完成監控的探針工作和具體服務設置,例如設置 VIP、指向新同步節點

MMM的主要作用:

  • 監控和管理MySQL的主主複製拓撲,並在當前的主服務器發生故障時,進行主和主備服務器之間的主從切換和故障轉移等工作

MMM提供了什麼功能:

  • MMM可以監控MySQL主從複製健康情況,包括mysql服務器的狀態、從庫拷貝活動的狀態等
  • 可以在主庫出現宕機時進行故障轉移,並自動配置其他從庫對新主庫的複製
  • 爲主庫提供了一個寫虛擬IP,在主從服務器出現問題時可以自動遷移虛擬IP
  • 當配置多個從庫時,可配置多個虛擬讀IP,配合第三方負載均衡軟件(如LVS),實現負載均衡功能

MMM對於主備切換後如何讓從庫同步日誌點:

  • MMM對於這方面的處理並不安全,只是簡單粗暴地讓從庫同步新主庫的當前日誌點,所以在一個繁忙的系統中使用MMM很有可能會對數據造成丟失的情況

動手搭建MMM架構

本文要搭建的MMM架構如下:
基於MMM搭建MySQL Replication集羣高可用架構

以上述架構爲例,描述一下故障轉移的流程,現在假設 Master1 宕機:

  1. Monitor 檢測到 Master1 連接失敗
  2. Monitor 發送 set_offline 指令到 Master1 的 Agent
  3. Master1 Agent 如果存活,下線寫 VIP,嘗試把 Master1 設置爲 read_only=1
  4. Moniotr 發送 set_online 指令到 Master2
  5. Master2 Agent 接收到指令,執行 select master_pos_wait() 等待同步完畢
  6. Master2 Agent 上線寫 VIP,把 Master2 節點設爲 read_only=0
  7. Monitor 發送更改同步對象的指令到各個 Slave 節點的 Agent
  8. 各個 Slave 節點向新 Master 同步數據

從整個流程可以看到,如果主節點出現故障,MMM 會自動實現切換,不需要人工干預,同時我們也能看出一些問題,就是數據庫掛掉後,只是做了切換,不會主動補齊丟失的數據,所以 MMM 會有數據不一致性的風險。

搭建MMM架構所需的資源說明:

名稱 數量 說明
Master服務器 2 用於主備模式的主主複製配置
Slave服務器 0-N 可以配置0臺或多臺從服務器,但不建議太多
監控服務器 1 安裝MMM用於監控MySQL複製集羣
IP地址 2*(n+1) n爲MySQL服務器的數量
監控用戶 1 用於監控數據庫狀態的MySQL用戶(至少擁有replication client權限)
代理用戶 1 用於MMM代理的MySQL用戶(至少擁有superreplication clientprocess權限)
複製用戶 1 用於配置MySQL主從複製的用戶(至少擁有replication slave權限)

本文中所使用的機器說明:

名稱 IP 角色
master-01 192.168.190.146 主庫
master-02 192.168.190.148 備庫
slave-01 192.168.190.149 從庫
manager 192.168.190.147 集羣管理器(MMM)

環境版本說明:

  • 操作系統版本:CentOS 7
  • MySQL版本:8.0.19
  • MMM版本:2.2.1

另外的說明:

  • 會來了解MMM架構的小夥伴們想必都已經掌握了MySQL的安裝方式,而且介紹MySQL的安裝也有很多文章,所以本文爲了減少不必要的篇幅就不演示MySQL的安裝了,文中所用到的機器都已經提前安裝好了MySQL。

配置主主複製及主從同步集羣

1、在master-01master-02上使用如下語句分別創建用於主主複製的MySQL用戶:

create user 'repl'@'%' identified with mysql_native_password by 'Abc_123456';
grant replication slave on *.* to 'repl'@'%';
flush privileges;
  • Tips:創建好賬戶後,最好使用該賬戶在兩個節點互相登錄一下,以確保賬戶是可用的

2、修改master-01上的MySQL配置文件:

[root@master-01 ~]# vim /etc/my.cnf
[mysqld]
# 設置節點的id
server_id=101
# 開啓binlog,並指定binlog文件的名稱
log_bin=mysql_bin
# 開啓relay_log,並指定relay_log文件的名稱
relay_log=relay_bin
# 將relaylog的同步內容記錄到binlog中
log_slave_updates=on

master-02的配置文件中也是添加一樣配置,只不過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,由於該節點不是作爲備庫存在,而只是單獨的從庫角色,所以不需要開啓log_slave_updates參數:

[root@slave-01 ~]# vim /etc/my.cnf
[mysqld]
server_id=103
log_bin=mysql_bin
relay_log=relay_bin

完成以上配置文件的修改後,分別重啓這三個節點上的MySQL服務:

[root@master-01 ~]# systemctl restart mysqld
[root@master-02 ~]# systemctl restart mysqld
[root@slave-01 ~]# systemctl restart mysqld

配置master-02master-01的主從關係

進入master-01的MySQL命令行終端,通過如下語句查詢master-01當前正在使用的二進制日誌及當前執行二進制日誌位置:

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 |      155 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

記錄其中的FilePosition的值,然後進入master-02的MySQL命令行終端,分別執行如下語句:

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節點的連接信息,以及從哪個binlog文件的哪個位置開始複製
mysql> start slave;  -- 啓動主從同步

配置完主從關係後,使用show slave status\G;語句查看主從同步狀態,Slave_IO_RunningSlave_SQL_Running的值均爲Yes才能表示主從同步狀態是正常的:
基於MMM搭建MySQL Replication集羣高可用架構


配置master-01master-02的主從關係

爲了實現主主複製,master-01master-02需要互爲主從關係,所以還需要配置master-01master-02的主從關係。進入master-02的MySQL命令行終端,通過如下語句查詢master-02當前正在使用的二進制日誌及當前執行二進制日誌位置:

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 |      155 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

記錄其中的FilePosition的值,然後進入master-01的MySQL命令行終端,分別執行如下語句:

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;語句查看主從同步狀態,Slave_IO_RunningSlave_SQL_Running的值均爲Yes才能表示主從同步狀態是正常的:
基於MMM搭建MySQL Replication集羣高可用架構


配置slave-01master-01的主從關係

接着就是配置從庫對主庫的主從關係了,這裏與master-02是一樣的,除非期間對master-01上的數據做了修改才需要重新獲取日誌點:

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服務

1、在所有的機器上安裝 epel 源:

yum install -y epel-release

2、在所有的主從節點上安裝MMM代理客戶端:

yum install -y mysql-mmm-agent

3、在 manager節點上安裝所有的MMM包:

yum install -y mysql-mmm*

4、然後在master-01上創建用於監控和代理的MySQL用戶:

-- 監控用戶
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;

由於配置了主從的原因,此時其他兩個數據庫節點也會同步這些新建的用戶。在另外兩個節點執行如下語句就可以查詢到:

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、編輯所有節點包括監控節點上的mmm_common.conf配置文件,主要是配置當前節點和集羣中其他節點的信息。這裏以master-01節點爲例,其配置內容如下:

[root@master-01 ~]# vim /etc/mysql-mmm/mmm_common.conf
active_master_role      writer

<host default>
    cluster_interface       ens32  # 當前節點的網卡名稱,用於綁定虛擬IP,可以ip addr命令查詢
    pid_path                /run/mysql-mmm-agent.pid  # pid文件存放的路徑
    bin_path                /usr/libexec/mysql-mmm/  # 可執行文件存放的路徑
    replication_user        repl  # 用於複製的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>

# 配置負責寫操作的庫
<role writer>
    hosts   db1, db2  # 指定可寫的庫,這裏是上面host標籤中定義的名稱
    ips     192.168.190.90  # 配置寫虛擬IP,可以有多個使用逗號分隔
    mode    exclusive   # 表示同一時刻只有一個主庫提供服務
</role>

# 配置負責讀操作的庫
<role reader>
    hosts   db1, db2, db3  # 指定可讀的庫
    ips     192.168.190.91,192.168.190.92,192.168.190.93  # 配置讀虛擬IP
    mode    balanced  # 表示將讀請求負載均衡到以上所配置的db上
</role>

其他三個節點也按照相同的方式進行配置即可,除了網卡名稱可能會不同外,其它的參數都應該是一致的。

6、然後配置各個節點的mmm_agent.conf文件,聲明當前節點在host標籤中所定義的名稱。master-01節點的配置如下:

[root@master-01 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1

master-02節點的配置如下:

[root@master-02 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1

slave-01節點的配置如下:

[root@slave-01 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db3

7、接着配置監控節點上的mmm_mon.conf文件,配置內容如下:

[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  # 配置集羣中各個節點的IP
    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>
    # 配置用於監控的MySQL用戶和密碼
    monitor_user        mmm_monitor
    monitor_password    Abc_123456
</host>

debug 0

8、啓動所有主從節點的MMM代理服務:

[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服務默認會監聽9989端口,如果開啓了防火牆則需要開放該端口:

firewall-cmd --zone=public --add-port=9989/tcp --permanent
firewall-cmd --reload

9、啓動監控節點上的監控服務:

[root@manager ~]# systemctl start mysql-mmm-monitor

10、完成以上所有步驟後,在監控節點上使用mmm_control show命令就可以查看到集羣中各個節點的狀態及其分配的虛擬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 ~]#

測試

到此爲止,我們就已經完成了MMM高可用架構的搭建,接下來我們對其進行一些簡單的測試。例如,測試下是否能正常ping通虛擬IP,畢竟應用端訪問數據庫時連接的是虛擬IP,所以首先得確保虛擬IP是能夠被訪問的。如下:
基於MMM搭建MySQL Replication集羣高可用架構

ping通之後,使用Navicat等遠程連接工具測試下能否正常連接上:
基於MMM搭建MySQL Replication集羣高可用架構

確定了各個虛擬IP都能正常訪問後,測試下MMM是否能正常進行故障轉移,首先將master-01上的MySQL服務給停掉:

[root@master-01 ~]# systemctl stop mysqld

正常情況下,此時到監控節點上使用mmm_control show命令可以看到master-01節點已經處於脫機狀態,而用於寫的虛擬IP正常的切換到了master-02節點上:

[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 ~]# 

接着進入slave-01節點上的MySQL終端。之前我們配置slave-01的主庫是master-01,現在已經將master-01停掉後,可以看到slave-01的主庫被MMM切換成了master-02
基於MMM搭建MySQL Replication集羣高可用架構

經過以上測試後,可以看到我們搭建的MMM架構是能夠正常運行的,已經使得Replication集羣擁有了基本的高可用能力,即便主庫下線後也能正常切換到備庫上,也正確建立了從庫與新主庫的關係。


MMM架構的優缺點

優點:

  • 使用Perl腳本語言開發並且完全開源,開發者可以根據自己的需求進行二次開發
  • 提供了從服務器的延遲監控以及讀寫VIP(虛擬IP),使服務器角色的變更對前端應用透明。並且在從庫出現大量的主從延遲或主從複製鏈路中斷時,可以把這臺從庫上的讀虛擬IP,漂移到集羣中其他正常的可讀節點上
  • 提供了當主庫故障轉移後,從庫對新主庫的重新同步功能,所以很容易對發生故障的主庫重新上線,讓Replication集羣具備高可用性

缺點:

  • MMM屬於一個比較老的工具了,其最後發佈的版本也是好幾年前了,所以會存在一些小bug,並且不支持MySQL 5.6+版本中新增的基於GTID的複製,只支持基於日誌點的複製
  • 沒有提供讀負載均衡的功能,需要額外引入LVS等工具來實現
  • 在進行主從切換時,容易造成數據丟失或事務的重複提交。因爲MMM不會對比多個從庫的日誌點,而是直接選擇備庫進行切換。由於Replication集羣是異步複製的,當備庫的同步延遲比較大時,可能會出現從庫的日誌點比備庫的要更新。所以當主庫意外下線時,MMM強制切換成備庫就有可能會導致數據的丟失或從庫重複提交事務
  • MMM沒有提供相關的高可用功能,所以監控節點自身存在單點故障,而Replication集羣的高可用依賴於監控節點,當監控節點掛掉Replication集羣也就不再具備高可用性了。但我們可以引入第三方工具來對監控節點做雙機熱備,例如Keepalived

綜合優缺點可以得知:MMM僅適用於對數據一致性要求不高,允許丟失少量數據的場景下,例如評論、資訊類等數據

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章