摘要:當(dāng)服務(wù)端的一些操作觸發(fā)了事件監(jiān)聽,就會向指定的客戶端發(fā)送事件通知。因此,使用的監(jiān)聽機(jī)制實(shí)現(xiàn)的發(fā)布訂閱系統(tǒng)使用的推拉結(jié)合的方式。
本文主要對zookeeper的數(shù)據(jù)模型Znode進(jìn)行的簡要說明 主要內(nèi)容:
1. zk的主要應(yīng)用場景 2. zk的數(shù)據(jù)節(jié)點(diǎn)的概述
數(shù)據(jù)節(jié)點(diǎn)的類型
節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)
節(jié)點(diǎn)上的監(jiān)聽機(jī)制
1. zk的主要應(yīng)用場景數(shù)據(jù)的發(fā)布與訂閱
負(fù)載均衡
統(tǒng)一命名服務(wù)
分布式協(xié)調(diào)與通知
集群管理
master選舉
分布式鎖與分布式隊(duì)列
具體將在后續(xù)的文章中給出具體的應(yīng)用介紹。
2. zk的數(shù)據(jù)節(jié)點(diǎn)的概述在介紹數(shù)據(jù)節(jié)點(diǎn)之前,先給大家說明一下zk中事務(wù)的概念。zk中的事務(wù)指的是能夠改變zk服務(wù)器狀態(tài)的操作,包括
數(shù)據(jù)節(jié)點(diǎn)的刪除,創(chuàng)建和內(nèi)容更新等
客戶端會話的創(chuàng)建與失效
zk中還有一個事務(wù)id的概念,會為每次事務(wù)請求分配一個全局唯一的id,關(guān)于事務(wù)id的特點(diǎn)簡要說明如下:
2.1 zk數(shù)據(jù)節(jié)點(diǎn)的類型64位數(shù)字
高32是Leader統(tǒng)治時期的標(biāo)識,說明該事務(wù)是在哪個Leader時期進(jìn)行的
低32位是事務(wù)的id號
通過這64位數(shù)字可以確定一個事務(wù)請求的全局唯一的順序
zk中的數(shù)據(jù)節(jié)點(diǎn)是有生命周期的概念的,根據(jù)生命周期的不同可以劃分為兩種類型的節(jié)點(diǎn)
2.2 節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)持久節(jié)點(diǎn)(Persistent)
最常見的一種節(jié)點(diǎn)類型,也叫做regular節(jié)點(diǎn)。數(shù)據(jù)節(jié)點(diǎn)一旦被創(chuàng)建,就會一直存在于zk服務(wù)器上,直到有刪除事務(wù)操作主動清除該節(jié)點(diǎn)
臨時節(jié)點(diǎn)(Ephemeral)
臨時節(jié)點(diǎn)的生命周期是和客戶端會話綁定在一起的,只要客戶端會話失效,那么臨時節(jié)點(diǎn)就會被清除。這里的客戶端會話失效和客戶端tcp連接斷開是不一樣的。
臨時節(jié)點(diǎn)只能是leaf節(jié)點(diǎn)順序節(jié)點(diǎn)(Sequential)
zk會給創(chuàng)建的節(jié)點(diǎn)自動加上一個數(shù)字后綴,作為一個完整的節(jié)點(diǎn)名稱,這種方式可以維護(hù)節(jié)點(diǎn)之間的一種順序性
持久節(jié)點(diǎn)+順序節(jié)點(diǎn)
臨時節(jié)點(diǎn)+順序節(jié)點(diǎn)
數(shù)據(jù)節(jié)點(diǎn)的類結(jié)構(gòu)代碼如下:
public class DataNode implements Record { byte data[]; //節(jié)點(diǎn)上存儲的數(shù)據(jù) Long acl; //權(quán)限控制列表版本號 public StatPersisted stat; //節(jié)點(diǎn)狀態(tài)信息 private Setchildren = null; //節(jié)點(diǎn)的子節(jié)點(diǎn)列表 }
StatPersisted stat是該節(jié)點(diǎn)的狀態(tài)信息類,類結(jié)構(gòu)代碼如下:
public class StatPersisted implements Record { private long czxid; //創(chuàng)建該節(jié)點(diǎn)的事務(wù)id private long mzxid; //最后一次修改節(jié)點(diǎn)的事務(wù)id private long ctime; //節(jié)點(diǎn)的創(chuàng)建時間 private long mtime; //最后一次更新節(jié)點(diǎn)內(nèi)容的時間 private int version; //數(shù)據(jù)節(jié)點(diǎn)的版本號,version=0表示該節(jié)點(diǎn)被創(chuàng)建之后,更新過0次,在實(shí)現(xiàn)樂觀鎖的時候有用 private int cversion; //子節(jié)點(diǎn)的版本號,只有當(dāng)子節(jié)點(diǎn)列表被更改后,才會+1 private int aversion; //子節(jié)點(diǎn)的acl列表版本號 private long ephemeralOwner; //如果是臨時節(jié)點(diǎn),該值表示創(chuàng)建該節(jié)點(diǎn)的臨時會話的sessionID,如果是持久節(jié)點(diǎn)的話,該值為0 private long pzxid; //子節(jié)點(diǎn)列表最后一次被修改時的事務(wù)id,一定是子節(jié)點(diǎn)列表被修改,子節(jié)點(diǎn)的內(nèi)容被修改是不會改變這個屬性的值的 }2.3 節(jié)點(diǎn)上的監(jiān)聽機(jī)制
zookeeper允許客戶端對象在數(shù)據(jù)節(jié)點(diǎn)上注冊事件監(jiān)聽,可以實(shí)現(xiàn)數(shù)據(jù)的發(fā)布與訂閱。
當(dāng)zk服務(wù)端的一些操作觸發(fā)了事件監(jiān)聽Watcher,就會向指定的客戶端發(fā)送事件通知。
zk中的事件監(jiān)聽機(jī)制由三部分組成:
zk服務(wù)端
客戶端線程
客戶端的WatcherManager
客戶端線程在zk服務(wù)器上注冊事件監(jiān)聽之后,會將這個watcher對象存儲在WatcherManager中,當(dāng)zk服務(wù)器觸發(fā)這個事件之后,會向客戶端發(fā)送通知,客戶端線程會從WatcherManager中取出對應(yīng)的Watcher對象來執(zhí)行回調(diào)邏輯。
監(jiān)聽器的接口類Watcher代碼如下public interface Watcher{ public interface Event{ public enum KeeperState{ Disconnected(0), //斷開連接 SyncConnected(3), //此時客戶端與zk服務(wù)器處于連接狀態(tài) AuthFailed(4), //權(quán)限檢查失敗 ConnectedReadOnly(5) //客戶端和一臺只讀server處于連接狀態(tài),what is readonly server? 就是只和集群中的一小部分服務(wù)器處于連接的服務(wù)器 Expired(-122) //會話超時 } public enum EventType{ None (-1), NodeCreated (1), //watcher監(jiān)聽的數(shù)據(jù)節(jié)點(diǎn)被創(chuàng)建 NodeDeleted (2), //watcher監(jiān)聽的數(shù)據(jù)節(jié)點(diǎn)被刪除 NodeDataChanged (3), //watcher監(jiān)聽的數(shù)據(jù)節(jié)點(diǎn)內(nèi)容被更新 NodeChildrenChanged (4), //watcher監(jiān)聽的數(shù)據(jù)節(jié)點(diǎn)的子節(jié)點(diǎn)列表被更新了 DataWatchRemoved (5), ChildWatchRemoved (6); } } public enum WatcherType{ Children (1), Data (2), Any (3); } abstract public void process(WatchedEvent event); }
主要有以下幾個部分組成
Watcher.Event.KeeperState: 表示通知狀態(tài)
Watcher.Event.EventType: 表示通知的事件類型
Watcher.WatcherType: 監(jiān)聽器的類型
process(WatchedEvent event) 事件的回調(diào)函數(shù)
在處理監(jiān)聽事件的回調(diào)函數(shù)process中,參數(shù)event是一個org.apache.zookeeper.WatchedEvent類型的參數(shù)。WatchedEvent說明如下
public class WatchedEvent { final private KeeperState keeperState; //通知的狀態(tài) final private EventType eventType; //事件類型 private String path; //參與該事件的節(jié)點(diǎn)路徑 /** *實(shí)現(xiàn)WatchedEvent到WatcherEvent的轉(zhuǎn)換 */ public WatcherEvent getWrapper() { return new WatcherEvent(eventType.getIntValue(), keeperState.getIntValue(), path); } /** *實(shí)現(xiàn)WatcherEvent到WatchedEvent的轉(zhuǎn)換 */ public WatchedEvent(WatcherEvent eventMessage) { keeperState = KeeperState.fromInt(eventMessage.getState()); eventType = EventType.fromInt(eventMessage.getType()); path = eventMessage.getPath(); } }
從WatchedEvent的代碼中可以看出一個監(jiān)聽事件由三個部分組成的:
Watcher.Event.KeeperState:通知狀態(tài)
Watcher.Event.EventType:通知類型
String path:參與該事件的節(jié)點(diǎn)路徑
并且,與WatchedEvent對應(yīng)的還有一個類WatcherEvent,這個WatcherEvent和WatchedEvent相比,只是實(shí)現(xiàn)了序列化,方便通過網(wǎng)絡(luò)在服務(wù)端和客戶端之間傳輸。
序列化使用的是jute
客戶端在服務(wù)器數(shù)據(jù)節(jié)點(diǎn)上注冊相應(yīng)的監(jiān)聽事件Watcher,注冊的方式后面闡述
服務(wù)端操作觸發(fā)該事件,生成WatchedEvent事件對象
調(diào)用getWrapper方法將WatchedEvent包裝稱為一個實(shí)現(xiàn)序列化的、可在網(wǎng)絡(luò)上傳輸?shù)腤atcherEvent對象
通過網(wǎng)絡(luò)將WatcherEvent對象發(fā)送到client
client將WatcherEvent對象還原成為一個WatchedEvent對象,并傳遞給process方法進(jìn)行處理
客戶端接受到的服務(wù)器傳送過來的監(jiān)聽事件的格式如下:
KeeperState:SyncConnected EventType:NodeDataChanged Path: /zk-book
顯然,從接收到的事件中,客戶端是無法獲取到該節(jié)點(diǎn)在更新前后的數(shù)據(jù)的,因此客戶端是要主動再向服務(wù)器獲取數(shù)據(jù)。因此,使用zk的監(jiān)聽機(jī)制實(shí)現(xiàn)的發(fā)布訂閱系統(tǒng)使用的"推拉"結(jié)合的方式。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74052.html
摘要:的設(shè)計(jì)目標(biāo)是將那些復(fù)雜且容易出錯的分布式一致性服務(wù)封裝起來,構(gòu)成一個高效可靠的原語集,并以一系列簡單易用的接口提供給用戶使用。具有不可分割性即原語的執(zhí)行必須是連續(xù)的,在執(zhí)行過程中不允許被中斷。 該文已加入開源文檔:JavaGuide(一份涵蓋大部分Java程序員所需要掌握的核心知識)。地址:https://github.com/Snailclimb... showImg(https:...
摘要:協(xié)調(diào)服務(wù)的功能在分布式架構(gòu)中,每個服務(wù)器或者服務(wù)之間信息的協(xié)調(diào)和管理是非常有必要的常見的分布式協(xié)調(diào)服務(wù)有的,的因?yàn)楣雀璧氖遣婚_源的,后來雅虎模仿它開發(fā)了,并捐贈給,并將其開源供大家使用我們先從的幾個功能來了解名稱服務(wù)什么是名稱服務(wù)比如將域名 協(xié)調(diào)服務(wù)的功能 在分布式架構(gòu)中,每個服務(wù)器或者服務(wù)之間信息的協(xié)調(diào)和管理是非常有必要的 常見的分布式協(xié)調(diào)服務(wù)有Google的Chubby,Apach...
摘要:除此之外,它嚴(yán)格的序列訪問控制意味著復(fù)雜的控制原語可以應(yīng)用在客戶端上。版本號對節(jié)點(diǎn)的每一個操作都將致使這個節(jié)點(diǎn)的版本號增加。事件是一次性的觸發(fā)器,當(dāng)?shù)膶ο鬆顟B(tài)發(fā)生改變時,將會觸發(fā)此對象上所對應(yīng)的事件。節(jié)點(diǎn)事件節(jié)點(diǎn)的建立,刪除,數(shù)據(jù)的修改。 目錄 一、ZooKeeper概述 二、ZooKeeper數(shù)據(jù)模型 三、ZooKeeper服務(wù)中操作 四、Watch觸發(fā)器 五、ZooKeeper應(yīng)用...
摘要:具有不可分割性即原語的執(zhí)行必須是連續(xù)的,在執(zhí)行過程中不允許被中斷。提供服務(wù)主要就是通過數(shù)據(jù)結(jié)構(gòu)原語集機(jī)制達(dá)到的。子節(jié)點(diǎn)的版本號數(shù)據(jù)節(jié)點(diǎn)版本號版本號創(chuàng)建該節(jié)點(diǎn)的會話的。后位則為遞增序列。 前言 最近加入了部門的技術(shù)興趣小組,被分配了Zookeeper的研究任務(wù)。在研究過程當(dāng)中,發(fā)現(xiàn)Zookeeper由于其開源的特性和其卓越的性能特點(diǎn),在業(yè)界使用廣泛,有很多的應(yīng)用場景,而這些不同的應(yīng)用場景...
摘要:之后服務(wù)器等待其他服務(wù)器的反饋,一旦超過半數(shù)的服務(wù)器進(jìn)行了正確的反饋,那么就會再次向所有的服務(wù)器分發(fā)消息,要求其將前一個進(jìn)行提交。協(xié)議包括兩種基本的模式,分別是崩潰恢復(fù)和消息廣播。 前言 zookeeper本質(zhì)上就是一個分布式協(xié)調(diào)服務(wù),用來解決分布式一致性的問題。 本文適合有一定分布式基礎(chǔ)的讀者閱讀。什么叫相關(guān)的基礎(chǔ)呢?起碼你得知道系統(tǒng)架構(gòu)為何從集中式演變成了分布式,分布式有哪些優(yōu)點(diǎn)...
閱讀 2468·2021-11-19 09:40
閱讀 3602·2021-11-17 17:08
閱讀 3807·2021-09-10 10:50
閱讀 2229·2019-08-27 10:56
閱讀 1953·2019-08-27 10:55
閱讀 2649·2019-08-26 12:14
閱讀 1002·2019-08-26 11:58
閱讀 1501·2019-08-26 10:43