Zookeeper詳解(六):Zookeeper的應用場景

Zookeeper是一個發佈/訂閱模式的分佈式數據管理與協調框架,結合Watcher事件通知,可以搭建分佈式框架中的很多核心功能。


數據發佈和訂閱

也就是常用的配置管理,將數據信息發佈到一個或者多個ZK節點上,應用程序監聽這些節點當有數據變化時就獲取這些變化並應用到程序中,實現動態更新配置的功能。發佈訂閱中通常有推拉兩種模式,ZK採用推拉結合,客戶端註冊感興趣的節點,一旦節點發生變化服務器會發出Watcher事件通知(推),然後客戶端收到消息後主動去服務器提取變化(拉)。

這種配置管理通常應用在具有配置通用性的場景中,比如機器列表、某些參數的開關或者數據庫配置信息等。

  • 這些信息通常體量小

  • 在應用運行時會隨時調整

  • 這些應用(至少是某一組應用)都使用相同的配置

常規解決辦法是本地配置文件或者內存變量(通過JMX方式對正在運行的JAVA程序進行修改)。這些常規辦法在集羣規模較小的時候比較方便但是集羣規模一大管理就比較困難。

比如數據庫配置信息變化

  • 首先在ZK上創建一個節點叫做 /Configuration 這裏面有一個APP名稱節點表示特定APP,這個APP名稱節點下面有一個叫做 dbConfig的節點用於存儲數據庫配置信息(/Configuration-->APP1-->dbConfig)

  • 然後將配置信息寫入到這個節點(這些信息肯定是序列化後寫入的,如果在程序中不是以對象形式存在也可以不用序列化)

  • 應用程序啓動後讀取這個節點數據,然後在這個節點上註冊一個Watcher事件,當數據有變化時再次讀取該節點數據並應用到自己的程序上。


負載均衡

ZK提供的負載屬於軟負載均衡服務。通常的做法就是動態的DNS服務,如果你的機器數量比較少你可以手動在內網DNS上配置這些域名,你要知道一個域名就對應一個IP。如果集羣規模比較大手動維護這些信息相當繁瑣;另外你還可以採用HOST的方式就是在服務器上配置本地HOST把這些域名寫進去,還是一樣的問題規模小傳統方式都很好用,但是規模大尤其是有時候需要動態擴容或者縮容的時候你再去手動維護這些HOST或者DNS記錄顯然就不能滿足業務需求。

在Zookeeper中如何解決呢?下面的名稱就是名字不一定你也這樣取,畢竟節點名稱是自定義的。

  • 首先建立一個節點叫做 /DDNS 這下面包含所有應用的名字比如APP1,APP2等,每個應用名字節點下面又一個域名比如  app1.servers.abc.com這樣一個域名(/DDNS-->APP1-->app1.servers.abc.com)後面這個域名就是改APP1集羣使用的,這個節點包含的數據可以是IP:PORT或者多個IP:PORT,看下圖

        Snip20180623_87.png

  • 應用讀取節點數據獲取IP列表,然後根據負載均衡算法找到一個IP來使用,之後註冊一個監聽事件來監聽該節點的變化

  • IP變更我們只需要在該節點進行操作就可以

上面的過程還是需要人工干預,如何改進一下呢?可以劃分幾個組件出來

  1. Register,負載域名動態註冊的服務,這個服務可以是單臺但最好是一個集羣,服務提供者通過SDK向Register註冊,也就是把服務提供者所使用域名和IP:PORT發給Register,它再獲取ZK集羣節點數據,加上本次註冊的數據,產生一個新數據更新到ZK節點上

  2. Dispatcher,負載域名解析,通過域名向該服務查詢獲取IP:PORT列表,它監聽ZK節點發生有變化之後就更新存儲在自己內存中的信息,相當於域名使用者不直接去ZK節點讀取數據。同時它還提供屏蔽功能,也就是說服務提供者都可用但是我可以設置只解析出部分服務提供者IP:PORT出來。

  3. Scanner,負載檢查維護服務狀態,它作用是檢查服務提供者的可用性,這裏採用服務提供者主動彙報自身狀態的方式,這種狀態可以包括很多信息服務是否可用、當前QPS、RT、JVM的資源狀態等。Scanner會記錄服務提供者每一次的狀態。如果一段時間後(通常爲幾秒)發現有服務提供者沒有彙報,那麼就認爲不可用,然後去更新ZK節點,把失敗的IP:PORT信息刪除。

  4. Monitor,負載監控DDNS系統本身的狀態。

  5. Controller,是一個DDNS的後臺管理端,負載管理上述組件以及必要時候的手工干預。

  6. SDK,服務提供者和消費者通過封裝的SDK來和上述組件通信。


命名服務

命名服務是分佈式系統中的基本功能之一。被命名的實體通常可以是集羣中的機器、提供的服務地址或者遠程對象,這些都可以稱作爲名字。常見的就是一些分佈式服務框架(RPC、RMI)中的服務地址列表,通過使用名稱服務客戶端可以獲取資源的實體、服務地址和提供者信息。命名服務就是通過一個資源引用的方式來實現對資源的定位和使用。在分佈式環境中,上層應用僅僅需要一個全局唯一名稱,就像數據庫中的主鍵。

在單庫單表系統中可以通過自增ID來標識每一條記錄,但是隨着規模變大分庫分表很常見,那麼自增ID有僅能針對單一表生成ID,所以在這種情況下無法依靠這個來標識唯一ID。UUID就是一種唯一識別碼在分佈式中也會用到,最典型的GUID,全局唯一標識符。但是長度過長不易識別。

在Zookeeper中通過創建順序節點就可以實現。你創建的時候只需要提供節點名稱,至於序號它自己會返回一個。你每次使用的語句是相同的,但是由於順序節點的特性它返回的內容不同但是是有順序的。那麼你通過  type1-job00000000 這種就可以得到一個唯一ID。

Snip20180623_88.png


分佈式協調/通知


集羣管理

集羣管理包括集羣監控和集羣控制。前者側重收集集羣運行狀態,後者側重對進行的操作和控制。場景的需求是

  • 獲取當前集羣有多少機器

  • 每個機器運行的狀態

  • 對集羣機器上下線操作

在傳統方式中通常使用Agent,Agent收集服務器信息向監控中心上報。在小規模環境中這種方式還比較適用。但是集羣規模變大問題也就來了。

  • 大規模升級Agent困難,升級成本和進度

  • 統一的Agent無法滿足多樣要求,對硬件資源比較好辦,但是如果涉及到對程序內部的監控Agent就容易束手無策了,這種東西不適合用一個統一的Agent來監控

  • 編程語言多樣,你需要提供各種語言版本的Agent

通過Zookeeper怎麼解決?利用節點監聽和臨時節點特性。


Master選舉

簡單來說就是爭搶Zookeeper上個一個節點且這個節點只能被一個機器爭搶到,其他沒有搶到的就在這個節點上註冊監聽變化。


分佈式鎖服務



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章