ZooKeeper 入門
zookeeper,通俗的來講,他目前在各種分布式係統中充當大腦的角色,給各個應用管理配置文件,提供應用的分布式鎖,提供應用命名,提供組服務這四個功能.
1. 管理配置文件(維護配置信息)
1. zookeeper提供的這個配置管理,就是把這公用的配置文件提取出來放到一個地方,對這個地方(目錄節點)進行監聽,一旦配置信息發生變化,每個應用程序就會收到 Zookeeper 的通知,然後從 Zookeeper 獲取新的配置信息應用到係統中就好,項目不需要重啟.
2. 標準的key value的配置文件結構
3. 基於web頁麵的配置文件的增刪改查
4. 同一個app(應用)下多個配置文件
5. 版本管理,當前版本,曆史版本管理
6. 數據持久化保存
7. 非標準的key value配置文件的管理
8. 客戶端watcher的實現
2. 提供應用命名
1. 當集群的時候,相同的一個服務有很多個提供者,這些提供者啟動時,提供者服務器的相關信息,包括服務接口,地址,端口等一下連接提供者的信息注冊到zookper中,當消費者要消費某服務的時候,從zookeeper中拿改服務的所有提供者信息目錄,再根據dubbo的負載均衡機製從地圖中選擇一個提供者。
3. 分布式鎖(分布式同步)
1. 進程需要訪問共享數據時, 就在"/locks"節點下創建一個sequence類型的子節點, 稱為thisPath. 當thisPath在所有子節點中最小時, 說明該進程獲得了鎖. 進程獲得鎖之後, 就可以訪問共享資源了. 訪問完成後, 需要將thisPath刪除. 鎖由新的最小的子節點獲得.
2. 有了清晰的思路之後, 還需要補充一些細節. 進程如何知道thisPath是所有子節點中最小的呢? 可以在創建的時候, 通過getChildren方法獲取子節點列表, 然後在列表中找到排名比thisPath前1位的節點, 稱為waitPath, 然後在waitPath上注冊監聽, 當waitPath被刪除後, 進程獲得通知, 此時說明該進程獲得了鎖.
3. lock操作過程
1. 首先為一個lock場景,在zookeeper中指定對應的一個根節點,用於記錄資源競爭的內容
2. 每個lock創建後,會lazy在zookeeper中創建一個node節點,表明對應的資源競爭標識。 (小技巧:node節點為EPHEMERAL_SEQUENTIAL,自增長的臨時節點)
3. 進行lock操作時,獲取對應lock根節點下的所有字節點,也即處於競爭中的資源標識
4. 按照Fair競爭的原則,按照對應的自增內容做排序,取出編號最小的一個節點做為lock的owner,判斷自己的節點id是否就為owner id(鎖有者),如果是則返回,lock成功。
5. 如果自己非owner id,按照排序的結果找到序號比自己前一位的id,關注它鎖釋放的操作(也就是exist watcher),形成一個鏈式的觸發過程。
4. unlock操作過程
1. 將自己id對應的節點刪除即可,對應的下一個排隊的節點就可以收到Watcher事件,從而被喚醒得到鎖後退出
5. 其中的幾個關鍵點
1. node節點選擇為EPHEMERAL_SEQUENTIAL很重要
1. 自增長的特性,可以方便構建一個基於Fair特性的鎖,前一個節點喚醒後一個節點,形成一個鏈式的觸發過程。可以有效的避免"驚群效應"(一個鎖釋放,所有等待的線程都被喚醒),有針對性的喚醒,提升性能。
2. 選擇一個EPHEMERAL臨時節點的特性。因為和zookeeper交互是一個網絡操作,不可控因素過多,比如網絡斷了,上一個節點釋放鎖的操作會失敗。臨時節點是和對應的session掛接的,session一旦超時或者異常退出其節點就會消失,類似於ReentrantLock中等待隊列Thread的被中斷處理.
6. 注意
1. 使用EPHEMERAL會引出一個風險:在非正常情況下,網絡延遲比較大會出現session timeout,zookeeper就會認為該client已關閉,從而銷毀其id標示,競爭資源的下一個id就可以獲取鎖。這時可能會有兩個process同時拿到鎖在跑任務,所以設置好session timeout很重要。
2. 同樣使用PERSISTENT同樣會存在一個死鎖的風險,進程異常退出後,對應的競爭資源id一直沒有刪除,下一個id一直無法獲取到鎖對象。
4. 提供組服務
1. 服務器上的服務注冊,或者獲取服務,都是在zookeeper上操作的,所以所謂的提供組服務也就包括創建組、加入組成員、列出組成員和刪除組成員。對於這些服務,主要通過zookeeper心跳機製,它會去檢測與其連接的一些服務器的數量,以及信息。什麼時候連上zookeeper,或什麼時候斷開都有其心跳機製完成。
最後更新:2017-11-14 11:04:42