1. zookeeper基本概念

zookeeper是一個分散式的,開放源碼的分散式應用程序協調服務,是hadoop和Habase的重要組件,是為分散式應用提供一致性服務的軟體。

2. zookeeper的特徵

2.1. 簡易

ZooKeeper的最重要核心就是一個精簡文件系統,提供一些簡單的操作以及附加的抽象(例如排序和通知)。

2.2. 易表達

ZooKeeper的原型是一個豐富的集合,它們是一些已建好的塊,可以用來構建大型的協作數據結構和協議,例如:分散式隊列、分散式鎖以及一組對等體的選舉。

2.3. 高可用性

ZooKeeper運行在一些集羣上,被設計成可用性較高的,因此應用程序可以依賴它。ZooKeeper可以幫助你的系統避免單點故障,從而建立一個可靠的應用程序。

2.4. 鬆散耦合

ZooKeeper的交互支持參與者之間並不瞭解對方。例如:ZooKeeper可以被當做一種公共的機制,使得進程彼此不知道對方的存在也可以相互發現並且交互,對等方可能甚至不是同步的。

2.5. Zookeeper一致性的保證

順序一致性:按照客戶端發送請求的順序更新數據。

原子性:更新要麼成功,要麼失敗,不會出現部分更新。

單一性:無論客戶端連接哪個server,都會看到同一個視圖。

可靠性:一旦數據更新成功,將一直保持,直到新的更新。

實時性:Zookeeper保證客戶端將在一個時間間隔範圍內獲得伺服器的更新信息或者伺服器失效的信息。

3. zookeeper工作原理

Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。Zab協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啟動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和leader的狀態同步以後,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。

為了保證事務的順序一致性,zookeeper採用了遞增的事務id號(zxid)來標識事務。所有的提議(proposal)都在被提出的時候加上了zxid。實現中zxid是一個64位的數字,它高32位是epoch用來標識leader關係是否改變,每次一個leader被選出來,它都會有一個新的epoch,標識當前屬於那個leader的統治時期。低32位用於遞增計數。

· 在zookeeper集羣中有三種角色和四種狀態

角色:leader,follower,observer

狀態:leading,following,observing,looking

每個Server在工作過程中有4種狀態:

LOOKING:當前Server不知道leader是誰,正在搜尋。

LEADING:當前Server即為選舉出來的leader。

FOLLOWING:leader已經選舉出來,當前Server與之同步。

OBSERVING:observer的行為在大多數情況下與follower完全一致,但是他們不參加選舉和投票,而僅僅接受(observing)選舉和投票的結果。

3.1 Leader選舉

當leader崩潰或leader失去大多數的follower時,zookeeeper將進入恢復模式,恢復模式選舉出新的leader讓所有的server進入正確狀態,選舉演算法包括兩種:基於basic paxos和基於fast paxos,系統默認是fast paxos。

3.2 basic paxos

1.選舉線程由當前Server發起選舉的線程擔任,其主要功能是對投票結果進行統計,並選出推薦的Server;

2 .選舉線程首先向所有Server發起一次詢問(包括自己);

3 .選舉線程收到回復後,驗證是否是自己發起的詢問(驗證zxid是否一致),然後獲取對方的id(myid),並存儲到當前詢問對象列表中,最後獲取對方提議的leader相關信息(id,zxid),並將這些信息存儲到當次選舉的投票記錄表中;

4. 收到所有Server回復以後,就計算出zxid最大的那個Server,並將這個Server相關信息設置成下一次要投票的Server;

5. 線程將當前zxid最大的Server設置為當前Server要推薦的Leader,如果此時獲勝的Server獲得n/2 + 1的Server票數, 設置當前推薦的leader為獲勝的Server,將根據獲勝的Server相關信息設置自己的狀態,否則,繼續這個過程,直到leader被選舉出來。

3.3 fast paxox

fast paxos流程是在選舉過程中,某Server首先向所有Server提議自己要成為leader,當其它Server收到提議以後,解決epoch和zxid的衝突,並接受對方的提議,然後向對方發送接受提議完成的消息,重複這個流程,最後一定能選舉出Leader。

3.4 同步流程

選完leader以後,zk就進入狀態同步過程。

1. leader等待server連接;

2 .Follower連接leader,將最大的zxid發送給leader;

