keepalived+mysql雙主
keepalived+mysql雙主原理:
(1)主庫1上的keepalived啟動之後,會檢查mysql服務是否活著,如果活著,keepalived進入master狀態,獲得VIP;
(2)主庫2上的keepalived啟動之後,也會檢查mysql是否活著,然後檢查keepalived組內是否有master狀態,如果有,則主庫2上的keepalived進入backup狀態,處於隨時接管VIP狀態;
(3)如果主庫1上的mysql掛了,keepalived進入fault狀態,釋放VIP,主庫2上的keepalived會變成master狀態,獲得VIP;
實驗環境:
OS:CentOS release 6.6 (Final)
數據庫:mysql 5.7.14
A: master :192.168.91.23
B: slave :192.168.91.22
VIP:192.168.91.100
操作系統時間一致更改:
date -s "20170227 16:25"
hwclock --systohc
主從參數:
A:
server_id = 330623
gtid_mode=ON
log_slave_updates = 0
enforce_gtid_consistency = ON
auto_increment_offset =1
auto_increment_increment =2
B:
server_id = 330622
gtid_mode=ON
log_slave_updates = 0
enforce_gtid_consistency = ON
auto_increment_offset=2
auto_increment_increment=2
配置AB互為主從:
A:
創建復制賬戶:
create user [email protected]%‘ identified by ‘147258‘;
grant replication slave on *.* to [email protected]%‘;
把A做個全備,還原到B上(這裏省略不寫)
B:添加A為B的主庫:
change master to master_host=‘192.168.91.23‘, master_port=3306, master_user=‘rep‘,master_password=‘147258‘, master_auto_position=1;
start slave;
A:添加B為A的主庫:
change master to master_host=‘192.168.91.22‘, master_port=3306, master_user=‘rep‘,master_password=‘147258‘, master_auto_position=1;
start slave;
創建一個監控賬戶:(後面checkMySQL.py 腳本會用到,用於檢測mysql數據庫狀態,這個用戶只要有usage權限即可)
GRANT REPLICATION CLIENT ON *.* TO [email protected]%‘ IDENTIFIED BY ‘m0n1tor‘;
A和B都要安裝keepalived軟件:
yum install keepalived -y
yum install MySQL-python -y
A的keepalived配置文件:
[[email protected] keepalived]#cat << EOF > keepalived.conf
vrrp_script vs_mysql_23 { #可以根據實際情況命名
script "/etc/keepalived/checkMySQL.py -h 192.168.91.23 -P 3306"
interval 60 #切換時間
}
vrrp_instance VI_23 { #可以根據實際情況命名
state BACKUP #剛開始時使其處於backup狀態
nopreempt #設置為不搶占,m1掛了,m2接管VIP,m1重啟不會自動搶回VIP
interface eth0 #VIP用的網卡
virtual_router_id 23 #路由id,範圍是0-255,不能和路由器高可用的id一樣,同一集群中該數值要相同
priority 100 #優先級,同一個vrrp_instance的MASTER優先級必須比BACKUP高。
advert_int 5
authentication {
auth_type PASS #認證加密
auth_pass 1111 # 認證密碼,但密碼不要超過 8 位
}
track_script {
vs_mysql_23 #調用這個腳本,返回0就持有VIP,返回1就釋放VIP
}
virtual_ipaddress {
192.168.11.100 #VIP地址
}
}
EOF
B配置文件:
[[email protected] keepalived]# cat << EOF > keepalived.conf
vrrp_script vs_mysql_22 {
script "/etc/keepalived/checkMySQL.py -h 192.168.91.22 -P 3306" #此處和A不同,其他都相同
interval 60
}
vrrp_instance VI_22 {
state BACKUP
nopreempt
interface eth0
virtual_router_id 23
priority 90
advert_int 5
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
vs_mysql_22
}
virtual_ipaddress {
192.168.91.100
}
}
EOF
checkMySQL.py腳本作用(這裏省略不寫):
腳本的作用是判斷mysql進程是否存在,如果存在返回0,如果不存在返回1;
A和B啟用keepalived
/etc/init.d/keepalived start (開始開的時候,A和B誰先啟動,VIP就先在誰上)
chkconfig –level 2345 keepalived on
keepalived啟動過程:
此時A開啟keepalived服務:
[[email protected] ~]# /etc/init.d/keepalived start
[[email protected] ~]# tail -f /var/log/messages
May 9 14:41:05 Darren1 Keepalived[28172]: Starting Keepalived v1.2.13 (03/19,2015)
May 9 14:41:05 Darren1 Keepalived[28173]: Starting Healthcheck child process, pid=28175
May 9 14:41:05 Darren1 Keepalived[28173]: Starting VRRP child process, pid=28176
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: Netlink reflector reports IP 192.168.91.23 added
May 9 14:41:05 Darren1 Keepalived_healthcheckers[28175]: Netlink reflector reports IP 192.168.91.23 added
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: Netlink reflector reports IP fe80::20c:29ff:fe56:5380 added
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: Registering Kernel netlink reflector
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: Registering Kernel netlink command channel
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: Registering gratuitous ARP shared channel
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: Opening file ‘/etc/keepalived/keepalived.conf‘.
May 9 14:41:05 Darren1 Keepalived_healthcheckers[28175]: Netlink reflector reports IP fe80::20c:29ff:fe56:5380 added
May 9 14:41:05 Darren1 Keepalived_healthcheckers[28175]: Registering Kernel netlink reflector
May 9 14:41:05 Darren1 Keepalived_healthcheckers[28175]: Registering Kernel netlink command channel
May 9 14:41:05 Darren1 Keepalived_healthcheckers[28175]: Opening file ‘/etc/keepalived/keepalived.conf‘.
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: Configuration is using : 62873 Bytes
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: Using LinkWatch kernel netlink reflector...
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) Entering BACKUP STATE
May 9 14:41:05 Darren1 Keepalived_healthcheckers[28175]: Configuration is using : 5173 Bytes
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
May 9 14:41:05 Darren1 Keepalived_healthcheckers[28175]: Using LinkWatch kernel netlink reflector...
May 9 14:41:05 Darren1 Keepalived_vrrp[28176]: VRRP_Script(vs_mysql_23) succeeded
May 9 14:41:21 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) Transition to MASTER STATE
May 9 14:41:26 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) Entering MASTER STATE
May 9 14:41:26 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) setting protocol VIPs.
May 9 14:41:26 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) Sending gratuitous ARPs on eth0 for 192.168.91.100
May 9 14:41:26 Darren1 Keepalived_healthcheckers[28175]: Netlink reflector reports IP 192.168.91.100 added
May 9 14:41:31 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) Sending gratuitous ARPs on eth0 for 192.168.91.100
總結啟動過程:
(1)啟動keepalived三個進程,分別是主進程,健康檢查子進程,VRRP協議子進程;
(2)啟動結束後,VRRP_Instance開始進入backup狀態;
(3)進入backup成功後,VRRP_Instance轉變狀態為master,然後進入master狀態;
(4)獲取VIP,並且用ARP廣播告訴其他服務器;
keepalived切換過程:
停止A的mysql服務:
[[email protected] ~]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS!
此時A的變化:
[[email protected] ~]# tail -f /var/log/messages
May 9 14:43:25 Darren1 Keepalived_vrrp[28176]: VRRP_Script(vs_mysql_23) failed
May 9 14:43:26 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) Entering FAULT STATE
May 9 14:43:26 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) removing protocol VIPs.
May 9 14:43:26 Darren1 Keepalived_vrrp[28176]: VRRP_Instance(VI_23) Now in FAULT state
May 9 14:43:26 Darren1 Keepalived_healthcheckers[28175]: Netlink reflector reports IP 192.168.91.100 removed
總結A的變化:VRRP_Instance進入fault狀態,釋放VIP;
此時B的變化:
[[email protected] ~]# tail -f /var/log/messages
May 9 14:43:26 Darren2 Keepalived_vrrp[35138]: VRRP_Instance(VI_22) Transition to MASTER STATE
May 9 14:43:31 Darren2 Keepalived_vrrp[35138]: VRRP_Instance(VI_22) Entering MASTER STATE
May 9 14:43:31 Darren2 Keepalived_vrrp[35138]: VRRP_Instance(VI_22) setting protocol VIPs.
May 9 14:43:31 Darren2 Keepalived_vrrp[35138]: VRRP_Instance(VI_22) Sending gratuitous ARPs on eth0 for 192.168.91.100
May 9 14:43:31 Darren2 Keepalived_healthcheckers[35137]: Netlink reflector reports IP 192.168.91.100 added
May 9 14:43:36 Darren2 Keepalived_vrrp[35138]: VRRP_Instance(VI_22) Sending gratuitous ARPs on eth0 for 192.168.91.100
總結B的變化:VRRP_Instance進入master狀態,獲得VIP,ARP廣播通知;
使用VIP登陸數據庫:
創建登陸用戶:
create user [email protected]%‘ identified by ‘147258‘;
grant all on *.* to [email protected]%‘;
此時VIP在B上:
[[email protected] ~]# ip addr |grep 192
inet 192.168.91.22/24 brd 192.168.91.255 scope global eth0
inet 192.168.91.100/32 scope global eth0
[email protected]%‘賬戶登陸,是可以登陸成功的,證明此VIP是有效的:
[[email protected] ~]# mysql -ukeepalived -p147258 -h192.168.91.100
[email protected] [(none)]>select user(),current_user();
+--------------------------+----------------+
| user() | current_user() |
+--------------------------+----------------+
| [email protected] | keepalived@% |
+--------------------------+----------------+
總結:
幾種VIP切換情況:
(1)m1主機宕機,VIP會切換到m2;
(2)m1上的mysql掛了,VIP會切換到m2;
(3)m1上的keepalived服務掛了,又分為兩種情況:
/etc/init.d/keepalived stop:正常切換
kill -9 keepalived_pid:因為keepalived是直接退出,m1和m2都有VIP,但是連接時候只有一個是生效的;
(4)腦裂的情況,m1和m2都各自認為自己是master狀態,搶占VIP,VIP一會在m1上,一會在m2上;
在同一個交換機下不存在腦裂情況,這個在比較復雜的網絡環境中會發生。
可以在腳本中防範:ping一下網關,如果連網關都ping不通,vrrp_script腳本就放回1,keepalived進入fault狀態;
m1掛了,m2接管VIP,m1修復好了之後怎麽辦?
(1)如果是GTID復制直接把m1change master to m2上,如果是傳統復制,需要找到binlog位置;
(2)等待m1同步完成;
(3)啟動keepalived;
keepalived+mysql雙主缺點和對應方法:
(1)數據庫一致性難保障:
可以使用增強半同步,把主庫等待從庫回應的參數rpl_semi_sync_master_timeout 調大點,
出現master的日誌沒能實時的傳到slave上,需要手工把binlog截取出來補到從庫上;如果系統不存在了,可以通過binlog server 補日誌;
(2)需要手動把出現故障的主庫加入到原來的結構中;
本文出自 “10979687” 博客,請務必保留此出處http://10989687.blog.51cto.com/10979687/1924225
keepalived+mysql雙主