工做不怎麼忙,搞點兒開發吧差點兒事,就想着弄點兒架構的事兒。正好前段時間看過關於keepalived+雙主實現高可用的文章,也剛好身邊的朋友所在的公司也部分用這個架構。沒什麼事兒就搞搞吧,正好對比下MMM、MHA、keepalived+雙主三種架構的優劣和DB維護的體驗感。簡單講講本身的用戶體驗感,就搭建難易程度講MMM的安裝包封裝好的,修改的配置文件較MHA少一些,比keepalived+雙主要稍微麻煩點兒。本着省事,維護起來省事仍是以爲MMM真的便利,黑盒操做適合我這種懶人加小白類型。mysql
某位大佬講過,若是你的公司還在用MMM和MHA,那麼你能夠考慮跳槽了。我以爲這句話頗有道理,其實並非讓咱們真的去跳槽,畢竟每一個人工做的目的,環境不同,有些架構上的事兒咱們決定不了。無法隨性而行,但不能中止探索的腳步,本過程從搭建調研/搭建過程/搭建測試/搭建總結四個方面講述我對雙主+keepalived的理解和用戶體驗感。程序員
1、搭建調研sql
傳統的高可用架構如MHA、MMM存在一些不成熟的問題,如腦裂。引入keepalived和雙主複製模式,實現高可用架構,但keepalived自己是在機器宕機時纔會實現漂移功能,咱們的目標是要MySQL實例宕機後要實現故障切換,還須要輔助的腳原本幫助keepalived來實現更靈活的漂移。shell
keepalived簡介數據庫
keepalived是集羣管理中保證集羣高可用的一個軟件解決方案,其功能相似於heartbeat,用來防止單點故障,這裏的做用我理解其實就是保證VIP的順利漂移。虛擬路由冗餘協議,能夠認爲是實現路由器高可用的協議,即將N臺提供相同功能的路由器組成一個路由器組,這個組裏面有一個master和多個backup,master上面有一個對外提供服務的vip,master會發組播(組播地址爲224.0.0.18),當backup收不到vrrp包時就認爲master宕掉了,這時就須要根據VRRP的優先級來選舉一個backup當master,這樣的話就能夠保證路由器的高可用了。bash
keepalived配置說明服務器
keepalived只有一個配置文件keepalived.conf,裏面主要包括如下幾個配置區域,分別是global_defs、vrrp_instance和virtual_server。多線程
2、搭建過程架構
搭建環境(服務器配置忽略)併發
master1:172.16.3.190/22 3309 VIP:172.16.3.123/22
1 #master1配置keepalived 2 yum install keepalived.x86_64 3 [root@172-16-3-190 we_ops_admin]# cat /etc/keepalived/keepalived.conf 4 ! Configuration File for keepalived 5 6 global_defs { 7 router_id lvs_master1 8 } 9 10 vrrp_instance VI_1 { 11 state BACKUP 12 interface eth0 13 virtual_router_id 172 14 priority 100 15 advert_int 1 16 nopreempt 17 authentication { 18 auth_type PASS 19 auth_pass 1111 20 } 21 virtual_ipaddress { 22 172.16.3.123/22 23 } 24 } 25 26 virtual_server 172.16.3.123 3309 { 27 delay_loop 6 28 lb_algo rr 29 lb_kind NAT 30 nat_mask 255.255.255.0 31 persistence_timeout 50 32 protocol TCP 33 34 real_server 172.16.3.190 3309 { 35 weight 3 36 notify_down /opt/shells/keepalived_mysql.sh 37 TCP_CHECK { 38 connect_timeout 3 39 nb_get_retry 3 40 delay_before_retry 3 41 connect_port 3309 42 } 43 } 44 } 45 46 #master2上安裝keepalived 47 yum install keepalived.x86_64 48 [root@172-16-3-189 we_ops_admin]# cat /etc/keepalived/keepalived.conf 49 ! Configuration File for keepalived 50 51 global_defs { 52 router_id lvs_master2 53 } 54 55 vrrp_instance VI_1 { 56 state BACKUP 57 interface eth0 58 virtual_router_id 172 59 priority 50 60 advert_int 1 61 # nopreempt 62 authentication { 63 auth_type PASS 64 auth_pass 1111 65 } 66 virtual_ipaddress { 67 172.16.3.123/22 68 } 69 } 70 71 virtual_server 172.16.3.123 3309 { 72 delay_loop 6 73 lb_algo rr 74 lb_kind NAT 75 nat_mask 255.255.255.0 76 persistence_timeout 50 77 protocol TCP 78 79 real_server 172.16.3.189 3309 { 80 weight 3 81 notify_down /opt/shells/keepalived_mysql.sh 82 TCP_CHECK { 83 connect_timeout 3 84 nb_get_retry 3 85 delay_before_retry 3 86 connect_port 3309 87 } 88 } 89 }
上述配置中咱們能夠保證keepalived服務對VIP:172.16.3.123/22的控制權,默認是keepalived服務關閉,那麼會觸發VIP的漂移。正常運行的服務不會發生異常中止的現象,若是系統發生宕機會觸發全部的服務中止,這裏系統宕機是觸發VIP漂移的導火索。只是這裏咱們想讓keepalived服務於MySQL複製集,那麼這裏的導火索天然而然是MySQL服務的狀態。若是服務狀態不可用,那麼咱們但願這個應用VIP能夠漂移到複製集的另外一臺機器上;若是服務狀態可用,咱們但願VIP不要漂移。要想實現這個目的,咱們還須要一個服務腳原本幫助咱們去幫助keepalived發現MySQL服務宕機後的動做,腳本以下配置。
1 [root@172-16-3-190 we_ops_admin]# cat /opt/shells/keepalived_mysql.sh 2 #!/bin/bash 3 pkill keepalived 4 /sbin/ifdown eth0 && /sbin/ifup eth0 5 #授予可執行權限 6 [root@172-16-3-190 we_ops_admin]# ls -lh /opt/shells/keepalived_mysql.sh 7 -rwxr-xr-x 1 root root 66 Sep 27 19:29 /opt/shells/keepalived_mysql.sh
經過步驟1·2的配置,啓動MySQL服務,啓動keepalived服務,這裏的master1和master2基本就能夠實現高可用,保證了master1服務不可用時,master2還能繼續提供數據庫的支持。
3、搭建測試(Bash腳本模擬高併發)
一、master1的MySQL服務宕機,VIP會從master1上摘除漂移落盤到master2上,且master1上的keepalived服務也會中止。應用鏈接VIP,master2繼續爲整個集羣提供數據庫支持。
1 #中止master1上的MySQL服務 2 [root@172-16-3-190 we_ops_admin]# /etc/init.d/mysql_3309 stop 3 Shutting down MySQL (Percona Server).. SUCCESS! 4 5 #keepalived服務也中止了,且VIP已經被從master1上摘除 6 [root@172-16-3-190 we_ops_admin]# /etc/init.d/keepalived status 7 keepalived dead but subsys locked 8 [root@172-16-3-190 we_ops_admin]# ip add 9 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 10 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 11 inet 127.0.0.1/8 scope host lo 12 inet6 ::1/128 scope host 13 valid_lft forever preferred_lft forever 14 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP qlen 1000 15 link/ether 52:54:00:f4:ec:b2 brd ff:ff:ff:ff:ff:ff 16 inet 172.16.3.190/22 brd 172.16.3.255 scope global eth0 17 inet6 fe80::5054:ff:fef4:ecb2/64 scope link 18 valid_lft forever preferred_lft forever 19 #VIP漂移到master2上 20 [root@172-16-3-189 we_ops_admin]# ip add 21 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 22 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 23 inet 127.0.0.1/8 scope host lo 24 inet6 ::1/128 scope host 25 valid_lft forever preferred_lft forever 26 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP qlen 1000 27 link/ether 52:54:00:2d:96:5c brd ff:ff:ff:ff:ff:ff 28 inet 172.16.3.189/22 brd 172.16.3.255 scope global eth0 29 inet 172.16.3.123/22 scope global secondary eth0 30 inet6 fe80::5054:ff:fe2d:965c/64 scope link 31 valid_lft forever preferred_lft forever
二、master1從新加入集羣,VIP不會從新漂移回來,形成二次波動或者腦裂現象
1 #重啓master1上的MySQL服務 2 [root@172-16-3-190 we_ops_admin]# /etc/init.d/mysql_3309 start 3 Starting MySQL (Percona Server)............... SUCCESS! 4 #重啓master1上的keepalived服務 5 [root@172-16-3-190 we_ops_admin]# /etc/init.d/keepalived start 6 Starting keepalived: [ OK ] 7 #VIP仍是在master2上,且master1上並無VIP,由於master1上設置非搶佔模式,即便優先級更高 8 [root@172-16-3-190 we_ops_admin]# ip add #master1 9 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP qlen 1000 10 link/ether 52:54:00:f4:ec:b2 brd ff:ff:ff:ff:ff:ff 11 inet 172.16.3.190/22 brd 172.16.3.255 scope global eth0 12 inet6 fe80::5054:ff:fef4:ecb2/64 scope link 13 valid_lft forever preferred_lft forever 14 15 [root@172-16-3-189 we_ops_admin]# ip add master2 16 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP qlen 1000 17 link/ether 52:54:00:2d:96:5c brd ff:ff:ff:ff:ff:ff 18 inet 172.16.3.189/22 brd 172.16.3.255 scope global eth0 19 inet 172.16.3.123/22 scope global secondary eth0 20 inet6 fe80::5054:ff:fe2d:965c/64 scope link 21 valid_lft forever preferred_lft forever
1 #關閉master2實例 2 [root@172-16-3-189 we_ops_admin]# /etc/init.d/mysql_3309 stop 3 Shutting down MySQL (Percona Server).. SUCCESS! 4 [root@172-16-3-189 we_ops_admin]# /etc/init.d/keepalived status 5 keepalived dead but subsys locked 6 #VIP已經從master2上飄走了 7 [root@172-16-3-189 we_ops_admin]# ip add 8 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP qlen 1000 9 link/ether 52:54:00:2d:96:5c brd ff:ff:ff:ff:ff:ff 10 inet 172.16.3.189/22 brd 172.16.3.255 scope global eth0 11 inet6 fe80::5054:ff:fe2d:965c/64 scope link 12 valid_lft forever preferred_lft forever 13 14 #VIP已經落盤到master1上 15 [root@172-16-3-190 we_ops_admin]# ip add 16 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP qlen 1000 17 link/ether 52:54:00:f4:ec:b2 brd ff:ff:ff:ff:ff:ff 18 inet 172.16.3.190/22 brd 172.16.3.255 scope global eth0 19 inet 172.16.3.123/22 scope global secondary eth0 20 inet6 fe80::5054:ff:fef4:ecb2/64 scope link 21 valid_lft forever preferred_lft forever 22 #server-id能夠證實鏈接到master1實例 23 [root@172-16-3-190 we_ops_admin]# /opt/app/mysql_3309/bin/mysql -urepl -prepl --socket=/opt/app/mysql_3309/tmp/mysql.sock --port=3309 --host=172.16.3.123 24 Warning: Using a password on the command line interface can be insecure. 25 Welcome to the MySQL monitor. Commands end with ; or \g. 26 Your MySQL connection id is 33 27 Server version: 5.6.20-68.0-log Percona Server (GPL), Release 68.0, Revision 656 28 29 Copyright (c) 2009-2014 Percona LLC and/or its affiliates 30 Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 31 32 Oracle is a registered trademark of Oracle Corporation and/or its 33 affiliates. Other names may be trademarks of their respective 34 owners. 35 36 Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 37 38 mysql> show global variables like '%server_id%'; 39 +----------------+---------+ 40 | Variable_name | Value | 41 +----------------+---------+ 42 | server_id | 1903309 | 43 | server_id_bits | 32 | 44 +----------------+---------+ 45 2 rows in set (0.01 sec)
1 Warning: Using a password on the command line interface can be insecure. #這個錯誤這裏測試大概會報10條 2 Warning: Using a password on the command line interface can be insecure. 3 ERROR 2003 (HY000): Can't connect to MySQL server on '172.16.3.123' (111) 4 Warning: Using a password on the command line interface can be insecure. 5 ERROR 2003 (HY000): Can't connect to MySQL server on '172.16.3.123' (111)
二、master2同步被中斷的問題,沒有等待同步完成的機制。(VIP在maste2上時,由於master2上已經寫入了數據但沒來得及同步到master1上;master2實例中止後,VIP也漂移到master1,應用鏈接master1進行寫入,但由於表設計爲主鍵自增加,會出現ID爲25已寫入master2而沒有同步到master1,應用鏈接master1寫入到數據庫同步到master2時報主鍵重複)
1 mysql> show slave status \G; 2 *************************** 1. row *************************** 3 Slave_IO_State: Waiting for master to send event 4 Master_Host: 172.16.3.190 5 Master_User: repl 6 Master_Port: 3309 7 Connect_Retry: 30 8 Master_Log_File: binlog.000036 9 Read_Master_Log_Pos: 103620 10 Relay_Log_File: relay_bin.000038 11 Relay_Log_Pos: 280 12 Relay_Master_Log_File: binlog.000036 13 Slave_IO_Running: Yes 14 Slave_SQL_Running: No 15 Replicate_Do_DB: 16 Replicate_Ignore_DB: 17 Replicate_Do_Table: 18 Replicate_Ignore_Table: 19 Replicate_Wild_Do_Table: 20 Replicate_Wild_Ignore_Table: 21 Last_Errno: 1062 22 Last_Error: Error 'Duplicate entry '25' for key 'PRIMARY'' on query. Default database: 'practice'. Query: 'insert into test_keepalived values(null,1,4)' 23 Skip_Counter: 0 24 Exec_Master_Log_Pos: 120 25 Relay_Log_Space: 104434 26 Until_Condition: None 27 Until_Log_File: 28 Until_Log_Pos: 0 29 Master_SSL_Allowed: No 30 Master_SSL_CA_File: 31 Master_SSL_CA_Path: 32 Master_SSL_Cert: 33 Master_SSL_Cipher: 34 Master_SSL_Key: 35 Seconds_Behind_Master: NULL 36 Master_SSL_Verify_Server_Cert: No 37 Last_IO_Errno: 0 38 Last_IO_Error: 39 Last_SQL_Errno: 1062 40 Last_SQL_Error: Error 'Duplicate entry '25' for key 'PRIMARY'' on query. Default database: 'practice'. Query: 'insert into test_keepalived values(null,1,4)' 41 Replicate_Ignore_Server_Ids: 42 Master_Server_Id: 1903309 43 Master_UUID: 1b589d80-f450-11e7-9150-525400f4ecb2 44 Master_Info_File: /opt/app/mysql_3309/logs/master.info 45 SQL_Delay: 0 46 SQL_Remaining_Delay: NULL 47 Slave_SQL_Running_State: 48 Master_Retry_Count: 86400 49 Master_Bind: 50 Last_IO_Error_Timestamp: 51 Last_SQL_Error_Timestamp: 180929 17:43:30 52 Master_SSL_Crl: 53 Master_SSL_Crlpath: 54 Retrieved_Gtid_Set: 55 Executed_Gtid_Set: 56 Auto_Position: 0 57 1 row in set (0.00 sec)
Keepalived+雙主架構總結