zookeeper基礎知識分享(一)

ikestu小猪發表於2024-11-12

寫在前面

今天來學習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的ChubbyApache的Zookeeper都基於Paxos的理論進行實現。Paxos被認為是目前為止唯一成熟的分散式一致性演算法,其他演算法往往是對Paxos的改進或簡化。

需要指出的是,Paxos有一個前提:沒有拜占庭將軍問題。意思是,Paxos只有在一個可信的計算環境中才能成立,這個環境不應受到入侵或破壞。

Paxos演算法的描述

Paxos描述了這樣一個場景:有一個叫做Paxos小島(Island)的地方,島上住著一批居民,他們的事務由一些特殊的人來決定,這些人被稱為議員(Senator)。議員的數量是固定的,不可更改。

島上的每次事務變更都需要透過提議(Proposal),每個提議都有一個編號(PID),這個編號是遞增的,不能倒退。每個提議必須得到超過半數議員的同意才能生效。如果某個議員收到的提議編號小於等於他當前的編號,他會拒絕該提議,並告知對方“你的提議已經有人提過了”。

這個編號是每個議員在自己的記事本上記錄的數字,隨著時間的推移,議員會更新這個編號,確保提議按照正確的順序進行。整個議會的目標是:保證所有議員對於提議達成一致的看法

舉個例子

假設島上有三個議員:S1S2S3

  • 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相關的內容。

相關文章