Zookeeper主要用在分佈式應用中實現一致性協調調度服務。它的命名空間相似傳統文件系統,每一個節點都以惟一的路徑進行標識,不一樣的是,每一個節點除了能夠擁有子節點外,還可擁有相對性的data數據。node
1、Zookeeper命名空間數據庫
上圖是一個典型的Zookeeper命名空間結構,經過路徑"/app1/p_1"可訪問znode1節點,每一個節點可存儲少許數據,如狀態、配置、位置信息等等,且data信息量很小,通常在byte到KB級別。節點znode維護一個狀態stat結構(包括數據變化的版本號、ACL變化、時間戳),以容許緩存驗證與協調更新。每當節點數據內容改變時,多一個版本號,相似HBase。客戶端獲取數據的同時也獲取相對應的版本號。節點數據內容以原子方式讀寫,讀操做會讀取該znode的所有data數據,一樣寫操做也會覆蓋該znode的所有data數據,不存在部分讀寫的狀況。同時,每一個節點有一個訪問控制列表ACL(Access Control List)來約束訪問操做,即具備權限控制。緩存
znode存在兩種:session
常規的znode: 由用戶顯式建立和刪除app
ephemeral znode:臨時型znode, 其生命週期伴隨於建立它的session, session結束後,ZooKeeper Server會自動刪除它,固然用戶也能夠顯式的刪除框架
2、Zookeeper的Watches異步
Zookeeper對Node的增刪改查均可觸發監聽,每一個client可對一個znode設置一個watch事件。當watch監視的數據發生變化時,會通知設置了該watch的client,即watcher。watch事件是一次性觸發器,即觸發一次就會被取消,該client若是還要監視該znode的變化,須要再次設置相應的watch事件。分佈式
注:ide
watch事件異步發送至觀察者,可能致使當兩次觸發時間間隔過短的時候,不一樣的接收者收到的事件不一致3d
watch是一次性觸發的且在獲取watch事件和設置watch事件之間有延遲,因此不能可靠的觀察到節點的每一次變化
客戶端監視一個節點,老是先獲取watch事件,再發現節點的數據變化。
watch事件的順序對應於zookeeper服務所見的數據更新順序
3、Zookeeper讀寫流程
讀請求到來時,將直接從replicated database獲取數據,replicated database是一個內存數據庫,所以讀寫效率高
寫請求到來時,全部的寫請求都會先發送給一個稱之爲leader的server,而後由該leader廣播給各個follower(server),在收到超過一半的server反饋的ack以後,認爲這次寫操做成功。同時,再寫操做更新到內存數據庫以前,會先持久化到磁盤,用於恢復。以下圖所示:
4、在dubbo中的應用
在分佈式系統中,經過使用命名服務,客戶端應用可以根據指定名字來獲取資源或服務的地址,提供者等信息。被命名的實體一般能夠是集羣中的機器,提供的服務地址,遠程對象等等——這些咱們均可以統稱他們爲名字(Name)。其中較爲常見的就是一些分佈式服務框架中的服務地址列表。經過調用ZK提供的建立節點的API,可以很容易建立一個全局惟一的path,這個path就能夠做爲一個名稱。好比dubbo應用中:
服務提供者在啓動的時候,向ZK上的指定節點/dubbo/${serviceName}/providers目錄下寫入本身的URL地址,這個操做就完成了服務的發佈。
服務消費者啓動的時候,訂閱/dubbo/${serviceName}/providers目錄下的提供者URL地址, 並向/dubbo/${serviceName} /consumers目錄下寫入本身的URL地址。
注意,全部向ZK上註冊的地址都是臨時節點,這樣就可以保證服務提供者和消費者可以自動感應資源的變化。
另外,Dubbo還有針對服務粒度的監控,方法是訂閱/dubbo/${serviceName}目錄下全部提供者和消費者的信息。