溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

zookeeper機(jī)制的原理是什么

發(fā)布時(shí)間:2021-12-03 17:47:28 來(lái)源:億速云 閱讀:122 作者:柒染 欄目:云計(jì)算

今天就跟大家聊聊有關(guān)zookeeper機(jī)制的原理是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

zookeeper機(jī)原理(長(zhǎng)連接):

Zookeeper 并不是用來(lái)專(zhuān)門(mén)存儲(chǔ)數(shù)據(jù)的,它的作用主要是用來(lái)維護(hù)和監(jiān)控你存儲(chǔ)的數(shù)據(jù)的狀態(tài)變化。通過(guò)監(jiān)控這些數(shù)據(jù)狀態(tài)的變化,從而可以達(dá)到基于數(shù)據(jù)的集群管。當(dāng)對(duì)目錄節(jié)點(diǎn)監(jiān)控狀態(tài)打開(kāi)時(shí),一旦目錄節(jié)點(diǎn)的狀態(tài)發(fā)生變化,Watcher 對(duì)象的 process 方法就會(huì)被調(diào)用。

(任何實(shí)現(xiàn)org.apache.zookeeper.Watcher類(lèi),持有zookeeper實(shí)例對(duì)象,只要調(diào)用zookeeper的方法,并且監(jiān)控相應(yīng)節(jié)點(diǎn)類(lèi)型,

  那么zookeeper服務(wù)端該節(jié)點(diǎn)發(fā)生變化會(huì)通知到觀察者(觀察者重寫(xiě)方法process會(huì)被調(diào)用))

zk = new ZooKeeper(zookeeperQuorum, sessionTimeout, this); 

zookeeperQuorum=IP+端口(xxx.xxx.xxx.xxx:2181,xxx.xxx.xxx.xxx:2181,xxx.xxx.xxx.xxx:2181)多個(gè)逗號(hào)隔開(kāi)

可以設(shè)置觀察的操作:exists,getChildren,getData

可以觸發(fā)觀察的操作:create,delete,setData

zookeeper觀察機(jī)制;

服務(wù)端只存儲(chǔ)事件的信息,客戶端存儲(chǔ)事件的信息和Watcher的執(zhí)行邏輯.ZooKeeper客戶端是線程安全的每一個(gè)應(yīng)用只需要實(shí)例化一個(gè)ZooKeeper客戶端即可,同一個(gè)ZooKeeper客戶端實(shí)例可以在不同的線程中使用。ZooKeeper客戶端會(huì)將這個(gè)Watcher對(duì)應(yīng)Path路徑存儲(chǔ)在ZKWatchManager中,同時(shí)通知ZooKeeper服務(wù)器記錄該Client對(duì)應(yīng)的Session中的Path下注冊(cè)的事件類(lèi)型。當(dāng)ZooKeeper服務(wù)器發(fā)生了指定的事件后,ZooKeeper服務(wù)器將通知ZooKeeper客戶端哪個(gè)節(jié)點(diǎn)下發(fā)生事件類(lèi)型,ZooKeeper客戶端再?gòu)腪KWatchManager中找到相應(yīng)Path,取出相應(yīng)watcher引用執(zhí)行其回調(diào)函數(shù)process。

源碼分析如:

zookeeper.java

 wcb = new DataWatchRegistration(watcher, clientPath);//將觀察者引用和節(jié)點(diǎn)路徑綁定

ZKWatchManager.java

 public void register(int rc) {

            if (shouldAddWatch(rc)) {

                Map<String, Set<Watcher>> watches = getWatches(rc);

                synchronized(watches) {

                    Set<Watcher> watchers = watches.get(clientPath);

                    if (watchers == null) {

                        watchers = new HashSet<Watcher>();

                        watches.put(clientPath, watchers);//key為path,value為watcher引用

                    }

                    watchers.add(watcher);

                }

            }

        }

znode存儲(chǔ)數(shù)據(jù)量最大:jute.maxbuffer默認(rèn)1M

通知注意點(diǎn):

1.一次性觸發(fā)器(可以通過(guò)定時(shí)調(diào)用方法 get() 或者 exists()獲取觸發(fā)事件,手動(dòng)訪問(wèn)觸發(fā),)
client在一個(gè)節(jié)點(diǎn)上設(shè)置watch,隨后節(jié)點(diǎn)內(nèi)容改變,client將獲取事件。當(dāng)節(jié)點(diǎn)內(nèi)容再次改變,client不會(huì)獲取這個(gè)事件,除非它又執(zhí)行了一次讀操作并設(shè)置watch

