MySQL-mmm是Multi-Master Replication Manager For MySQL的縮寫,該軟件是爲MySQL數據庫實現主主複製功能而實現的一系列腳本。
MySQL-mmm的功用:
可以實現MySQL數據庫的高可用效果,當主數據庫出現故障後,會自動切換其他主服務器,保證業務不會中斷,也能對主從數據庫服務器實現讀負載均衡,在具體的實現細節中,它可以實現一組基於複製的虛擬IP,還能有對數據備份、節點之間重新同步的功能。
MySQL-mmm的使用場景:
用戶的讀寫請求已經完成了讀寫分離,無論是前端的應用程序層面解決還是使用了MySQL語句路由,到達數據庫時,讀寫分離的工作已經完成,MySQL-MMM主要完成的是數據庫節點間工作狀態的監控及資源的流轉操作。
MySQL-mmm運行的進程:
mysql-mmm是一組腳本套件,其安裝套件中有mysql-mmm-monitor、mysql-mmm-tools、mysql-mmm-agent、mysql-mmm四部分。
monitor程序包安裝後啓動的服務用於監控在common配置文件中定義的數據庫工作狀況,通常我們使用的數據庫主服務器中有一個節點是允許寫入數據,其他的節點只能讀取數據,如果主服務器故障,監控程序會通知另外的服務器端啓動主服務器端原有的資源,並代替之前的主服務器的工作,更多的是接替了主服務器的寫入的任務。
mysql-agent程序包是安裝在各個數據庫節點上的代理程序,其主要功用在於當其他節點尤其是主節點出現故障後,其可以收到mysql-monitor進程的信息,並根據自身的配置自動修改其工作特性,比如提升自己爲主服務器,接收寫請求,或者是修改主服務器指向等。
實例:使用MySQL-mmm實現雙主模型的數據庫的高可用
使用三臺虛擬機:node1爲主服務器,接收用戶的寫操作,IP:172.16.103.2
node2爲備用主服務器,接收用戶的讀請求,IP:172.16.103.3
monitor主機爲監控用服務器,其IP:172.16.103.1
兩個主服務器使用的VIP地址爲:172.16.103.200(接收寫請求的IP)、172.16.103.201、172.16.103.202(後兩個IP接收讀請求)
實驗用簡易拓撲:
一、準備工作:
配置好/etc/hosts文件,注意配置好hosts文件很關鍵,因爲連接數據庫服務器默認使用的是第一個與IP地址匹配的主機名,這個名稱要和授權的IP地址反解出來的主機名保持一致,否則就會出現無法連接或者無法寫入的錯誤,示例:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.103.1 monitor monitor.cluster.com 172.16.103.2 node1 node1.cluster.com 172.16.103.3 node2 node2.cluster.com 172.16.0.1 server.magelinux.com server
注意:簡短的主機名放在了完整主機名的前面比如172.16.103.1 monitor monitor.cluster.com而不是習慣性的172.16.103.1 monitor.cluster.com monitor,因爲在後續的配置mmm的過程中都是使用的簡短的主機名,而我們在連接數據庫建立授權賬號的時候又往往使用的是IP地址,這些解析的對應關係一定要弄清楚,數據庫只解析第一個匹配到的主機名,注意在這裏是只解析前面的簡短的主機名,我的意思是在解析172.16.103.1時數據庫會只解析node1而不會去解析node1.cluster.com,如果完整的主機名放在了前面,那麼後續在解析時是會出問題的,也即無法連接數據庫去執行寫操作。如果覺得這樣的配置很繁瑣,就在數據庫的配置文件中mysqld字段添加skip-name-resolve一行就可以避免這些問題了。
二、在兩臺虛擬機上安裝數據庫,安裝過程未給出,請參考前面博客內容,直接給出數據庫的配置文件:
1、node1:(也只列出了需要添加或者需要留意的條目)
datadir = /mydata/data auto-increment-increment = 2 auto-increment-offset = 2 relay-log=mysql-relay relay-log-index=mysql-relay.index log-bin=mysql-bin binlog_format=mixed server-id = 1
由於兩個數據庫服務器是主主模型,都要從對方複製數據,所以都要開啓中繼日誌和二進制日誌,而且爲了避免數據出現訛誤,記錄數據時使用不同的ID,偏移位置是不同的,而且要注意服務器的ID號一定是不同的。
2、node2:
datadir = /mydata/data auto-increment-increment = 2 auto-increment-offset = 1 relay-log=mysql-relay relay-log-index=mysql-relay.index log-bin=mysql-bin server-id = 2
3、連接node1數據庫,創建授權賬號,由於兩個數據庫節點之間是複製數據的,所以可以在一個數據庫上執行授權操作,另一個數據庫只需要在指向主服務器時,指向的記錄位置在創建賬號之前就可以了。
MariaDB [(none)]> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 245 | | | +------------------+----------+--------------+------------------+
MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO repl@'172.16.%.%' IDENTIFIED BY 'repl'; MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'mmm_monitor'@'172.16.%.%' IDENTIFIED BY 'mmm_monitor'; MariaDB [(none)]> GRANT PROCESS,SUPER,REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'mmm_agent'@'172.16.%.%' IDENTIFIED BY 'mmm_agent'
4、連接node2數據庫:執行CHANGE MASTER TO操作,要注意指向的數據庫文件及pos!
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.16.103.2',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=245; MariaDB [(none)]> START SLAVE; MariaDB [(none)]> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.103.2 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 960 Relay_Log_File: mysql-relay.000002 Relay_Log_Pos: 529 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 960 Relay_Log_Space: 819 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 1 row in set (0.00 sec)
之後,查看一下node2的Pos及二進制日誌文件,以便在node1上指向到node2:
MariaDB [(none)]> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 880 | | | +------------------+---------
在node1上執行操作:
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.16.103.3',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=880; MariaDB [(none)]> START SLAVE; MariaDB [(none)]> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.103.3 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 880 Relay_Log_File: mysql-relay.000002 Relay_Log_Pos: 529 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 880 Relay_Log_Space: 819 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 2
雙主的數據庫配置完成。
三、在三臺主機上安裝mysql-mmm的程序包:
# yum install -y mysql-mmm*
1、在node1上配置:
[root@node1 ~]# cd /etc/mysql-mmm/ [root@node1 mysql-mmm]# vim mmm_agent.conf
在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 node1
編輯node1上的mmm_common.conf文件,配置內容爲:
active_master_role writer <host default> cluster_interface eth0 pid_path /var/run/mysql-mmm/mmm_agentd.pid bin_path /usr/libexec/mysql-mmm/ replication_user repl replication_password repl agent_user mmm_agent agent_password mmm_agent </host> <host node1> ip 172.16.103.2 mode master peer node2 </host> <host node2> ip 172.16.103.3 mode master peer node1 </host> <host monitor> ip 172.16.103.1 mode slave </host> <role writer> hosts node1, node2 ips 172.16.103.200 mode exclusive </role> <role reader> hosts node1, node2 ips 172.16.103.201, 172.16.103.202 mode balanced </role>
mmm_common.conf文件在各個節點上內容相同,複製到其他的節點上去即可:
# scp mmm_common.conf monitor:/etc/mysql-mmm/ # scp mmm_common.conf node2:/etc/mysql-mmm/
2、在node2上編輯配置文件,內容如下:
[root@node2 mysql-mmm]# vim /etc/mysql-mmm/mmm_agent.conf include mmm_common.conf this node2
3、在監控節點上配置
mmm_agent.conf內容爲:
[root@monitor mysql-mmm]# vim mmm_agent.conf include mmm_common.conf this monitor
include mmm_common.conf <monitor> ip 127.0.0.1 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 172.16.103.2,172.16.103.3 #這裏配置的是監控用的IP地址,但不要設置本機的IP地址,其用途是是探測本機與外部通信的 auto_set_online 10 #這個參數的默認值是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 mmm_monitor </host> debug 0
至此兩臺數據庫服務器主機以及在三臺節點上配置mmm的過程完畢,現在可以啓動數據庫及mmm服務了。
# service mysqld start
node1和node2上:
# service mysql-mmm-agent start
monitor上:
# service mysql-mmm-monitor start
在全部啓動完畢後,監控端可以查看到各數據庫的工作狀態,使用mmm_control命令查看:
[root@monitor mysql-mmm]# mmm_control show # Warning: agent on host monitor is not reachable monitor(172.16.103.1) slave/HARD_OFFLINE. Roles: node1(172.16.103.2) master/ONLINE. Roles: reader(172.16.103.201), writer(172.16.103.200) node2(172.16.103.3) master/ONLINE. Roles: reader(172.16.103.202)
在node1上查看IP地址的配置情況:
[root@node1 mysql-mmm]# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:e1:37:51 brd ff:ff:ff:ff:ff:ff inet 172.16.103.2/16 brd 172.16.255.255 scope global eth0 inet 172.16.103.201/32 scope global eth0 inet 172.16.103.200/32 scope global eth0 inet6 fe80::20c:29ff:fee1:3751/64 scope link valid_lft forever preferred_lft forever
在node2上啓動的IP爲:
[root@node2 mysql-mmm]# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:cf:64:8f brd ff:ff:ff:ff:ff:ff inet 172.16.103.3/16 brd 172.16.255.255 scope global eth0 inet 172.16.103.202/32 scope global eth0 inet6 fe80::20c:29ff:fecf:648f/64 scope link valid_lft forever preferred_lft forever
如果服務器故障了,所有配置在主服務器上的VIP都會流轉到另一個主服務器上:
[root@node2 mysql-mmm]# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:cf:64:8f brd ff:ff:ff:ff:ff:ff inet 172.16.103.3/16 brd 172.16.255.255 scope global eth0 inet 172.16.103.202/32 scope global eth0 inet 172.16.103.201/32 scope global eth0 inet 172.16.103.200/32 scope global eth0 inet6 fe80::20c:29ff:fecf:648f/64 scope link valid_lft forever preferred_lft forever
可以看到VIP 200,201,202都配置在了node2上。