Redis開發運維實踐高可用和集群架構與實踐(四)
11.1.4 高可用和異常測試
11.1.4.1 測試環境介紹
sentinel的消息可以通過sentinel日誌(/redis/log/sentinel.log)以及sentinel:hello訂閱此頻道進行查看。
11.1.4.2 手動切換測試
集群情況,2.128為主

發起主動切換:
查看sentinel日誌:
在2.129上看,集群已經切換過來:

11.1.4.3 主實例宕測試
接上,此時master為2.129,找出redis實例的pid,然後kill:
此時查看sentinel日誌:
從日誌中可以看出已經切換到2.128,此時在2.128上看集群狀態:

目前2.128為主,2.130為從,2.129上的redis宕掉。現在重啟2.129上的redis實例,啟動後該節點會從原先的主變為從,並對2.128進行同步,最後達到同步狀態:

查看redis.conf和redis-sentinel.conf,發現都被改寫。
11.1.4.4 單從實例宕測試
接上,2.129為從,此時殺掉該進程,redis.log日誌記錄如下:
此時集群正常提供對外服務,並不影響。
11.1.4.5 雙從實例宕測試
接上,此時Master為2.128,還有一個活著的從2.130,集群狀態如下:

此時,殺掉2.130的redis實例後,集群狀態如下:

此時由於配置了最小slave個數為1,已經不滿足,因此集群變為隻讀狀態:

11.1.4.6 單sentinel宕測試
恢複集群狀態,2.128為主,2.129、2.130為從。

此時,從2.128上看sentinel狀態:

由於sentinel都是對等的,在此選擇對2.128上的sentinel進行進程宕測試:



11.1.4.7 雙sentinel宕測試
恢複集群狀態,2.128為主,2.129、2.130為從。此時,將2.128的sentinel和2.129的sentinel都宕掉。此時主從集群讀寫均正常。 在雙方sentinel宕機時,殺掉master,主從集群切換失效,原因是因為設置sentinel 的quorum為2,最少有兩個sentinel活集群才正常切換。
11.1.4.8 master所在主機整體宕測試
恢複集群狀態,2.128為主,2.129、2.130為從。此時,對2.128進行宕機測試,直接關閉電源。 主從切換至2.130,從2.129指向新的主:
sentinel日誌為:
11.1.4.9 slave所在主機整體宕測試
恢複集群狀態,2.128為主,2.129、2.130為從。此時直接關閉2.129,這時相當於一個redis slave進程和一個sentinel進程宕。主不受影響,並且感知到一個從已經宕機。
sentinel日誌記錄了此事件。
11.1.4.10 腦裂測試
恢複集群狀態,2.128為主,2.129、2.130為從。首先進行一個從網絡分離的測試:

此時集群狀態為(從master看):

此時切斷2.130這個鏈路,2.128和2.129分別為主從形成一個集群,2.130會失敗,因為沒有足夠的sentinel進行投票完成failover。剩餘集群如下:

第三台機器則為slave失敗狀態:
此時由於沒有發生切換,因此對應用沒有影響。
另一種情況,如果將主機網絡斷開,剩餘兩個從成為一個新的集群,其中一個從(2.129)成為主:

原來的主機則為沒有slave的主:

此時由於沒有可用的slave,舊主無法寫入(實際上由於網絡斷開也根本無法訪問,因此從網絡和數據庫本身都不具有可寫性):

新主從可以接受讀寫請求:

從上述兩種情況測試,此架構不會導致雙主對外服務,也不會因為網絡恢複而數據混亂。
腦裂的場景還可以進行的一個測試時多個sentinel,例如下列架構(為了便於測試在兩台機器上開多端口模擬多台機器):

這個場景配置Quorum=3. 此時切斷兩台機器的通信網絡(模擬兩個機房之間通信中斷),左邊的機器(模擬主機房)集群不會受到影響,右邊的機器(模擬災備機房)由於不夠大多數因此不會產生新的Master。
11.1.4.11 quorum測試
在一個如下的四節點環境中,

如果sentinel monitor的quorum設置為3,則宕機一台後再宕機,此時還剩餘兩台,存在兩個sentinel,兩個slave。由於quorum為3,而必須有>=max(quorum, num(sentinels)/2 +1) = max(3,2) = 3個sentinel都同意其中某一個sentinel主持failover,因此此時無sentinel可主持切換,因此測試表明,沒有新的master被選出來,此時隻能手動通過slaveof命令設置主從,並且手動切換(redis、sentinel和都應用不用重啟):
如果sentinel monitor的quorum設置為2,則宕機一台後再宕機,此時還剩餘兩台,存在兩個sentinel,兩個slave。由於quorum為2,必須有>=max(quorum, num(sentinels)/2 +1)=max(2,2) =2個的sentinel都同意其中某一個sentinel主持failover,因此此時存在sentinel可主持切換,因此測試表明,新的master被選出來。
但是設置為2有一個危險就是如果出現如下的網絡隔離狀況:

集群就會腦裂,就會出現兩個master。因此,生產上為了萬無一失,寧可犧牲掉一定的高可用容錯度也要避免腦裂。如果希望兩台宕機依然可以切換,最好的方案不是降低quorum而是增多sentinel的個數,這個建議也是antirez在stackoverflow中回答一個人的提問時給的建議(https://stackoverflow.com/questions/27605843/redis-sentinel-last-node-doesnt-become-master#)。 如下場景測試:
此時其中兩台宕機,必須有>=max(quorum, num(sentinels)/2 +1)=max(3,3) =3個的sentinel都同意其中某一個sentinel主持failover,因此此時存在sentinel可主持切換,測試結果表明此種部署方案可以正常切換。
11.1.4.12 Master hang死測試
由於我們的sentinel down-after-milliseconds為3100,即3.1s,因此在master上執行: debug sleep 3.0,係統不會切換,但是執行debug sleep 3.7或者更大的數值,係統就會判定為主sdown,進而變為odown隨後發起投票切換。很難模擬取消odown的,因為時間差很短。
11.1.4.13 附:sentinel.conf被修改後的含義
port 26379 dir "/var/lib/redis/tmp" sentinel monitor mymaster 192.168.65.128 6379 2 sentinel config-epoch mymaster 18 ###確認mymater SDOWN時長 sentinel leader-epoch mymaster 18 ###同時一時間最多18個slave可同時更新配置,建議數字不要太大,以免影響正常對外提供服務 sentinel known-slave mymaster 192.168.65.129 6379 ###已知的slave sentinel known-slave mymaster 192.168.65.130 6379 ###已知的slave sentinel known-sentinel mymaster 192.168.65.130 26379 be964e6330ee1eaa9a6b5a97417e866448c0ae40 ###已知slave的唯一id sentinel known-sentinel mymaster 192.168.65.129 26379 3e468037d5dda0bbd86adc3e47b29c04f2afe9e6 ###已知slave的唯一id sentinel current-epoch 18 ####當前可同時同步的salve數最大同步閥值
最後更新:2017-05-08 12:06:01