3 .Leader根據follower的zxid確定同步點;

4 .完成同步後通知follower 已經成為uptodate狀態;

5 .Follower收到uptodate消息後,又可以重新接受client的請求進行服務了。

3.5 Leader工作流程

1 .恢複數據;

2 .維持與Learner的心跳,接收Learner請求並判斷Learner的請求消息類型;

3 .Learner的消息類型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根據不同的消息類型,進行不同的處理。

PING消息是指Learner的心跳信息;REQUEST消息是Follower發送的提議信息,包括寫請求及同步請求;ACK消息是Follower的對提議的回復,超過半數的Follower通過,則commit該提議;REVALIDATE消息是用來延長SESSION有效時間。

3.6 Follower工作流程

1. 向Leader發送請求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);

2 .接收Leader消息並進行處理;

3 .接收Client的請求,如果為寫請求,發送給Leader進行投票;

4 .返回Client結果。

Follower的消息循環處理如下幾種來自Leader的消息:

1 .PING消息:心跳消息;

2 .PROPOSAL消息:Leader發起的提案,要求Follower投票;

3 .COMMIT消息:伺服器端最新一次提案的信息;

4 .UPTODATE消息:表明同步完成;

5 .REVALIDATE消息:根據Leader的REVALIDATE結果,關閉待revalidate的session還是允許其接受消息;

6 .SYNC消息:返回SYNC結果到客戶端,這個消息最初由客戶端發起,用來強製得到最新的更新。

3.7 ZooKeeper數據模型

Zookeeper會維護一個具有層次關係的數據結構,它非常類似於一個標準的文件系統,如圖所示:

Zookeeper這種數據結構有如下這些特點:

1)每個子目錄項如NameService都被稱作為znode,這個znode是被它所在的路徑唯一標識,如Server1這個znode的標識為/NameService/Server1。

2)znode可以有子節點目錄,並且每個znode可以存儲數據,注意EPHEMERAL(臨時的)類型的目錄節點不能有子節點目錄。

3)znode是有版本的(version),每個znode中存儲的數據可以有多個版本,也就是一個訪問路徑中可以存儲多份數據,version號自動增加。

4)znode可以是臨時節點(EPHEMERAL),可以是持久節點(PERSISTENT)。如果創建的是臨時節點,一旦創建這個EPHEMERALznode的客戶端與伺服器失去聯繫,這個znode也將自動刪除,Zookeeper的客戶端和伺服器通信採用長連接方式,每個客戶端和伺服器通過心跳來保持連接,這個連接狀態稱為session,如果znode是臨時節點,這個session失效,znode也就刪除了。

5)znode的目錄名可以自動編號,如App1已經存在,再創建的話,將會自動命名為App2。

6)znode可以被監控,包括這個目錄節點中存儲的數據的修改,子節點目錄的變化等,一旦變化可以通知設置監控的客戶端,這個是Zookeeper的核心特性,Zookeeper的很多功能都是基於這個特性實現的。

7)ZXID:每次對Zookeeper的狀態的改變都會產生一個zxid(ZooKeeperTransaction Id),zxid是全局有序的,如果zxid1小於zxid2,則zxid1在zxid2之前發生。

3.8 Watcher機制

1.概述

ZK中引入Watcher機制來實現分散式的通知功能,ZK允許客戶端向服務端註冊一個Watcher監聽,當服務點的的指定事件觸發監聽時,那麼服務端就會向客戶端發送事件通知,以便客戶端完成邏輯操作(即客戶端向服務端註冊監聽,並將watcher對象存在客戶端的Watchermanager中,服務端觸發事件後,向客戶端發送通知,客戶端收到通知後從wacherManager中取出對象來執行回調邏輯)

2.特性

a.一次性:一旦一個watcher被觸發,ZK都會將其從相應的的存儲中移除,所以watcher是需要每註冊一次,纔可觸發一次。

b.ZK客戶端串列執行:客戶端watcher回調過程是一個串列同步的過程

c.輕量:watcher數據結構中只包含:通知狀態、事件類型和節點路徑

3.watcher類型

Wacher類型

所監聽類型

data watches

getData()和exists()以及create()

child watches

getChildren()

4.Watch事件類型

