閱讀333 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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進行進程宕測試: 此時,本節點sentinel日誌為: 其他節點sentinel日誌為: 表示2.128上的sentnel已經宕。 此時集群讀寫正常,在一個sentinel宕機的基礎上宕master後切換正常。

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,舊主無法寫入(實際上由於網絡斷開也根本無法訪問,因此從網絡和數據庫本身都不具有可寫性):


新主從可以接受讀寫請求: 此時如果舊主的網絡恢複,由於它的epoch比較舊,因此會成為從,將部分同步(psync)網絡宕期間產生的新數據。

從上述兩種情況測試,此架構不會導致雙主對外服務,也不會因為網絡恢複而數據混亂。

腦裂的場景還可以進行的一個測試時多個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

  上一篇:go Redis開發運維實踐高可用和集群架構與實踐(五)
  下一篇:go Redis開發運維實踐高可用和集群架構與實踐(三)