Redis中sentinel叢集的搭建和Jedis測試 圖文教程[三],redisjedis

來源:互聯網
上載者:User

Redis中sentinel叢集的搭建和Jedis測試 圖文教程[三],redisjedis

  在前兩篇Redis中sentinel叢集的搭建和Jedis測試 圖文教程[一] 和Redis中sentinel叢集的搭建和Jedis測試 圖文教程[二] 中分別簡述了Redis中sentinel叢集的搭建和Java代碼的Jedis測試。
  
  這篇主要來簡單分析一下Redis-sentinel叢集的原理,根據追蹤sentinel資訊來完成Redis-sentinel叢集測試中的詳細的原理分析。包括master-slave各個中的sentinel資訊的分析,failover過程,master宕機後的leader選舉過程等等方面深層次詳細簡述了其各個原理。

一、Redis常見HA方案

  HA(High Available,高可用性群集)機叢集系統簡稱,是保證商務持續性的有效解決方案,一般有兩個或兩個以上的節點,且分為活動節點及備用節點。通常把正在執
行業務的稱為活動節點,而作為活動節點的一個備份的則稱為備用節點。當活動節點出現問題,導致正在啟動並執行業務(任務)不能正常運行時,備用節點此時就會偵測到,並立即接續活動節點來執行業務。從而實現業務的不中斷或短暫中斷。From 百度百科.
  Redis 一般以主/從方式部署(這裡討論的應用從執行個體主要用於備份,主執行個體提供讀寫)該方式要實現 HA 主要有如下幾種方案:
  1)keepalived:通過 keepalived 的虛擬 IP,提供主從的統一訪問,在主出現問題時, 通過 keepalived 運行指令碼將從提升為主,待主恢複後先同步後自動變為主,該方案的好處是主從切換後,應用程式不需要知道(因為訪問的虛擬 IP 不變),壞處是引入 keepalived 增加部署複雜性,在有些情況下會導致資料丟失;
  2) zookeeper: 通過 zookeeper 來監控主從執行個體, 維護最新有效 IP, 應用通過 zookeeper取得 IP,對 Redis 進行訪問,該方案需要編寫大量的監控代碼;
  3)sentinel:通過 Sentinel 監控主從執行個體,自動進行故障恢複,該方案有個缺陷:因為主從執行個體地址(IP&PORT)是不同的, 當故障發生進行主從切換後, 應用程式無法知道新地址,故 在 Jedis2.2.2 中 新 增 了 對 Sentinel 的 支 持 , 應 用 通 過redis.clients.jedis.JedisSentinelPool.getResource()取得的Jedis執行個體會及時更新到新的主執行個體地址。
  下面是該方案的部署邏輯圖。

二、Redis-sentinel配置與部署

  詳情請見Redis中sentinel叢集的搭建和Jedis測試 圖文教程[一]
  由於 sentinel 伺服器已經在 redis 伺服器的環境中(redis-sentinel),我們這裡就直接使用它們(在生產環境中,sentinel 伺服器和 redis-server 伺服器一般是分離的,部署在不同的pc-server 上面,同時 sentinel 的個數和 redis-server 個數也沒聯絡,下面為了方便學習使用將3 台 sentinel 服務都放到了一台 pc 上)。
  注意: sentinel 設定檔只和預設的 master 有關係,和 slave 都沒有關係。我們上面的例子是用了 3 個 redis-server 和 3 個 redis-sentinel,其實 redis-sentinel的個數不一定要和 redis-sever 對應,1~n 個都可以。
  首先要清楚,sentinel是一個獨立於redis之外的進程,不對外提供key/value服務。在redis的安裝目錄下名稱叫 redis-sentinel 。 主要用來監控redis-server進程,進行master/slave管理,如果你的redis沒有運行在master/slave模式下,不需要設定sentinel。