ZOO_CREATED_EVENT:節點創建事件,需要watch一個不存在的節點,當節點被創建時觸發,此watch通過zoo_exists()設置

ZOO_DELETED_EVENT:節點刪除事件,此watch通過zoo_exists()或zoo_get()設置ZOO_CHANGED_EVENT:節點數據改變事件,此watch通過zoo_exists()或zoo_get()設置ZOO_CHILD_EVENT:子節點列表改變事件,此watch通過zoo_get_children()或zoo_get_children2()設置ZOO_SESSION_EVENT:會話失效事件,客戶端與服務端斷開或重連時觸發

ZOO_NOTWATCHING_EVENT:watch移除事件,服務端出於某些原因不再為客戶端watch節點時

3.9 Zookeeper會話狀態轉換

3.10 Zookeeper故障切換

ZooKeeper客戶端可以自動地進行故障切換,切換至另一臺ZooKeeper伺服器。並且關鍵的一點是,在另一臺伺服器接替故障伺服器之後,所有的會話和相關的短暫Znode仍然是有效的。在故障切換過程中,應用程序將收到斷開連接和連接至服務的通知。當客戶端斷開連接時,觀察通知將無法發送;但是當客戶端成功恢復連接後,這些延遲的通知會被發送。當然,在客戶端重新連接至另一臺伺服器的過程中,如果應用程序試圖執行一個操作,這個操作將會失敗。這充分體現了在真實的ZooKeeper應用中處理連接丟失異常的重要性。

3.11 Zookeeper節點

PERSISTENT:持久節點,就一直存在,直到有刪除操作來主動清除這個節點

PERSISTENT_SEQUENTIAL:持久順序節點,需刪除操作來清除,除此之外,每個父節點會為他的第一級子節點維護一份時序,會記錄每個子節點創建的先後順序

EPHEMERAL:臨時節點與持久節點不同的是,臨時節點會隨著會話的結束而自動清除

EPHEMERAL_SEQUENTIAL:臨時順序節點與臨時節點一樣,會隨著會話結束,而自動清除,除此之外還具有時序

4. Zookeeper環境部署

Zookeeper使用Java語言編寫的,所以運行環境需要Java環境的支持(即需要JDK1.6或1.6以上版本的支持)。

ZK環境模式分為三種模式:單機模式、偽集羣模式、集羣模式。

4.1 單機模式配置

配置文件目錄conf下的配置文件zoo.cfg配置如下

tickTime=2000

dataDir=/opt/zookeeper/data

dataLogDir=/opt/zookeeper/logs

clientPort=21280

配置參數說明:

tickTime: zookeeper中使用的基本時間單位, 毫秒值.

dataDir: 數據目錄. 可以是任意目錄.

dataLogDir: log目錄, 同樣可以是任意目錄. 如果沒有設置該參數, 將使用和dataDir相同的設置.

clientPort: 監聽client連接的埠號.

4.2 偽集羣模式配置

偽集羣是指在單臺機器中啟動多個zookeeper進程, 並組成一個集羣. 以啟動3個zookeeper進程為例.

Zookeeper1的配置

1.配置文件目錄conf下的配置文件zoo.cfg配置如下:

tickTime=2000

initLimit=5

syncLimit=2

dataDir=/opt/zookeeper0/data

dataLogDir=/opt/zookeeper0/logs

clientPort=2181

server.0=127.0.0.1:8880:7770

server.1=127.0.0.1:8881:7771

server.2=127.0.0.1:8882:7772

2.在之前設置的dataDir中新建myid文件, 寫入一個數字, 該數字表示這是第幾號server. 該數字必須和zoo.cfg文件中的server.X中的X一一對應.

注意:因是單機偽集羣配置,故每個埠號只能被一個應用程序使用,所以剩餘兩個配置的客戶端監聽埠、leader消息交換埠和選舉埠參數必須不一樣

配置參數說明:

inittime:用於配置leader伺服器等待follower啟動,並完成數據同步的時間,默認值10

synclimit:用於配置leader伺服器和follower之間進行心條檢測的最大延時時間,默認值5

server.X=A:B:C:其中X是一個數字, 表示這是第幾號server. A是該server所在的IP地址. B配置該server和集羣中的leader交換消息所使用的埠. C配置選舉leader時所使用的埠. 由於配置的是偽集羣模式, 所以各個server的A,B,C參數必須不同.

