1. 程式人生 > >基於zookeeper管理redis叢集,實現訊息路由(一)

基於zookeeper管理redis叢集,實現訊息路由(一)

    Redis作為時下比較常用的記憶體資料庫有其幾個優勢,效能高,穩定強,操作簡單,提供多種語言且豐富API,叢集部署簡便等。目前很多企業用Redis叢集主要用於快取資料(設定與應用與資料庫之間中間層),如TOP10排序,全域性序號生產等,能較大提升使用者響應時間。本文主要介紹如何用ZooKeeper維護Redis集群系統,已經如何實現基於Redis訂閱釋出功能實現訊息路由功能。

   ZooKeeper介紹不多說,網上資料有很多。Zookeeper有兩個重要概念就znode和Watcher,znode是一個跟Unix檔案系統路徑相似的節點,可以往這個節點儲存或獲取資料。Watcher可由使用者實現,使用者監聽znode狀態變化,如子節點增加/修改/更新事件,監聽父節點也可以監聽到子節點的變化如增加和刪除。這方便可以參考ZooKeeper官方手冊。關於ZooKeeper部署,節點數目最好是基數,原因大致如下:

    zookeeper有這樣一個特性:叢集中只要有過半的機器是正常工作的,那麼整個叢集對外就是可用的。也就是說如果有2個zookeeper,那麼只要有1個死了zookeeper就不能用了,因為1沒有過半,所以2個zookeeper的死亡容忍度為0;同理,要是有3個zookeeper,一個死了,還剩下2個正常的,過半了,所以3個zookeeper的容忍度為1;同理你多列舉幾個:2->0;3->1;4->1;5->2;6->2會發現一個規律,2n和2n-1的容忍度是一樣的,都是n-1,所以為了更加高效,不必要的多增加一個zookeeper。

    如果Redis叢集有很多,如何進行高效的管理?ZooKeeper是一個不錯的選擇。通過ZooKeeper維持一個全域性Redis執行資訊,達到監控整個叢集的目的。同時可以把Redis和ZooKeeper API進行二次開發,開發人員即可透明的訪問Redis,無需關注Redis叢集執行狀態。分兩步考慮問題:

    1.開發RedisMonitor,用於定時監控Redis叢集狀態,儲存諸如Redis Master/Slave資訊,執行狀態,資料量大小等。具體實現:

     1)主程序定期發命令檢查所有節點狀態,目前有API可以查詢到所有redis叢集狀態,再呼叫ZooKeeper API修改znode資訊

     2)znode狀態變化觸發通知和相關切換

     附件提供相關RedisMonitor和HA原始碼

     2.結合ZooKeeper和Redis API開發通用API。本篇準備論述一下如何實現基於Redis的訊息路由。由於Redis自帶訊息訂閱和釋出功能,可以說是一個很不錯的功能。釋出訂閱(pub/sub)是一種訊息通訊模式,主要的目的是解耦訊息釋出者和訊息訂閱者之間的耦合。訂閱釋出在如下場景應用廣泛,如訊息推送,訊息路由,事件驅動告警與診斷等,對於開發來說,訂閱和釋出能大大減少系統之間的耦合。在設計模式中,釋出訂閱也是一個程式設計師必須掌握的模式。釋出/訂閱模型使釋出者和訂閱者之間不需要直接通訊(如遠端介面呼叫RMI)就可保證訊息的傳送,有效解決系統間耦合問題(當然有這個中介),還有就是提供了一對一、一對多的通訊方式,比較靈活。訂閱者可以通過subscribe和psubscribe命令向Redis訂閱自己感興趣的訊息型別,Redis將訊息型別稱為通道(channel)。當釋出者通過publish命令向Redis傳送特定型別的訊息時。訂閱該訊息型別的全部client都會收到此訊息。這裡訊息的傳遞是多對多的。一個client可以訂閱多個 channel,也可以向多個channel傳送訊息。

      那麼問題來了,在一個Redis叢集中,如何對外提供可靠的訊息路由功能,既保證了可靠性有保證了負載均衡。這裡提供了一個簡單的思路,讀者可以進一步實現。訂閱者在訂閱channel時要進行相關判斷,保持當前各個Redis Server負載基本均衡(選擇一個負載最輕的server),同時,釋出責傳送時也要遵循此原則。可以採用ZooKeeper保持這些channel資訊,以及Redis負載情況等等,資訊越完善越能做出更合理的決策。還需要解決的一個問題是熱切換。當某一臺Redis叢集掛掉之後,要求能自動切換到其他Redis Server。以上操作對使用者透明。後續會補上原始碼和流程圖