三、Redis-sentinel啟動和檢測

  分別啟動 redis-server 和redis-sentinel。
  
  1)啟動 redis-0 時 redis-0 的 sentinel 控制台
  
  
  2)啟動 redis-1 時 reids-1 的 sentinel 控制台
  
  
  啟動 redis-1 時 reids-0 的 sentinel 控制台
  
  
  3)啟動 redis-2 時 reids-2 的 sentinel 控制台
  
  
  啟動 redis-2 時 reids-0 的 sentinel 控制台
  
  
  啟動 redis-2 時 reids-1 的 sentinel 控制台
  

  通過上的控制輸出資訊可以看出,在依次啟動服務時,對用控制台輸出了+sentinel、+slave、-sdown 等資訊,說明各個 sentinel 之間進行了通訊,而且也監控到了 redis-server 的情況。+sentinel 表示有新的 sentinel 執行個體加入到監控。提示:首次構建 sentinel 環境時,必須首先啟動 master 機器。
  
  4)查看相關資訊
  使用 # netstat -ntlp | grep redis 命令可以看到當前 redis 運行情況。
  
  
  通過 redis-cli 查看 redis-server 的狀態

/usr/local/webserver/redis/redis-cli -h 127.0.0.1 -p 6379 -a abcd123457 info Replication

  (上面的 -a 用來輸入密碼)
  

說明:info 指令
  該指令將會列印完整的服務資訊,包括叢集,我們只需要關注”Replication”部分(在上面的命令中,我們在 info 後面加上了 Replication 的限制,如果不加,這還會輸出 Server、Clients、Memory、Persistence、Stats、CPU 和 Keyspace 等資訊),這部分資訊將會告訴我們”當前 server 的角色”以及指向它的所有的 slave 資訊。可以通過在任何一個 slave 上,使用”INFO”指令獲得當前 slave 所指向的 master 資訊。下面是 slave1 的 Replication 資訊。
   
  
  同時,該指令不僅可以協助我們獲得叢集的情況,當然 sentinel 組件也是使用”INFO”做同樣的事情。下面是 slave2 的 sentinel 資訊。
   
  
  通過上面資訊,可以清楚看到 redis 服務狀態和主從關係。 
 
  5)failover 測試
  當上述部署環境穩定後,我們直接關閉 redis-0,在等待”down-after-milliseconds”秒之後(30 秒),redis-0/redis-1/redis-2 的 sentinel 視窗會立即列印”+sdown”、”+odown”、”+failover”、”+selected-slave”、 “+promoted-slave”、 “+slave-reconf”等等一系列指令, 這些指令標明當 master失效後,sentinel 組件進行 failover 的過程。
  類比 mater 宕機的情況。此時各 sentinel 控制台輸出如下資訊。
  
  redis-0 上的 sentinel 資訊.
   

  redis-1 上的 sentinel 資訊
  
  
  redis-2 上的 sentinel 資訊
  

  從上面三個視窗的資訊可以看出, 當 master 宕機後, 三個 sentinel(哨兵)進行了對 master進行了容錯移轉。