4.3 集羣模式配置

1. 配置文件目錄conf下的配置文件zoo.cfg配置如下

tickTime=2000

initLimit=5

syncLimit=2

dataDir=/opt/zookeeper/data

dataLogDir=/opt/zookeeper/logs

clientPort=4180

server.43=10.1.39.43:2888:3888

server.47=10.1.39.47:2888:3888

server.48=10.1.39.48:2888:3888

2.在之前設置的dataDir中新建myid文件, 寫入一個數字, 該數字表示這是第幾號server. 該數字必須和zoo.cfg文件中的server.X中的X一一對應.

注意:此處各個埠號儘可能保持一致

配置參數說明:

同上

4.4 ZooKeeper詳細配置

配置類型配置項描述基本配置clientport客戶端連接埠號dataDir快照存儲、myid配置項存儲和zk服務進程pid存儲目錄dataLogDirZk日誌存儲目錄,如果不配置此項,日誌將存儲到dataDir目錄下tickTimeZK中的一個時間單元。ZK中所有時間都是以這個時間單元為基礎,進行整數倍配置的,默認值為3000毫秒。存儲配置preAllocSize預先開闢磁碟空間,用於後續寫入事務日誌。默認是64M,每個事務日誌大小就是64M。如果ZK的快照頻率較大的話,建議適當減小這個參數。(Java system property:zookeeper.preAllocSize)snapCount每進行snapCount次事務日誌輸出後,觸發一次快照(snapshot), 此時,ZK會生成一個snapshot.*文件,同時創建一個新的事務日誌文件log.*。默認是100000.(真正的代碼實現中,會進行一定的隨機數處理,以避免所有伺服器在同一時間進行快照而影響性能)(Java system property:zookeeper.snapCount)autopurge.snapRetainCoun這個參數和上面的參數搭配使用,這個參數指定了需要保留的文件數目。默認是保留3個。autopurge.purgeIntervalZK提供了自動清理事務日誌和快照文件的功能,這個參數指定了清理頻率,單位是小時,需要配置一個1或更大的整數,默認是0,表示不開啟自動清理功能。fsync.warningthresholdms事務日誌輸出時,如果調用fsync方法超過指定的超時時間,那麼會在日誌中輸出警告信息。默認是1000ms。( fsync.warningthresholdms)New in 3.3.4 Weight.x=n group.x=nnnnn[:nnnnn]權重和分組設置traceFile用於記錄所有請求的log,一般調試過程中可以使用,但是生產環境不建議使用,會嚴重影響性能。(Java system property:? requestTraceFile)網路配置globalOutstandingLimit最大請求堆積數。默認是1000。ZK運行的時候, 儘管server已經沒有空閑來處理更多的客戶端請求了,但是還是允許客戶端將請求提交到伺服器上來,以提高吞吐性能。當然,為了防止Server內存溢出,這個請求堆積數還是需要限制下的。 (zookeeper.globalOutstandingLimit.)maxClientCnxns單個客戶端與單臺伺服器之間的連接數的限制,是ip級別的,默認是60,如果設置為0,那麼表明不作任何限制。請注意這個限制的使用範圍,僅僅是單臺客戶端機器與單臺ZK伺服器之間的連接數限制,不是針對指定客戶端IP,也不是ZK集羣的連接數限制,也不是單臺ZK對所有客戶端的連接數限制。指定客戶端IP的限制策略,這裡有一個patch,可以嘗試一下clientPortAddress對於多網卡的機器,可以為每個IP指定不同的監聽埠。默認情況是所有IP都監聽 clientPort指定的埠。 New in 3.3.0minSessionTimeoutSession最小超時限制,默認值2 * tickTimemaxSessionTimeoutSession最大超時限制,默認值20 * tickTime集羣配置initLimitFollower在啟動過程中,會從Leader同步所有最新數據,然後確定自己能夠對外服務的起始狀態。Leader允許F在initLimit時間內完成這個工作,默認值3*ticktimesyncLimit在運行過程中,Leader負責與ZK集羣中所有機器進行通信,例如通過一些心跳檢測機制,來檢測機器的存活狀態。如果L發出心跳包在syncLimit之後,還沒有從F那裡收到響應,那麼就認為這個F已經不在線了。注意:不要把這個參數設置得過大,否則可能會掩蓋一些問題。leaderServes默認情況下,Leader是會接受客戶端連接,並提供正常的讀寫服務。但是,如果你想讓Leader專註於集羣中機器的協調,那麼可以將這個參數設置為no,這樣一來,會大大提高寫操作的性能。(Java system property: zookeeper.leaderServes)。server.x=[hostname]:prot1:port2[:observer]這裡的x是一個數字,與myid文件中的id是一致的。右邊可以配置兩個埠,第一個埠用於F和L之間的數據同步和其它通信,第二個埠用於Leader選舉過程中投票通信,還有可選配置observer』。cnxTimeoutLeader選舉過程中,打開一次連接的超時時間,默認是5s。(zookeeper. cnxTimeout)electionAlg在之前的版本中, 這個參數配置是允許我們選擇leader選舉演算法,但是由於在以後的版本中,只會留下一種「TCP-based version of fast leader election」演算法,所以這個參數目前看來沒有用了。授權配置zookeeper.DigestAuthenticationProvider.superDigest超級用戶密碼認證選項,默認是關閉的不安全選項forceSync這個參數確定了是否需要在事務日誌提交的時候調用FileChannel.force來保證數據完全同步到磁碟。(Java system property: zookeeper.forceSync)jute.maxbuffer每個節點最大數據量,是默認是1M。這個限制必須在server和client端都進行設置才會生效。(Java system property: jute.maxbuffer) skipACL對所有客戶端請求都不作ACL檢查。如果之前節點上設置有許可權限制,一旦伺服器上打開這個開頭,那麼也將失效。(Java system property: zookeeper.skipACL)Readonlymode.enabled