2.發(fā)送至client,watch事件延遲
watch事件異步發(fā)送至觀察者。比如說(shuō)client執(zhí)行一次寫(xiě)操作,節(jié)點(diǎn)數(shù)據(jù)內(nèi)容發(fā)生變化,操作返回后,而watch事件可能還在發(fā)往client的路上。這種情況下,zookeeper提供有序保證:client不會(huì)得知數(shù)據(jù)變化,直到它獲取watch事件。網(wǎng)絡(luò)延遲或其他因素可能導(dǎo)致不同client在不同時(shí)刻獲取watch事件和操作返回值。

循環(huán)調(diào)用:

Watcher watcher = loopWatch?this:null;

byte[] newdata = keeper.getData(path, watcher, null);//實(shí)現(xiàn)改變?cè)俅翁嵝眩。?/p>

應(yīng)用場(chǎng)景:

Zookeeper 從設(shè)計(jì)模式角度來(lái)看,是一個(gè)基于觀察者模式設(shè)計(jì)的分布式服務(wù)管理框架,它負(fù)責(zé)存儲(chǔ)和管理大家都關(guān)心的數(shù)據(jù),然后接受觀察者的注冊(cè),一旦這些數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper 就將負(fù)責(zé)通知已經(jīng)在 Zookeeper 上注冊(cè)的那些觀察者做出相應(yīng)的反應(yīng)。

通知者模式:

發(fā)布者持有訂閱者的句柄引用,一單狀態(tài)變化,調(diào)用訂閱者接口,實(shí)現(xiàn)通知模式調(diào)用。

zookeeper 操作API:

客戶端要連接 Zookeeper 服務(wù)器可以通過(guò)創(chuàng)建 org.apache.zookeeper. ZooKeeper 的一個(gè)實(shí)例對(duì)象,然后調(diào)用這個(gè)類(lèi)提供的接口來(lái)和服務(wù)器交互

ZooKeeper 主要是用來(lái)維護(hù)和監(jiān)控一個(gè)目錄節(jié)點(diǎn)樹(shù)中存儲(chǔ)的數(shù)據(jù)的狀態(tài)。

目錄節(jié)點(diǎn)類(lèi)型:

PERSISTENT:持久化目錄節(jié)點(diǎn),這個(gè)目錄節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)不會(huì)丟失

PERSISTENT_SEQUENTIAL:順序自動(dòng)編號(hào)的目錄節(jié)點(diǎn),這種目錄節(jié)點(diǎn)會(huì)根據(jù)當(dāng)前已近存在的節(jié)點(diǎn)數(shù)自動(dòng)加 1

EPHEMERAL:臨時(shí)目錄節(jié)點(diǎn),一旦創(chuàng)建這個(gè)節(jié)點(diǎn)的客戶端與服務(wù)器端口也就是 session 超時(shí)或者斷口,這種節(jié)點(diǎn)會(huì)被自動(dòng)刪除

EPHEMERAL_SEQUENTIAL:臨時(shí)自動(dòng)編號(hào)節(jié)點(diǎn)

節(jié)點(diǎn)狀態(tài)(Stat):

  private long czxid;

  private long mzxid;

  private long ctime;

  private long mtime;

  private int version;

  private int cversion;

  private int aversion;

  private long ephemeralOwner;

  private int dataLength;

  private int numChildren;

  private long pzxid;

Watch事件類(lèi)型

ZOO_CREATED_EVENT:節(jié)點(diǎn)創(chuàng)建事件,需要watch一個(gè)不存在的節(jié)點(diǎn),當(dāng)節(jié)點(diǎn)被創(chuàng)建時(shí)觸發(fā),此watch通過(guò)zoo_exists()設(shè)置
ZOO_DELETED_EVENT:節(jié)點(diǎn)刪除事件,此watch通過(guò)zoo_exists()或zoo_get()設(shè)置
ZOO_CHANGED_EVENT:節(jié)點(diǎn)數(shù)據(jù)改變事件,此watch通過(guò)zoo_exists()或zoo_get()設(shè)置
ZOO_CHILD_EVENT:子節(jié)點(diǎn)列表改變事件,此watch通過(guò)zoo_get_children()或zoo_get_children2()設(shè)置
ZOO_SESSION_EVENT:會(huì)話失效事件,客戶端與服務(wù)端斷開(kāi)或重連時(shí)觸發(fā)
ZOO_NOTWATCHING_EVENT:watch移除事件,服務(wù)端出于某些原因不再為客戶端watch節(jié)點(diǎn)時(shí)觸發(fā)