{從 redis-1 的 sentinel 控制台可以看出,進行了下面的操作。a.+sdown mater mymaster 127.0.0.1 6379 (主觀認為 mater 失效);b.+odown mater mymaster 127.0.0.1 6379 #quorum 2/2(已經有兩個哨兵認為 master 主觀失效,則認為 mater 客觀失效);c.+new-epoch 1(準備進行新 mater 的選取);d.+try-failover master mymaster 127.0.0.1 6379(嘗試熱備份切換,master 讓出位置);e.+vote-for-leader 1eb0f03b7a7815c3c5506b0fa041ad8d6ca9db90 1(投票選舉 Leader);f.127.0.0.1:16379 voted for 1eb0f03b7a7815c3c5506b0fa041ad8d6ca9db90 1(投票選舉Leader);g.127.0.0.1:36379 voted for 1eb0f03b7a7815c3c5506b0fa041ad8d6ca9db90 1(投票選舉Leader);h.+elected-leader master mymaster 127.0.0.1 6379(之前被選舉出來的 master);i.+failover-state-select-slave master mymaster 127.0.0.1 6379(Leader 開始尋找合適的slave);j.+selected-slave slave 127.0.0.1:63792 127.0.0.1 63792 @ mymaster 127.0.0.1 6379 (leader已經找到合適的 slave);k.+failover-state-send-slaveof-noone slave 127.0.0.1:63792 127.0.0.1 63792 @ mymaster 127.0.0.1 6379(Leader 向 slave 發送“slaveof no one”指令,此時 slave 已經完成角色轉換,此 slave 即為 master);l.+failover-state-wait-promotion slave 127.0.0.1:63792 127.0.0.1 63792 @ mymaster 127.0.0.1 6379(等待其他 sentinel 確認 slave);m.+promoted-slave slave 127.0.0.1:63792 127.0.0.1 63792 @ mymaster 127.0.0.1 6379(確認成功);n.+failover-state-reconf-slaves master mymaster 127.0.0.1 6379 (開始對slaves進行reconfig 操作);o.+slave-reconf-sent slave 127.0.0.1:63791 127.0.0.1 63791 @ mymaster 127.0.0.1 6379 (向指定的 slave 發送“slaveof”指令,告知此 slave 跟隨新的 master);p. +slave-reconf-inprog slave 127.0.0.1:63791 127.0.0.1 63791 @ mymaster 127.0.0.1 6379(此 slave 正在執行 slaveof + SYNC 過程,如過 slave 收到“+slave-reconf-sent”之後將會執行 slaveof 操作,迴圈 n);q.+slave-reconf-done slave 127.0.0.1:63791 127.0.0.1 63791 @ mymaster 127.0.0.1 6379(此 slave 同步完成,此後 leader 可以繼續下一個 slave 的 reconfig 操作);r.+failover-end master mymaster 127.0.0.1 6379(容錯移轉結束);s.+switch-master mymaster 127.0.0.1 6379 127.0.0.1 63792(容錯移轉成功後,各個sentinel 執行個體開始監控新的 master);t.+slave slave 127.0.0.1:63791 127.0.0.1 63791 @ mymaster 127.0.0.1 63792(下面幾步在給新的 master 加入 slave);u.+slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 63792;v.+sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 63792。

  當環境穩定後,我們發現,redis-2 被提升(“promoted”)為 master,且 redis-1 也通過”slave-reconf”過程之後跟隨了 redis-2。
如果此時 redis-0 伺服器恢複正常, sentinel 會自動將 redis-0 作為 slave 加入到 redis-2 中。
  下面是 redis-0 的 sentinel 控制台輸出的資訊。
  
  
  再次查看 redis-2(當前 master 的 info)
  

  提示:sentinel 執行個體需要全程處於啟動狀態,如果只啟動 server 而不啟動相應的 sentinel,仍然不能確保 server 能夠正確的被監控和管理。

四、Redis-sentinel原理分析

1)SDOWN 和 ODOWN 轉換過程
【名詞解釋】
  SDOWN:subjectively down,直接翻譯的為”主觀”失效,即當前 sentinel 執行個體認為某個redis 服務為”不可用”狀態。
  ODOWN:objectively down,直接翻譯為”客觀”失效,即多個 sentinel 執行個體都認為 master處於”SDOWN”狀態,那麼此時 master 將處於 ODOWN,ODOWN 可以簡單理解為 master已經被叢集確定為”不可用”,將會開啟 failover。
  ( SDOWN 適合於 master 和 slave,但是 ODOWN 只會使用於 master;當 slave 失效超過”down-after-milliseconds”後,那麼所有 sentinel 執行個體都會將其標記為”SDOWN”。)

【轉換過程】
  a.每個 sentinel 執行個體在啟動後,都會和已知的 slaves/master 以及其他 sentinels 建立 TCP串連,並周期性發送 PING(預設為 1 秒);
  b.在互動中,如果 redis-server 無法在”down-after-milliseconds”時間內響應或者響應錯誤資訊,都會被認為此 redis-server 處於 SDOWN 狀態;
  c.如果 b.中 SDOWN 的 server 為 master, 那麼此時 sentinel 執行個體將會向其他 sentinel 間歇性(一秒)發送”is-master-down-by-addr “指令並擷取響應資訊, 如果足夠多的 sentinel 執行個體檢測到 master 處於 SDOWN,那麼此時當前 sentinel 執行個體標記 master 為 ODOWN…其他 sentinel執行個體做同樣的互動操作.配置項”sentinel monitor “,如果檢測到 master 處於 SDOWN 狀態的slave 個數達到,那麼此時此 sentinel 執行個體將會認為 master 處於 ODOWN;
  d.每個 sentinel 執行個體將會間歇性(10 秒)向 master 和 slaves 發送”INFO”指令,如果 master失效且沒有新 master 選出時,每 1 秒發送一次”INFO”;”INFO”的主要目的就是擷取並確認當前叢集環境中 slaves 和 master 的存活情況;
  經過上述過程後,所有的 sentinel 對 master 失效達成一致後,開始 failover。