4.4 運行服務

完成配置後可啟動ZK服務,用 ZK自帶的服務啟動腳本來啟動服務。

ZK自帶的腳本有:

腳本

說明

zkCleanup

清理ZK歷史數據包括庶務日誌文件和數據快照

zkCli

ZK的一個簡易客戶端

zkServer

ZK的服務啟動、停止、重啟和狀態查看start,stop、restart、status

zkEnv

設置ZK的環境變數

ZK常用四字命令

命令:echo 四字命令 | nc IP PORT (注意:此處IP和port之間是空格不是冒號)

zookeeper四字命令

功能描述

conf

輸出相關服務配置的詳細信息

cons

列出所有連接到伺服器的客戶端的完全的連接 /會話的詳細信息。包括「接受 / 發送」的包數量、會話 id 、操作延遲、最後的操作執行等等信息。

dump

列出未經處理的會話和臨時節點。

envi

輸出關於服務環境的詳細信息(區別於 conf命令)。

reqs

列出未經處理的請求

ruok

測試服務是否處於正確狀態。如果確實如此,那麼服務返回「imok 」,否則不做任何相應。

stat

輸出關於性能和連接的客conf戶端的列表。

wchs

列出伺服器watch的詳細信息。

wchc

通過 session列出伺服器 watch的詳細信息,它的輸出是一個與watch相關的會話的列表。

wchp

通過路徑列出伺服器 watch的詳細信息。它輸出一個與 session相關的路徑

zk客戶端常用命令

命令

功能描述

ls

查看子節點

ls2

查看當前節點數據並能看到更新次數等數據

create [-s] [-e] path data

創建節點

delete

刪除節點

get

獲取節點數據

set

更新節點數據

4.5 ZooKeeper Client API

ZooKeeperClient Library提供了豐富直觀的API供用戶程序使用,下面是一些常用的API:

create(path, data, flags): 創建一個ZNode, path是其路徑,data是要存儲在該ZNode上的數據,flags常用的有:PERSISTEN, PERSISTENT_SEQUENTAIL, EPHEMERAL, EPHEMERAL_SEQUENTAIL

delete(path, version): 刪除一個ZNode,可以通過version刪除指定的版本, 如果version是-1的話,表示刪除所有的版本

exists(path, watch): 判斷指定ZNode是否存在,並設置是否Watch這個ZNode。這裡如果要設置Watcher的話,Watcher是在創建ZooKeeper實例時指定的,如果要設置特定的Watcher的話,可以調用另一個重載版本的exists(path, watcher)。以下幾個帶watch參數的API也都類似

