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

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


數據發佈和訂閱數據庫

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

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

  • 這些信息一般體量小app

  • 在應用運行時會隨時調整負載均衡

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

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

好比數據庫配置信息變化分佈式

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

  • 而後將配置信息寫入到這個節點(這些信息確定是序列化後寫入的,若是在程序中不是以對象形式存在也能夠不用序列化)

  • 應用程序啓動後讀取這個節點數據,而後在這個節點上註冊一個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上個一個節點且這個節點只能被一個機器爭搶到,其餘沒有搶到的就在這個節點上註冊監聽變化。


分佈式鎖服務

相關文章
相關標籤/搜索