ZooKeeper 基礎知識、部署和應用程式
簡介
讓我們首先討論一下為什麼想使用 ZooKeeper
。ZooKeeper
是一個面向分散式系統的構建塊。當設計一個分散式系統時,一般需要設計和開發一些協調服務:
- 名稱服務— 名稱服務是將一個名稱對映到與該名稱有關聯的一些資訊的服務。電話目錄是將人的名字對映到其電話號碼的一個名稱服務。同樣,
DNS
服務也是一個名稱服務,它將一個域名對映到一個IP
地址。在分散式系統中,您可能想跟蹤哪些伺服器或服務在執行,並通過名稱檢視其狀態。ZooKeeper
暴露了一個簡單的介面來完成此工作。也可以將名稱服務擴充套件到組成員服務,這樣就可以獲得與正在查詢其名稱的實體有關聯的組的資訊。 - 鎖定— 為了允許在分散式系統中對共享資源進行有序的訪問,可能需要實現分散式互斥(
distributed mutexes
)。ZooKeeper
提供一種簡單的方式來實現它們。 - 同步— 與互斥同時出現的是同步訪問共享資源的需求。無論是實現一個生產者-消費者佇列,還是實現一個障礙,
ZooKeeper
都提供一個簡單的介面來實現該操作。您可以在Apache ZooKeeper
維基上檢視示例,瞭解如何做到這一點(參閱 參考資料)。 - 配置管理— 您可以使用
ZooKeeper
集中儲存和管理分散式系統的配置。這意味著,所有新加入的節點都將在加入系統後就可以立即使用來自ZooKeeper
的最新集中式配置。這還允許您通過其中一個ZooKeeper
客戶端更改集中式配置,集中地更改分散式系統的狀態。 - 領導者選舉— 分散式系統可能必須處理節點停機的問題,您可能想實現一個自動故障轉移策略。
ZooKeeper
通過領導者選舉對此提供現成的支援。
雖然可以從頭開始設計和實現所有這些服務,但除錯任何問題、競爭條件或死鎖都需要執行額外的工作,並且很難實現。就像您不會在程式碼中隨處編寫自己的隨機數發生器或雜湊函式一樣,這裡有一個要求:人們不應該在每次有需要時就到處從頭編寫自己的名稱服務或領導者選舉服務。此外,您可以相對容易地一起解決一個非常簡單的組成員服務,但是,要編寫它們來提供可靠性、複製和可擴充套件性,可能需要做更多的工作。這導致了 Apache ZooKeeper
的開發和開源,Apache ZooKeeper
是一個針對分散式系統的、開箱即用的、可靠的、可擴充套件的、高效能的協調服務。
InfoSphere® BigInsights™ Quick Start Edition
是 IBM
的大資料產品,以開源的 Apache Hadoop
專案為基礎。它包括 ZooKeeper
和其他大資料技術,以及增加了該平臺的價值的 IBM
技術。在本文中,我們只是使用了 ZooKeeper
,但是,如欲瞭解有關 InfoSphere BigInsights
的更多資訊,請參閱 參考資料,其中包括一個下載產品的連結。
ZooKeeper
雖然是一個針對分散式系統的協調服務,但它本身也是一個分散式應用程式。ZooKeeper
遵循一個簡單的客戶端-伺服器模型,其中客戶端 是使用服務的節點(即機器),而伺服器 是提供服務的節點。ZooKeeper
伺服器的集合形成了一個 ZooKeeper
集合體(ensemble
)。在任何給定的時間內,一個 ZooKeeper
客戶端可連線到一個 ZooKeeper
伺服器。每個 ZooKeeper
伺服器都可以同時處理大量客戶端連線。每個客戶端定期傳送 ping
到它所連線的 ZooKeeper
伺服器,讓伺服器知道它處於活動和連線狀態。被詢問的 ZooKeeper
伺服器通過 ping
確認進行響應,表示伺服器也處於活動狀態。如果客戶端在指定時間內沒有收到伺服器的確認,那麼客戶端會連線到集合體中的另一臺伺服器,而且客戶端會話會被透明地轉移到新的 ZooKeeper
伺服器。
圖 1 描述了 ZooKeeper
的客戶端-伺服器架構。
ZooKeeper
有一個類似於檔案系統的資料模型,由 znodes
組成。可以將 znodes
(ZooKeeper
資料節點)視為類似 UNIX
的傳統系統中的檔案,但它們可以有子節點。另一種方式是將它們視為目錄,它們可以有與其相關的資料。每個這些目錄都被稱為一個 znode
。圖 2 顯示的圖代表與兩個城市中的運動隊相同的層次結構。
圖 2. 該圖表示了兩個城市中的運動隊的層次結構
znode
層次結構被儲存在每個 ZooKeeper
伺服器的記憶體中。這實現了對來自客戶端的讀取操作的可擴充套件的快速響應。每個 ZooKeeper
伺服器還在磁碟上維護了一個事務日誌,記錄所有的寫入請求。因為 ZooKeeper
伺服器在返回一個成功的響應之前必須將事務同步到磁碟,所以事務日誌也是 ZooKeeper
中對效能最重要的組成部分。可以儲存在 znode
中的資料的預設最大大小為 1 MB。因此,即使 ZooKeeper
的層次結構看起來與檔案系統相似,也不應該將它用作一個通用的檔案系統。相反,應該只將它用作少量資料的儲存機制,以便為分散式應用程式提供可靠性、可用性和協調。
當客戶端請求讀取特定 znode
的內容時,讀取操作是在客戶端所連線的伺服器上進行的。因此,由於只涉及集合體中的一個伺服器,所以讀取是快速和可擴充套件的。然而,為了成功完成寫入操作,要求 ZooKeeper
集合體的嚴格意義上的多數節點都是可用的。在啟動 ZooKeeper
服務時,集合體中的某個節點被選舉為領導者。當客戶端發出一個寫入請求時,所連線的伺服器會將請求傳遞給領導者。此領導者對集合體的所有節點發出相同的寫入請求。如果嚴格意義上的多數節點(也被稱為法定數量(quorum
))成功響應該寫入請求,那麼寫入請求被視為已成功完成。然後,一個成功的返回程式碼會返回給發起寫入請求的客戶端。如果集合體中的可用節點數量未達到法定數量,那麼 ZooKeeper
服務將不起作用。
法定數量是通過嚴格意義上的多數節點來表示的。在集合體中,可以包含一個節點,但它不是一個高可用和可靠的系統。如果在集合體中有兩個節點,那麼這兩個節點都必須已經啟動並讓服務正常執行,因為兩個節點中的一個並不是嚴格意義上的多數。如果在集合體中有三個節點,即使其中一個停機了,您仍然可以獲得正常執行的服務(三個中的兩個是嚴格意義上的多數)。出於這個原因,ZooKeeper
的集合體中通常包含奇數數量的節點,因為就容錯而言,與三個節點相比,四個節點並不佔優勢,因為只要有兩個節點停機,ZooKeeper
服務就會停止。在有五個節點的叢集上,需要三個節點停機才會導致 ZooKeeper
服務停止運作。
現在,我們已經清楚地瞭解到,節點數量應該是奇數,讓我們再來思考一下 ZooKeeper
集合體中需要有多少個節點。讀取操作始終從連線到客戶端的 ZooKeeper
伺服器讀取資料,所以它們的效能不會隨著集合體中的伺服器數量額變化而變化。但是,僅在寫入法定數量的節點時,寫入操作才是成功的。這意味著,隨著在集合體中的節點數量的增加,寫入效能會下降,因為必須將寫入內容寫入到更多的伺服器中,並在更多伺服器之間進行協調。
ZooKeeper
的美妙之處在於,想執行多少伺服器完全由您自己決定。如果想執行一臺伺服器,從 ZooKeeper
的角度來看是沒問題的;只是您的系統不再是高度可靠或高度可用的。三個節點的 ZooKeeper
集合體支援在一個節點故障的情況下不丟失服務,這對於大多數使用者而言,這可能是沒問題的,也可以說是最常見的部署拓撲。不過,為了安全起見,可以在您的集合體中使用五個節點。五個節點的集合體讓您可以拿出一臺伺服器進行維護或滾動升級,並能夠在不中斷服務的情況下承受第二臺伺服器的意外故障。
因此,在 ZooKeeper
集合體中,三、五或七是最典型的節點數量。請記住,ZooKeeper
集合體的大小與分散式系統中的節點大小沒有什麼關係。分散式系統中的節點將是 ZooKeeper
集合體的客戶端,每個 ZooKeeper
伺服器都能夠以可擴充套件的方式處理大量客戶端。例如,HBase
(Hadoop
上的分散式資料庫)依賴於 ZooKeeper
實現區域伺服器的領導者選舉和租賃管理。您可以利用一個相對較少(比如說,五個)節點的 ZooKeeper
集合體執行有 50 個節點的大型 HBase
叢集。
設定並部署 ZooKeeper
集合體
現在讓我們設定並部署有三個節點的 ZooKeeper
集合體。在這裡,我們將使用撰寫本文時的最新版的 ZooKeeper:3.4.5
(請參閱 參考資料 獲得有關的下載資訊)。我們用於此演示的節點被命名為 zkserver1.mybiz.com、zkserver2.mybiz.com
和 zk3server3.mybiz.com
。必須在每個節點上遵循下面的步驟來啟動 ZooKeeper
伺服器:
- 如果尚未安裝 JDK,請下載安裝它(參閱 參考資料)。這是必需的,因為
ZooKeeper
伺服器在JVM
上執行。 - 下載
ZooKeeper 3.4.5. tar.gz tarball
並將它解壓縮到適當的位置。
清單 1. 下載ZooKeeper tarball
並將它解壓縮到適當的位置
wget
http://www.bizdirusa.com/mirrors/apache/ZooKeeper/stable/zookeeper3.4.5.
tar.gz tar xzvf zookeeper3.4.5.tar.gz
- 建立一個目錄,用它來儲存與
ZooKeeper
伺服器有關聯mkdir /var/lib/zookeeper
將這個目錄建立為根目錄,並在以後將這個目錄的所有者更改為您希望執行ZooKeeper
伺服器的使用者。 設定配置。建立或編輯
zookeeper3.4.5/conf/zoo.cfg
檔案,使其與 清單 2 相似。
清單 2. 設定配置
tickTime=2000
dataDir=/var/lib/zookeeper clientPort=2181
initLimit=5 syncLimit=2
server.1=zkserver1.mybiz.com:2888:3888
server.2=zkserver2.mybiz.com:2888:3888
server.3=zkserver3.mybiz.com:2888:3888
值得重點注意的一點是,所有三個機器都應該開啟埠2181、2888
和3888
。在本例中,埠2181
由ZooKeeper
客戶端使用,用於連線到ZooKeeper
伺服器;埠2888
由對等ZooKeeper
伺服器使用,用於互相通訊;而埠3888
用於領導者選舉。您可以選擇自己喜歡的任何埠。通常建議在所有ZooKeeper
伺服器上使用相同的埠。- 建立一個
/var/lib/zookeeper/myid
檔案。此檔案的內容將只包含zkserver1.mybiz.com
上的數字 1、zkserver2.mybiz.com
上的數字 2 和zkserver3.mybiz.com
上的數字 3。清單 3 顯示了來自zkserver1.mybiz.com
的此檔案的cat
輸出。
- 建立一個
清單 3. cat 輸出
mark@zkserver1.mybiz.com:~# cat
/var/lib/zookeeper/myid 1
現在,您已經做好了在每臺機器上啟動 ZooKeeper 伺服器的準備。
清單 4. 啟動 ZooKeeper 伺服器
zookeeper3.4.5/ bin/zkServer.sh
start
現在,您可以從其中一臺正在執行 ZooKeeper 伺服器的機器上啟動一個 CLI 客戶端。
清單 5. 啟動 CLI 客戶端
zookeeper3.4.5/ bin/zkCli.sh server
zkserver1.mybiz.com:2181,zkserver2.mybiz.com:2181,zkserver3.mybiz.com:2181
客戶端提供一個伺服器列表,可以任意選中一個進行連線。如果在連線過程中失去與該伺服器的連線,則會選中列表中的另一臺伺服器,而且客戶端會話也會轉移到該伺服器。一旦啟動了客戶端,您就可以建立、編輯和刪除 znode
。讓我們在 /mynode
建立一個znode
,使用 helloworld
作為關聯的資料。
清單 6. 在 /mynode
上建立一個 znode
[zk:127.0.0.1:2181(CONNECTED) 2] create /mynode
helloworld Created /mynode
現在,讓我們在 /mynode
驗證和檢索資料。
清單 7. 在 /mynode
驗證和檢索資料
[zk:127.0.0.1:2181(CONNECTED) 6] get /mynode
helloworld cZxid = 0x200000005 ctime = Sat Jul 20
19:53:52 PDT 2013 mZxid = 0x200000005 mtime = Sat
Jul 20 19:53:52 PDT 2013 pZxid = 0x200000005
cversion = 0 dataVersion = 0 aclVersion = 0
ephemeralOwner = 0x0 dataLength = 11 numChildren = 0
您會發現,在獲取一個 znode
資料時,客戶端也返回了一些與 znode
有關的後設資料。此後設資料中的一些重要欄位包括,與建立和最後修改 znode
的時間有關的階段時間戳(ctime
和 mtime
)、每次修改資料都會更改的資料版本(dataVersion
)、資料長度(dataLength
)、這個 znode
的子節點的數量(numChildren
)。我們現在可以刪除 znode
。
清單 8. 刪除 znode
[zk:127.0.0.1:2181(CONNECTED) 7]
rmr /mynode
讓我們在 /mysecondnode
建立另一個 znode
。
清單 9. 建立另一個 znode
[zk:127.0.0.1:2181(CONNECTED) 10] create
/mysecondnode hello Created /mysecondnode
現在,讓我們在 /mysecondnode
驗證和檢索資料。這一次,我們在最後提供了一個可選引數 1。此引數為 /mysecondnode
上的資料設定了一個一次性的觸發器(名稱為 watch
)。如果另一個客戶端在 /mysecondnode
上修改資料,該客戶端將會獲得一個非同步通知。請注意,該通知只傳送一次,除非 watch
被重新設定,否則不會因資料發生改變而再次傳送通知。
清單 10. 在 /mysecondnode
上驗證和檢索資料
[zk:127.0.0.1:2181(CONNECTED) 12] get
/mysecondnode 1 hello cZxid = 0x200000007 ctime =
Sat Jul 20 19:58:27 PDT 2013 mZxid = 0x200000007
mtime = Sat Jul 20 19:58:27 PDT 2013 pZxid =
0x200000007 cversion = 0 dataVersion = 0
aclVersion = 0 ephemeralOwner = 0x0 dataLength = 5
numChildren = 0
現在,從不同的客戶端(比如,從不同的機器)更改與 /mysecondnode
有關聯的資料的值。
清單 11. 更改與 /mysecondnode
有關聯的資料的值
[zk: localhost:2181(CONNECTED)
1] set /mysecondnode hello2 cZxid = 0x200000007
ctime = Sat Jul 20 19:58:27 PDT 2013 mZxid =
0x200000009 mtime = Sat Jul 20 20:02:37 PDT 2013
pZxid = 0x200000007 cversion = 0 dataVersion = 1
aclVersion = 0 ephemeralOwner = 0x0 dataLength = 6
numChildren = 0
您會發現,在第一個客戶端上獲得了一個 watch
通知。
清單 12. 在第一個客戶端上獲得了一個 watch
通知
[zk:127.0.0.1:2181(CONNECTED) 13] WATCHER::
WatchedEvent state:SyncConnected
type:NodeDataChanged path:/mysecondnode
繼續下去,因為 znode
形成了一個分層名稱空間,所以您還可以建立子節點。
清單 13. 建立子節點
[zk:
localhost:2181(CONNECTED) 2] create /mysecondnode/
subnode 123 Created /mysecondnode/ subnode
您可以獲得關於某個 znode
的其他統計後設資料。
清單 14. 獲得關於某個 znode
的其他統計後設資料
[zk:127.0.0.1:2181(CONNECTED)
14] stat /mysecondnode cZxid = 0x200000007 ctime =
Sat Jul 20 19:58:27 PDT 2013 mZxid = 0x200000009
mtime = Sat Jul 20 20:02:37 PDT 2013 pZxid =
0x20000000a cversion = 1 dataVersion = 1
aclVersion = 0 ephemeralOwner = 0x0 dataLength = 6
numChildren = 1
在上面的示例中,我們使用了 ZooKeeper
的 CLI
客戶端與 ZooKeeper
伺服器進行互動。ZooKeeper
提供了 Java™
、C
、Python
和其他繫結。您可以通過這些繫結呼叫客戶端 API
,將 Java
、C
或 Python
應用程式轉換為ZooKeeper
客戶端。
ZooKeeper
的應用程式
由於 ZooKeeper
在分散式系統中提供了一些多功能的用例,ZooKeeper
有一組不同的實用應用程式。我們將在這裡列出部分這些應用程式。這些應用程式大多取自 Apache ZooKeeper
維基,那裡還提供了一個更完整的最新列表。請參閱 參考資料,獲得這些技術的連結:
Apache Hadoop
依靠ZooKeeper
來實現Hadoop HDFS NameNode
的自動故障轉移,以及YARN ResourceManager
的高可用性。Apache HBase
是構建於Hadoop
之上的分散式資料庫,它使用ZooKeeper
來實現區域伺服器的主選舉(master election
)、租賃管理以及區域伺服器之間的其他通訊。Apache Accumulo
是構建於 Apache ZooKeeper(和Apache Hadoop
)之上的另一個排序分散式鍵/值儲存。Apache Solr
使用ZooKeeper
實現領導者選舉和集中式配置。Apache Mesos
是一個叢集管理器,提供了分散式應用程式之間高效的資源隔離和共享。Mesos
使用ZooKeeper
實現了容錯的、複製的主選舉。Neo4j
是一個分散式圖形資料庫,它使用ZooKeeper
寫入主選擇和讀取從協調(read slave coordination
)。Cloudera Search
使用ZooKeeper
(通過Apache Solr
)整合了搜尋功能與Apache Hadoop
,以實現集中式配置管理。
結束語
實現您自己的協議來協調分散式系統,這可能是一個令人感到沮喪的費時的過程。這正是 ZooKeeper
發揮其作用的地方。ZooKeeper
是一個穩定的、簡單的、高效能的協調服務,為您提供編寫正確的分散式應用程式所需的工具,而無需擔心競爭條件、死鎖和不一致。在下一次編寫分散式應用程式時,您就可以利用 ZooKeeper
支援所有協調需求。
相關文章
- zookeeper基礎知識分享(一)
- 應用程式基礎知識:activity和intent——Android開發祕籍IntentAndroid
- 程式基礎知識
- Docker 基礎知識 - 使用卷(volume)管理應用程式資料Docker
- 鴻蒙初學002-應用程式包基礎知識鴻蒙
- 6. Oracle開發和應用——6.1. 基礎知識Oracle
- 用例基礎知識
- 脫殼基礎知識以及簡單應用
- 程式設計基礎知識程式設計
- GMAC和PHY基礎知識Mac
- Zookeeper基礎原理&應用場景詳解
- Docker 基礎知識 - 使用 tmpfs 掛載(tmpfs mounts)管理應用程式資料Docker
- ASP.NET Core基礎知識(二)【應用啟動】ASP.NET
- 前端-html和css基礎知識前端HTMLCSS
- 基礎知識
- Docker 基礎知識 - 使用繫結掛載(bind mounts)管理應用程式資料Docker
- Android 基礎知識課程助您輕鬆構建應用Android
- Python技術基礎知識點:OS模組的應用Python
- 《java程式設計基礎》java的基礎知識(三)Java程式設計
- 網路程式設計基礎知識程式設計
- app,小程式開發基礎知識APP
- SQLAlchemy 基礎知識 - autoflush 和 autocommit(轉)SQLMIT
- javaweb-ajax和json基礎知識JavaWebJSON
- Windows應用程式基礎Windows
- Envoy基礎知識
- DockerFile基礎知識Docker
- Webpack 基礎知識Web
- js基礎知識JS
- React基礎知識React
- Docker基礎知識Docker
- qml基礎知識
- Mybatis基礎知識MyBatis
- python基礎知識Python
- Hadoop基礎知識Hadoop
- webpack基礎知識Web
- AI 基礎知識AI
- JSP基礎知識JS
- Dart基礎知識Dart