一:集群管理:

1 監(jiān)控服務(wù)器健康

它們的實(shí)現(xiàn)方式都是在 Zookeeper 上創(chuàng)建一個(gè) EPHEMERAL 類(lèi)型的目錄節(jié)點(diǎn),然后每個(gè) Server 在它們創(chuàng)建目錄節(jié)點(diǎn)的父目錄節(jié)點(diǎn)上調(diào)用 getChildren(String path, boolean watch) 方法并設(shè)置 watch 為 true,由于是 EPHEMERAL 目錄節(jié)點(diǎn),當(dāng)創(chuàng)建它的 Server 死去,這個(gè)目錄節(jié)點(diǎn)也隨之被刪除,所以 Children 將會(huì)變化,這時(shí) getChildren上的 Watch 將會(huì)被調(diào)用,所以其它 Server 就知道已經(jīng)有某臺(tái) Server 死去了。新增 Server 也是同樣的原理。

2 Master選舉

Zookeeper 如何實(shí)現(xiàn) Leader Election,也就是選出一個(gè) Master Server。和前面的一樣每臺(tái) Server 創(chuàng)建一個(gè) EPHEMERAL 目錄節(jié)點(diǎn),不同的是它還是一個(gè) SEQUENTIAL 目錄節(jié)點(diǎn),所以它是個(gè) EPHEMERAL_SEQUENTIAL 目錄節(jié)點(diǎn)。之所以它是 EPHEMERAL_SEQUENTIAL 目錄節(jié)點(diǎn),是因?yàn)槲覀兛梢越o每臺(tái) Server 編號(hào),我們可以選擇當(dāng)前是最小編號(hào)的 Server 為 Master,假如這個(gè)最小編號(hào)的 Server 死去,由于是 EPHEMERAL 節(jié)點(diǎn),死去的 Server 對(duì)應(yīng)的節(jié)點(diǎn)也被刪除,所以當(dāng)前的節(jié)點(diǎn)列表中又出現(xiàn)一個(gè)最小編號(hào)的節(jié)點(diǎn),我們就選擇這個(gè)節(jié)點(diǎn)為當(dāng)前 Master。這樣就實(shí)現(xiàn)了動(dòng)態(tài)選擇 Master,避免了傳統(tǒng)意義上單 Master 容易出現(xiàn)單點(diǎn)故障的問(wèn)題。

二:分布式鎖

在同一個(gè)進(jìn)程中很容易實(shí)現(xiàn),但是在跨進(jìn)程或者在不同 Server 之間就不好實(shí)現(xiàn)了。Zookeeper 卻很容易實(shí)現(xiàn)這個(gè)功能,實(shí)現(xiàn)方式也是需要獲得鎖的 Server 創(chuàng)建一個(gè) EPHEMERAL_SEQUENTIAL 目錄節(jié)點(diǎn),然后調(diào)用 getChildren方法獲取當(dāng)前的目錄節(jié)點(diǎn)列表中最小的目錄節(jié)點(diǎn)是不是就是自己創(chuàng)建的目錄節(jié)點(diǎn),如果正是自己創(chuàng)建的,那么它就獲得了這個(gè)鎖,如果不是那么它就調(diào)用 exists(String path, boolean watch) 方法并監(jiān)控 Zookeeper 上目錄節(jié)點(diǎn)列表的變化,一直到自己創(chuàng)建的節(jié)點(diǎn)是列表中最小編號(hào)的目錄節(jié)點(diǎn),從而獲得鎖,釋放鎖很簡(jiǎn)單,只要?jiǎng)h除前面它自己所創(chuàng)建的目錄節(jié)點(diǎn)就行了 n> Server 也是同樣的原理。

看完上述內(nèi)容,你們對(duì)zookeeper機(jī)制的原理是什么有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI