1. 簡介
- MMM(Master-Master replication manager for Mysql)是一套支持雙主故障切換和雙主日常管理的腳本程序。
- MMM是使用perl語言進行開發,主要用來管理Mysql Master-Master(雙主複製)。
- 雙主複製:雖然是雙主,但業務上只能同時對一個主進行寫入,另一臺爲備選主,平時提供部分讀服務,當寫入主出現故障時,則會自動切換到這個主進行寫入。
- MMM不僅實現了,雙主故障切換的功能,內部附加組件還可以實現多個slave的read負載均衡。
- MMM提供了手動和自動兩種方式來移除一組服務器中複製延遲較高的服務器的虛擬ip。
- MMM同時可以實現數據備份的功能,實現兩節點的數據同步。
- MMM無法保證數據一致性,所以它適用於數據一致性不太嚴的場景。
- 對於要求數據一致性非常高的應用,不建議採用MMM架構。
2. 網址
- MMM項目來自於Google:http://code.google.com/p/mysql-master-master
- 官方網址爲:http://mysql-mmm.org
3. 具體配置
1. 主機角色和IP配置,這裏注意,虛擬IP儘量要和主機IP在同一個網段,不然可能會ping不通虛擬IP
角色 | IP地址 | 虛擬IP | 主機名字 | server-id | 讀寫操作 |
---|---|---|---|---|---|
monitoring | 192.168.111.128 | 192.168.111.10 | db2 | ||
master1 | 192.168.111.128 | 192.168.111.10 | db1 | 1 | write |
master2 | 192.168.111.129 | 192.168.111.20 | db2 | 2 | read |
slave1 | 192.168.111.130 | 192.168.111.30 | db3 | 3 | read |
2.主機配置,配置/etc/hosts,在所有主機中,添加所有主機信息:
root@localhost two]# cat /etc/hosts
192.168.111.128 db1
192.168.111.129 db2
192.168.111.130 db3
[root@localhost two]#
3. 在三臺主機上安裝mysql和主從複製,db1和db2互爲主從,db3爲db1的從
db1配置如下
[mysqld]
server-id=1
log_slave_updates=1
auto-increment-increment=2
auto-increment-offset=1
binlog-do-db=myblog
log-bin=mysql-bin
db2配置如下
[mysqld]
server-id=2
binlog-do-db=myblog
log_slave_updates=1
auto-increment-increment=2
auto-increment-offset=2
log-bin=mysql-bin
db3配置如下:
[mysqld]
server-id=3
4. 安裝MMM所需要的perl模塊,所有的主機都要安裝,命令如下
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum -y install mysql-mmm*
5. 下載mysql-mmm軟裝,在所有主機上安裝,在所有主機上執行如下命令
wget http://mysql-mmm.org/_media/:mmm2:mysql-mmm-2.2.1.tar.gz
mv :mmm2:mysql-mmm-2.2.1.tar.gz mysql-mmm-2.2.1.tar.gz
tar xf mysql-mmm-2.2.1.tar.gz
cd mysql-mmm-2.2.1
make install
6. 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了,其中mmm_common.conf和mmm_agent.conf爲agent端的配置文件。
mmm_mon.conf爲monitor端的配置文件。
7. 配置agent端的配置文件,要在db1,db2,db3分別配置。
在db1上配置agent配置文件如下:
[root@localhost sbin]# cd /etc/mysql-mmm
[root@localhost mysql-mmm]# cat mmm_common.conf
active_master_role writer
<host default>
cluster_interface eth0
pid_path /var/run/mmm_agentd.pid
bin_path /usr/lib/mysql-mmm/
replication_user repl
replication_password 123456
agent_user mmm_agent
agent_password mmm_agent
</host>
<host db1>
ip 192.168.111.128
mode master
peer db2
</host>
<host db2>
ip 192.168.111.129
mode master
peer db1
</host>
<host db3>
ip 192.168.111.130
mode slave
</host>
<role writer>
hosts db1, db2
ips 192.168.111.10
mode exclusive
</role>
<role reader>
hosts db2, db3
ips 192.168.111.20, 192.168.111.30
mode balanced
</role>
/**
replication_user : 用於檢查複製用於,
agent_user : 爲agent的用戶
mode : 標明是否爲主或者備選主,或者從庫
mode exclusive : 主爲獨佔模式,同一時刻只能有一個主
<role write> 和<role write>中
hosts:表示目前的主庫和備選主庫的真實ip或者主機名,
ips:爲對外提供的虛擬ip地址
mmm_common.conf 這個文件在db1,db2,db3中是一樣的
*/
8. 配置所有主機上的mmm_agent.conf文件
裏面要配置就一句 this db1,如果是db2主機,就改成this db2;如果是db3主機,就該成this db3;就是如此簡單。因爲這個配置文件引用了mmm_common.conf配置文件。
9. 在monitoring主機也就是db1主機上配置monitor的配置文件。
[root@localhost mysql-mmm]# cd /etc/mysql-mmm
[root@localhost mysql-mmm]# vi mmm_mon.conf
include mmm_common.conf
<monitor>
ip 127.0.0.1
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.111.128,192.168.111.129,192.168.111.130
auto_set_online 60
</monitor>
<host default>
monitor_user mmm_monitor
monitor_password mmm_monitor
</host>
debug 0
/**
ping_ips:添加真個架構被監控的主機的ip地址,
<host default> : 中配置了用於監控的用戶。
*/
10. 創建監控用戶,這裏需要創建3個監控用戶,具體描述如下:
角色 | 用戶名 | 描述 | 權限 |
---|---|---|---|
monitor user | mmm_monitor | MMM的monitor端監控所有mysql數據庫的狀態用戶 | REPLICATION CLIENT |
agent user | agent_user | 主要用於MMM客戶端用於改變master的read_only狀態的用戶 | SUPER,REPLICATION CLIENT,PROCESS |
replication | repl | 數據庫複製用戶 | REPLICATION SLAVE |
在三臺服務器進行授權,因爲主主複製已經實現(repl這個賬號已經OK),所以這裏只需要授權兩個賬號就行了。
mysql> grant super,replication client,process on *.* to 'mmm_agent'@'192.168.111.%' identified by 'mmm_agent';
Query OK, 0 rows affected (0.05 sec)
mysql> grant replication client on *.* to 'mmm_monitor'@'192.168.111.%' identified by 'mmm_monitor';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
/**
上面的sql在三臺服務器都需要執行。
如果上面沒有創建複製賬號,則下面一句也要執行:
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.111.%' IDENTIFIED BY '123456';
**/
#### 11. 在所有主機上啓動agent服務,並在manitor主機(這裏是db2)上啓動monitor程序。
[root@db1 ~]# /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@db1 ~]#
//啓動monitor程序
[root@db2 ~]# /etc/init.d/mysql-mmm-monitor start
Starting MMM Monitor Daemon: [ OK ]
[root@db2 ~]#
/**
如果這裏啓動報錯,無找不到perl,那就是沒有安裝perl,請自行安裝perl環境。
其中mysql-mmm-agent的日誌存放在/var/log/mysql-mmm/mmm_agentd.log中
monitor的日誌存放在/var/log/mysql-mmm/mmm_mond.log中,啓動過程中的有什麼問題都會記錄在日誌文件中。
**/
錯誤解決:
[root@db1 ~]# service mysql-mmm-monitor start
Daemon bin: '/usr/sbin/mmm_mond'
Daemon pid: '/var/run/mmm_mond.pid'
Starting MMM Monitor daemon: Can not 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_mond line 11.
BEGIN failed--compilation aborted at /usr/sbin/mmm_mond line 11.
failed
解決方法:
[root@db1 ~]# cpan Proc::Daemon
[root@db1 ~]# cpan Log::Log4perl
[root@db1 ~]# /etc/init.d/mysql-mmm-agent start
Daemon bin: '/usr/sbin/mmm_agentd'
Daemon pid: '/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Can't locate MMM/Agent/Agent.pm in @INC (@INC conta ins: /usr/local/lib/perl5/5.14.2/BSDPAN /usr/local/lib/perl5/site_perl/5.14.2/ma ch /usr/local/lib/perl5/site_perl/5.14.2 /usr/local/lib/perl5/5.14.2/mach /usr/l ocal/lib/perl5/5.14.2 .) at /usr/sbin/mmm_agentd line 21.
BEGIN failed--compilation aborted at /usr/sbin/mmm_agentd line 21.
解決方法:
[root@db1 ~]# cp -R ./mysql-mmm-2.2.1/lib/* /usr/local/lib/perl5/5.16.1/MMM/
如果缺少庫,則安裝相關庫:
[root@db1 ~]# 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
11. 在monitor主機上查看集羣狀態。
[root@db2 ~]# mmm_control checks all
db2 ping [last change: 2017/03/29 23:22:16] OK
db2 mysql [last change: 2017/03/29 23:22:16] OK
db2 rep_threads [last change: 2017/03/29 23:28:31] OK
db2 rep_backlog [last change: 2017/03/29 23:22:16] OK: Backlog is null
db3 ping [last change: 2017/03/29 23:22:16] OK
db3 mysql [last change: 2017/03/29 23:22:16] OK
db3 rep_threads [last change: 2017/03/29 23:22:16] OK
db3 rep_backlog [last change: 2017/03/29 23:22:16] OK: Backlog is null
db1 ping [last change: 2017/03/29 23:22:16] OK
db1 mysql [last change: 2017/03/29 23:22:16] OK
db1 rep_threads [last change: 2017/03/29 23:28:52] OK
db1 rep_backlog [last change: 2017/03/29 23:22:16] OK: Backlog is null
12. 在monitor主機上查看集羣在線狀態
[root@db2 ~]# mmm_control show
db1(192.168.111.128) master/ONLINE. Roles: reader(192.168.111.10)
db2(192.168.111.129) master/ONLINE. Roles: writer(192.168.111.20)
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.30)
故障分析:
# Warning: agent on host db3 is not reachable
這是防火牆的原因,關閉主機防火牆就行了
service iptables stop
13. 上線所有主機,master/ONLINE,slave/ONLINE代表已上線,如果未上線,可以使用如下命令上線主機:
[root@db2 ~]# mmm_control set_online db1
OK: This host is already ONLINE. Skipping command. // 提示一上線,跳過命令執行。
到這裏整個集羣就已經配置完成了,從輸出可以看出
db1的真實IP爲192.168.111.128,對外通過虛擬IP(192.168.0.10)提供讀服務,其他的同樣
同時,db1和db2互爲主從,db3位從服務器
14. MMM高可用測試
1.首先查看集羣狀態
[root@db2 ~]# mmm_control show
db1(192.168.111.128) master/ONLINE. Roles: reader(192.168.111.10)
db2(192.168.111.129) master/ONLINE. Roles: writer(192.168.111.20)
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.30)
// 一切正常
- 手動停止db2的mysql服務
[root@db2 ~]# service mysqld stop;
Stopping mysqld: [ OK ]
- 再來查看集羣狀態
// 由此可見MMM不能時時監控,會出現延遲
[root@db2 ~]# mmm_control show
db1(192.168.111.128) master/ONLINE. Roles: reader(192.168.111.10)
db2(192.168.111.129) master/ONLINE. Roles: writer(192.168.111.20)
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.30)
// 由此可見,當db2宕機後,MMM會把虛擬寫IP(192.168.111.20)綁定到db1上。
[root@db2 ~]# mmm_control show
db1(192.168.111.128) master/ONLINE. Roles: reader(192.168.111.30), writer(192.168.111.20)
db2(192.168.111.129) master/HARD_OFFLINE. Roles:
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.10)
- 啓動db2的mysql服務
[root@db2 ~]# service mysqld start
Starting mysqld: [ OK ]
- 再來查看集羣狀態
// mysql服務啓動後db2在AWAITING_RECOVERY(等待恢復)的時間有點長,差不多有半分鐘到一分鐘。
[root@db2 ~]# mmm_control show
db1(192.168.111.128) master/ONLINE. Roles: reader(192.168.111.30), writer(192.168.111.20)
db2(192.168.111.129) master/AWAITING_RECOVERY. Roles:
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.10)
// 當db2狀態爲online後,並不會自動回覆寫服務。而是出於閒置狀態,當然由於db2和db1互爲主從,
// 所以還是能同步db1,在它宕機期間修改的數據的。
[root@db2 ~]# mmm_control show
db1(192.168.111.128) master/ONLINE. Roles: reader(192.168.111.30), writer(192.168.111.20)
db2(192.168.111.129) master/ONLINE. Roles:
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.10)
// 如果一臺主機mysql服務剛啓動,狀態還是AWAITING_RECOVERY(等待恢復)的時候,另一臺主機宕機了。就會出現下面這種情況
// 兩臺主服務器都不能寫入,db1是等待恢復,db2則是離線狀態,原因是在db1的狀態還沒有恢復的online的時候,db2
// 宕機了,這是db1就會報一個錯誤, Last_IO_Error: error reconnecting to master '[email protected]:3306' - retry-time: 60 retries: 86400,意思是從服務連接不到主機。
// 這個時候的集羣就處於只能讀不能寫的狀態。
// db2的mysql服務啓動後,db1的錯誤就會自動消息。但是db1和db2想要恢復的online狀態還需要一點時間。
[root@db2 ~]# mmm_control show;
db1(192.168.111.128) master/AWAITING_RECOVERY. Roles:
db2(192.168.111.129) master/HARD_OFFLINE. Roles:
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.10), reader(192.168.111.30)
// db1,db2恢復到online狀態後,MMM會自動把寫服務綁定給最先恢復的主機。
[root@db2 ~]# mmm_control show;
db1(192.168.111.128) master/AWAITING_RECOVERY. Roles:
db2(192.168.111.129) master/ONLINE. Roles: writer(192.168.111.20)
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.10), reader(192.168.111.30)
// 這種情況是,可以使用192.168.111.10訪問db1的數據庫,但是不能使用192.168.111.20訪問
// 不曉得是不是綁定兩個ip時,會有衝突
// 這種情況的話,就起不到一個住數據庫宕機,另一臺主接替寫的角色了
// 雖然MMM把192.168.111.20這個IP綁定到db1上了,但是不能連接,所以也就沒什麼用了。
[root@localhost one]# mmm_control show
db1(192.168.111.128) master/ONLINE. Roles: reader(192.168.111.10), writer(192.168.111.20)
db2(192.168.111.131) master/ONLINE. Roles:
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.30)
- 使用mmm_control手動設置主機角色
// 將寫角色設置給主機db1
[root@localhost html]# mmm_control move_role writer db2
OK: Role 'writer' has been moved from 'db2' to 'db1'. Now you can wait some time and check new roles info!
[root@localhost html]# mmm_control show
db1(192.168.111.128) master/ONLINE. Roles: reader(192.168.111.30)
db2(192.168.111.131) master/ONLINE. Roles: writer(192.168.111.20)
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.
15. 連接服務器集羣
程序裏鏈接mysql服務器集羣用的是虛擬ip,所以虛擬IP必須能ping通,ping不同代表就有問題。
如果ip ping不同有可能是沒有安裝ARP
// 安裝arp
cpan install Net::ARP
16. 奇怪現象
// 當db1,db2中的mysql都關閉時,還可以通過mysql -h192.168.111.20打開數據庫,並新增數據。
// 而且db1,db2,db3的主從同步不受影響。
// 現在192.168.111.20這個ip在db3上,明明只有讀服務,但是事實證明也可以寫數據。
// 而且叢庫上的數據,還能同步的另外兩臺主庫上
[root@localhost one]# mmm_control show
db1(192.168.111.128) master/HARD_OFFLINE. Roles:
db2(192.168.111.131) master/HARD_OFFLINE. Roles:
db3(192.168.111.130) slave/ONLINE. Roles: reader(192.168.111.10), reader(192.168.111.20)
17. 總結
MMM服務器宕機後等待恢復的時間太長,而且有時候恢復不過來,所以對於要求數據一致性比較嚴格的業務不建議使用,
MMM高可用還是可以實現的,雖然恢復時間長,但是當恢復後,宕機時修改的數據,還是會自動跟新的。