寫在前面
今天來學習Zookeeper部分的知識,之後會學習hbase的知識。
Zookeeper簡介
Zookeeper是一個高效的分散式協調服務,可以提供以下功能:
- 配置資訊管理
- 命名
- 分散式同步
- 叢集管理
- 資料庫切換等服務
它不適合用來儲存大量資訊,而是用於儲存一些配置資訊、釋出與訂閱等少量資料。以下是Zookeeper的典型應用場景:
- Hadoop
- Storm
- 訊息中介軟體
- RPC服務框架
- 分散式資料庫同步系統
Zookeeper叢集
Zookeeper叢集中節點的個數一般為奇數(>=3)。如果叢集中的Master節點掛掉,且剩餘節點數超過半數時,叢集可以透過選舉推舉新的主節點繼續對外提供服務。
客戶端發起事務請求時,事務的結果在整個Zookeeper叢集中所有機器上的應用是一致的。不會出現叢集中部分機器應用了該事務,而其他機器未應用該事務的情況。Zookeeper確保叢集中所有機器的資料模型一致。
Zookeeper能夠保證客戶端請求的順序,每個請求都會分配一個全域性唯一的遞增編號,用來反映事務操作的先後順序。
Zookeeper將全量資料儲存在記憶體中,並直接服務於所有的非事務請求。因此,在以讀操作為主的場景中,Zookeeper效能非常突出。
Zookeeper的資料結構與節點角色
Zookeeper使用的主要資料結構是樹形結構,根節點為/
。Zookeeper叢集中的節點有以下幾種身份:
- Leader:負責客戶端寫請求(writer型別的請求)。
- Follower:負責客戶端讀請求(reader型別的請求),並參與Leader選舉。
- Observer:是特殊的Follower節點,可以接收客戶端的讀請求,但不會參與選舉。Observer可以用來擴充套件系統的讀能力,提升讀取效能。
Zookeeper的設計理念
Zookeeper是一個基於觀察者模式設計的分散式服務管理框架。它負責儲存和管理相關資料,並接收觀察者的註冊。一旦這些資料的狀態發生變化,Zookeeper會通知已註冊的觀察者,以便觀察者執行相關操作。
Zookeeper的協議與一致性保障
Zookeeper使用ZAB原子廣播協議,節點之間的資料一致性演算法採用Paxos演算法,能夠保障分散式環境中資料的一致性。
ZAB(Zookeeper原子廣播協議)
詳細介紹ZAB協議
Paxos演算法
Paxos演算法解決的問題是,如何在分散式系統中就某個值(決議)達成一致。典型的應用場景包括:分散式資料庫系統中,如果各節點的初始狀態一致,且執行相同的操作序列,則它們最終會得到一致的狀態。
為了確保每個節點執行相同的命令序列,需要透過一致性演算法來保證每個節點看到的指令一致。Paxos演算法就是為了解決分散式系統中的一致性問題,它是基於訊息傳遞模型的一致性演算法。
Paxos演算法不僅可以用於分散式系統中的一致性保證,也適用於多個程序/執行緒需要達成一致的場景,包括:
- 一臺機器中多個程序/執行緒的資料一致性
- 分散式檔案系統或資料庫中的併發讀寫
- 分散式儲存中多個副本響應讀寫請求的一致性
Zookeeper全解析——Paxos作為靈魂
Zookeeper(ZK)Server最基礎的東西是什麼呢?我想應該是Paxos。因此,本文將介紹Paxos及其在ZK Server中的實現。
什麼是Paxos?
Paxos是一種基於訊息傳遞的一致性演算法,由Leslie Lamport於1990年提出,近年來被廣泛應用於分散式計算中。Google的Chubby、Apache的Zookeeper都基於Paxos的理論進行實現。Paxos被認為是目前為止唯一成熟的分散式一致性演算法,其他演算法往往是對Paxos的改進或簡化。
需要指出的是,Paxos有一個前提:沒有拜占庭將軍問題。意思是,Paxos只有在一個可信的計算環境中才能成立,這個環境不應受到入侵或破壞。
Paxos演算法的描述
Paxos描述了這樣一個場景:有一個叫做Paxos小島(Island)的地方,島上住著一批居民,他們的事務由一些特殊的人來決定,這些人被稱為議員(Senator)。議員的數量是固定的,不可更改。
島上的每次事務變更都需要透過提議(Proposal),每個提議都有一個編號(PID),這個編號是遞增的,不能倒退。每個提議必須得到超過半數議員的同意才能生效。如果某個議員收到的提議編號小於等於他當前的編號,他會拒絕該提議,並告知對方“你的提議已經有人提過了”。
這個編號是每個議員在自己的記事本上記錄的數字,隨著時間的推移,議員會更新這個編號,確保提議按照正確的順序進行。整個議會的目標是:保證所有議員對於提議達成一致的看法。
舉個例子
假設島上有三個議員:S1、S2、S3。
- S1提議將電費設定為1元/度,這時他將提議編號定為1。
- 其他議員收到S1的提議後,查詢自己的記事本,發現當前編號為0,所以接受這個提議,並記錄編號為1。
- 如果S1收到了超過半數(即2個議員)的同意,他就會宣佈“1號提議生效!”
衝突解決
假設S1和S2同時發起了提議:
- S1提議設定電費為1元/度(提議編號為1)。
- S2提議設定電費為2元/度(提議編號也是1)。
S3先收到S1的提議並同意,接著收到S2的提議,但發現S2的提議編號小於等於自己當前的編號,因此拒絕了S2的提議,S1的提議生效。
Paxos在Zookeeper中的應用
現在讓我們將Paxos的概念與Zookeeper(ZK Server)中的實現對應起來:
- 小島(Island)—— Zookeeper叢集(ZK Server Cluster)
- 議員(Senator)—— Zookeeper Server節點
- 提議(Proposal)—— ZNode的變更操作(如Create、Delete、SetData等)
- 提議編號(PID)—— Zxid(ZooKeeper事務ID)
- 正式法令 —— 所有ZNode及其資料
儘管概念對得上,但是Zookeeper中有一個特殊角色——Leader。這個角色在Paxos中並不明顯,但實際上它是解決“活鎖”問題的關鍵。Paxos的作者Leslie Lamport在《The Part-Time Parliament》中提到,只有一個總統(President)可以發出提議,以避免多個議員同時提議導致的衝突。
總統——ZK Server中的Leader
Zookeeper的Leader角色正是Paxos中的總統。在Zookeeper叢集中,Leader負責協調事務的處理並保證一致性,而Follower節點則跟隨Leader的決策。
總統選舉
總統(Leader)的選舉機制是Paxos的一部分,選舉過程可能比較複雜,Zookeeper使用Paxos來確保叢集中的Leader一致性。你可以閱讀相關部落格瞭解更多詳細資訊:如何選出總統
ZK Server的操作
讓我們透過幾個情景來更好地理解Zookeeper是如何實施Paxos演算法的。
情況一:
- 客戶端甲到某個ZK Server詢問某條法令的情況(例如ZNode的資料)。ZK Server直接檢視本地儲存(local storage),並告訴客戶端結果。ZK Server會宣告:“我的資料不一定是最新的。”如果客戶端想要最新的資料,ZK Server會同步到Leader並返回最新結果。
情況二:
- 客戶端乙到某個ZK Server請求修改資料(例如ZNode資料)。ZK Server會將該請求提交給Leader,Leader會詢問叢集中的其他ZK Server的意見。當超過半數的ZK Server同意後,Leader會發布命令,完成資料的修改,ZK Server返回給客戶端。
情況三:
- 如果ZK Server的Leader突然掛掉,其他ZK Server會發現無法聯絡上Leader。此時,ZK叢集會啟動Leader選舉,選舉出一個新的Leader。在此期間,客戶端請求會被拒絕,直到選舉完成。
總結
Paxos是Zookeeper的靈魂,它提供了分散式系統中達成一致性的基礎。透過Paxos,Zookeeper保證了在分散式環境下的一致性與容錯性。儘管Zookeeper還有其他特性(如Session、Watcher、Version等),但Paxos的核心原理仍然是理解Zookeeper工作的關鍵。
Zookeeper安裝文件
1、上傳並解壓
上傳安裝包到master並解壓
tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /usr/local/soft
# 重新命名
cd /usr/local/soft
mv apache-zookeeper-3.5.7-bin/ zookeeper-3.5.7
2、配置環境變數
vim /etc/profile
# 加入下列內容
ZOOKEEPER_HOME=/usr/local/soft/zookeeper-3.5.7
export PATH=$PATH:$ZOOKEEPER_HOME/bin
# 重新載入環境變數
source /etc/profile
3、修改配置檔案
# 切換到配置檔案目錄
cd /usr/local/soft/zookeeper-3.5.7/conf
# 複製預設配置檔案並重新命名
cp zoo_sample.cfg zoo.cfg
# 修改配置
vim zoo.cfg
# 找到dataDir並修改
dataDir=/usr/local/soft/zookeeper-3.5.7/data
# 在檔案尾部增加
server.0=master:2888:3888
server.1=node1:2888:3888
server.2=node2:2888:3888
4、新建相關目錄及檔案
cd /usr/local/soft/zookeeper-3.5.7
# 建立ZK資料存放位置
mkdir data
cd data
# 在data目錄下建立myid檔案
touch myid
5、同步到其它節點
cd /usr/local/soft/
scp -r zookeeper-3.5.7 node1:`pwd`
scp -r zookeeper-3.5.7 node2:`pwd`
6、配置從節點的環境變數
配置node1和node2的環境變數
同步驟2中環境變數配置一致
最後記得source
7、修改myid檔案
每臺都需修改,並且myid都不同
cd /usr/local/soft/zookeeper-3.5.7/data
vim myid
# master ---> myid --> 0
# node1 ---> myid --> 1
# node2 ---> myid --> 2
8、啟動與停止ZK
三臺都需要執行
-
啟動
zkServer.sh start
-
停止
zkServer.sh stop
-
檢視ZK狀態
透過jps可以檢視zk的程序:QuorumPeerMain
當有一個leader的時候啟動成功zkServer.sh status
9、ZK基本操作
zk 是一個目錄結構 ,每個節點可以存資料,同時可以有子節點
# 連線ZK
zkCli.sh
# 建立目錄
create /test testData
create /test/a aData
# 獲取資料
get /test
# 檢視目錄
ls /test
# 刪除節點
delete /test
# 如果節點非空
deleteall /test
10、重置zk
如遇故障,可進行重置
重置將清除ZK中所有資料,慎用!!!
-
殺掉所有zk程序
# 找到ZK的程序編號pid kill -9 {pid}
-
刪除資料
刪除data目錄下的version檔案, 所有節點都要刪除rm -rf /usr/local/soft/zookeeper-3.5.7/data/version-2
-
重新啟動zk
zkServer.sh start
11、配置啟停指令碼
1.進入指令碼執行目錄
cd /usr/local/bin
2.建立指令碼檔案
vim zk
3.新增以下內容:
#!/bin/sh
case $1 in
"start"){
for i in master node1 node2
do
echo "********$i --> zkServer.sh start **********"
ssh $i 'source /etc/profile; /usr/local/soft/zookeeper-3.8.4/bin/zkServer.sh start;exit'
done
};;
"stop"){
for i in master node1 node2
do
echo "********$i --> zkServer.sh stop **********"
ssh $i 'source /etc/profile; /usr/local/soft/zookeeper-3.8.4/bin/zkServer.sh stop;exit'
done
};;
"status"){
for i in master node1 node2
do
echo "********$i --> zkServer.sh status **********"
ssh $i 'source /etc/profile; /usr/local/soft/zookeeper-3.8.4/bin/zkServer.sh status;exit'
done
};;
"restart"){
for i in master node1 node2
do
echo "********$i --> zkServer.sh restart **********"
ssh $i 'source /etc/profile; /usr/local/soft/zookeeper-3.8.4/bin/zkServer.sh restart;exit'
done
};;
esac
4.修改檔案許可權
chmod 777 zk
5.直接執行
zk start
6.其他命令
zk stop
zk status
zk restart
今天的分享就到這了,之後會分享hbase相關的內容。