zookeeper簡介
分布式系統(tǒng)的分布式協(xié)同服務(wù),保證分布式系統(tǒng)信息的一致性。
共享方式
- 通過網(wǎng)絡(luò)進行信息共享
- 共享存儲
集群角色
leader,follower, observer
observer不參與 leader選舉,不參與寫操作的過半寫成功策略,提高集群的性能
寫請求:
- follower接收客戶端寫請求,請求轉(zhuǎn)發(fā)給 leader
- leader 收到寫請求,寫請求轉(zhuǎn)換成帶有各種狀態(tài)的事務(wù),廣播該事務(wù)(proposal)
- 所有接收到 proposal的 follower 進行投票,向 leader 返回 ACK
- leader 發(fā)送事務(wù)提交請求
會話
客戶端和服務(wù)端之間的一個TCP長連接
Znode
數(shù)據(jù)節(jié)點,保存數(shù)據(jù)內(nèi)容和屬性
- 持久性節(jié)點(Persistent)
- 臨時性節(jié)點(Ephemeral)
- 順序性節(jié)點(Sequential)
Watcher--數(shù)據(jù)變更通知
Zookeeper使?Watcher機制實現(xiàn)分布式數(shù)據(jù)的發(fā)布/訂閱功能
Curator客戶端
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
private static CuratorFramework Client = CuratorFrameworkFactory.builder() .connectString("server1:2181,server2:2181,server3:2181") .sessionTimeoutMs(50000) .connectionTimeoutMs(30000) .retryPolicy(retryPolicy) .build(); client.start();
// 創(chuàng)建節(jié)點
client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);
// 刪除節(jié)點
client.delete().forPath(path);
// 獲取數(shù)據(jù)
client.getData().forPath(path);
// 更新數(shù)據(jù)
client.setData().forPath(path,"新內(nèi)容".getBytes());
zookeeper應(yīng)用場景
數(shù)據(jù)發(fā)布/訂閱
客戶端向服務(wù)端注冊自己關(guān)注的節(jié)點,節(jié)點數(shù)據(jù)變化,服務(wù)端向客戶端推送watcher時間通知??蛻舳私邮障⑼ㄖ鲃永》?wù)端的最新數(shù)據(jù)。
分布式鎖
- 排他鎖(寫鎖,獨占鎖)
所有客戶端創(chuàng)建同一個臨時節(jié)點,創(chuàng)建成功的客戶端獲取鎖。zookeeper保證只有?個客戶端能夠創(chuàng)建成功。
獲取鎖的客戶端機器發(fā)?宕機,或者正常執(zhí)?完業(yè)務(wù)邏輯后,客戶端就會主動將??創(chuàng)建的臨時節(jié)點刪除,從而釋放鎖 - 共享鎖(讀鎖)
創(chuàng)建臨時順序節(jié)點表示鎖
當(dāng)前 是讀請求,那么就創(chuàng)建例如/shared_lock/host1-R-0000000001的節(jié)點;如果是寫請求,那么就創(chuàng)建例 如/shared_lock/host2-W-0000000002的節(jié)點。
只需要關(guān)注/shared_lock節(jié)點下序號????的那個節(jié)點。
流程:
- 客戶端創(chuàng)建臨時順序節(jié)點
- 客戶端調(diào)?getChildren接?獲取所有已經(jīng)創(chuàng)建的?節(jié)點列表,不注冊 watcher
- 自己當(dāng)前是最小節(jié)點,獲取鎖,執(zhí)行業(yè)務(wù)后釋放鎖。
- 客戶端不是最小節(jié)點,對于讀請求:向??? 序號?的最后?個寫請求節(jié)點注冊Watcher監(jiān)聽。對于寫請求:向???序號?的最后?個節(jié)點注 冊Watcher監(jiān)聽。