2) Sentinel 與 slaves”自動探索”機制
  在 sentinel 的設定檔中(local-sentinel.conf),都指定了 port,此 port 就是 sentinel 執行個體偵聽其他 sentinel 執行個體建立連結的連接埠.在叢集穩定後,最終會每個 sentinel 執行個體之間都會建立一個 tcp 連結,此連結中發送”PING”以及類似於”is-master-down-by-addr”指令集,可用用來檢測其他 sentinel 執行個體的有效性以及”ODOWN”和”failover”過程中資訊的互動。
  在 sentinel 之間建立串連之前,sentinel 將會儘力和設定檔中指定的 master 建立串連。sentinel 與 master 的串連中的通訊主要是基於 pub/sub 來發布和接收資訊,發布的資訊內容包括當前 sentinel 執行個體的偵聽連接埠。

3)Leader 選舉
  其實在 sentinels 容錯移轉中,仍然需要一個“Leader”來調度整個過程:master 的選舉以及 slave 的重配置和同步。當叢集中有多個 sentinel 執行個體時,如何選舉其中一個 sentinel 為leader 呢?
  
  redis2.8.7的選舉有兩個條件,首先是要下面的條件過濾掉一些節點

  • 使用如下條件式篩選備選node:
    1、slave節點狀態處於S_DOWN,O_DOWN,DISCONNECTED的除外
    2、最近一次ping應答時間不超過5倍ping的間隔(假如ping的間隔為1秒,則最近一次應答延遲不應超過5秒,redis sentinel預設為1秒)
    3、info_refresh應答不超過3倍info_refresh的間隔(原理同2,redis sentinel預設為10秒)
    4、slave節點與master節點失去聯絡的時間不能超過( (now - master->s_down_since_time) + (master->down_after_period * 10))。總體意思是說,slave節點與master同步太不及時的(比如新啟動的節點),不應該參與被選舉。
    5、Slave priority不等於0(這個是在設定檔中指定,預設配置為100)。
  • 從備選node中,按照如下順序選擇新的master
    1、較低的slave_priority(這個是在設定檔中指定,預設配置為100)
    2、較大的replication offset(每個slave在與master同步後offset自動增加)
    3、較小的runid(每個redis執行個體,都會有一個runid,通常是一個40位的隨機字串,在redis啟動時設定,重複機率非常小)
    4、如果以上條件都不足以區別出唯一的節點,則會看哪個slave節點處理之前master發送的command多,就選誰。

我們期望有足夠多的sentinel執行個體, 這樣能夠確保當leader失效時, 能夠選舉某個sentinel為 leader,以便進行 failover。如果 leader 無法產生,比如較少的 sentinels 執行個體有效,那麼failover 過程將無法繼續。

4)failover 過程
  在 Leader 觸發 failover 之前,首先 wait 數秒(隨即 0~5),以便讓其他 sentinel 執行個體準備和調整,如果一切正常,那麼 leader 就需要開始將一個 salve 提升為 master,此 slave 必須為狀態良好(不能處於 SDOWN/ODOWN 狀態)且權重值最低(redis.conf 中)的, 當 master 身份被確認後,開始 failover。

五、Redis-sentinel學習總結

  1)redis 的水平擴充。 前文所實現的是 redis 的主從 HA 叢集 (從伺服器做備份而存在) ,試想當緩衝到了一個層級一台伺服器已經不能滿足了,就想到了 redis 的分布式,將緩衝放到分配到多台伺服器中。Redis 官方也提供了 redis cluster 來實現分布式,但目還沒有正式版發布(redis 3.0貌似提供了支援,還沒來得及研究)。Java 可以通過 jedis 的 ShardedJedis 來做分區 。
  2)redis 的監控。一個東西啟動並執行是否正常、穩定和效能情況,這就涉及到了對它的監控。目前 redis 的監控工具有:redmon、redis-live 等。本文暫不做監控,讀者可參考其他資料學習使用。
  3)叢集時的讀寫分離。主用來寫,從用來讀。在 redis 的 HA 叢集中,主從伺服器是變化的,這就導致在程式中,不容易獲得當前哪台服務是主,哪幾台服務是從。我們可以自己通過代碼實現獲得從伺服器的 jedis 執行個體,具體可以參見Redis中sentinel叢集的搭建和Jedis測試 圖文教程[二] 從而達到讀寫分離。
  4)“快取資料同步”也是所有緩衝工具的一個必須思考的問題。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.