getData(path, watch): 讀取指定ZNode上的數據,並設置是否watch這個ZNode

setData(path, watch): 更新指定ZNode的數據,並設置是否Watch這個ZNode

getChildren(path, watch): 獲取指定ZNode的所有子ZNode的名字,並設置是否Watch這個ZNode

sync(path): 把所有在sync之前的更新操作都進行同步,達到每個請求都在半數以上的ZooKeeper Server上生效。path參數目前沒有用

setAcl(path, acl): 設置指定ZNode的Acl信息

getAcl(path): 獲取指定ZNode的Acl信息

5 ZooKeeper的典型應用場景

典型應用場景

1)數據發布/訂閱

目的:動態獲取數據,來實現配置信息的集中式管理和數據的動態更新Zookeeper採用設計模式:推拉相結合(客戶端向服務端註冊自己需要關注的節點,一旦該節點數據發生變更,那麼服務端就會向相應的客戶端發送Watcher事件通知,客戶端接到消息後,主動到服務端獲取最新的數據)

例:

(1).將應用中的配置信息放到ZK上集中處理,通常應用初始化時主動獲取所需配置信息,並在相對應的節點註冊Watcher,以後配置信息每發生變更一次,就通知相應的訂閱的客戶端,客戶端完成從節點獲取最新的配置信息。

(2).分散式搜索服務中,索引元信息和伺服器集羣機器的節點狀態存儲在指定的ZK節點中,供客戶端的訂閱使用

(3).分散式日誌收集系統,將應用日誌以應用為任務單元收集日誌,在ZK上以應用名為節點,把該應用的伺服器IP做為子節點,當應用伺服器出現宕機或伺服器發生變化時,通知日誌收集器,日誌收集器獲得最新的伺服器信息,來實現收集日誌的任務。

2) 負載均衡

目的:通常同一個應用或同一個服務的提供方都會部署多份,達到對等服務。而消費者就須要在這些對等的伺服器中選擇一個來執行相關的業務邏輯,其中比較典型的是消息中間件中的生產者,消費者負載均衡。

例:

生產者負載均衡:metaq發送消息的時候,生產者在發送消息的時候必須選擇一臺broker上的一個分區來發送消息,因此metaq在運行過程中,會把所有broker和對應的分區信息全部註冊到ZK指定節點上,默認的策略是一個依次輪詢的過程,生產者在通過ZK獲取分區列表之後,會按照brokerId和partition的順序排列組織成一個有序的分區列表,發送的時候按照從頭到尾循環往複的方式選擇一個分區來發送消息。

3)命名服務

目的:通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源的實體、服務地址和提供者的信息。

例:

(1).分散式任務調度系統中,通過調用Zookeeper節點創建API中的順序節點創建,返回全局唯一的命名,且可得到節點創建的順序。

4)分散式協調/通知

目的:將不同的分散式組件有機結合起來,協調分散式系統的全局運行流程

例:將需要互相協調的分散式系統組件註冊在ZK同一節點上,並對該節點註冊Wathcher,當其中一個組件更新節點信息時,其他節點將收到信息,並作出相應的處理。

5) 集羣管理

目的:為了靈活的管理大規模的集羣中機器的運行狀態,統計宕機率等

例:在線雲主機管理,首先將應用部署到這些機器上,在ZK上的機器列表節點下面創建臨時子節點,機器列表節點發出「子節點變更的」的消息,

6) Master選舉

目的:避免重複勞動,提高集羣的性能,讓集羣中的單機或部分集羣去完成耗時操作。

例:海量數據處理模型,用ZK強一致性選舉出master,並讓他處理耗時的海量數據,其餘客戶端在該節點註冊Watcher,監控master的存活。

7)分散式鎖

目的:分散式鎖的實現包括獨佔和控制時序

8)分散式隊列

隊列包括先進先出(FIFO)隊列和隊列成員聚齊

例如:

分散式環境中,一個大任務TaskA,需要在很多子任務完成(或條件就緒)情況下才能進行。這個時候,凡是其中一個子任務完成(就緒),那麼就去 /taskList 下建立自己的臨時時序節點(CreateMode.EPHEMERAL_SEQUENTIAL),當 /taskList 發現自己下面的子節點滿足指定個數,就可以進行下一步按序進行處理了。


推薦閱讀:
相關文章