首頁 > 軟體

ZooKeeper分散式協調服務設計核心概念及安裝設定

2022-03-21 19:01:52

一、ZooKeeper 簡介

ZooKeeper 是一個開源的分散式協調服務,目前由 Apache 進行維護。ZooKeeper 可以用於實現分散式系統中常見的釋出/訂閱、負載均衡、命令服務、分散式協調/通知、叢集管理、Master 選舉、分散式鎖和分散式佇列等功能。 它具有以下特性:

順序一致性: 來自使用者端的更新操作將會按照順序被應用;
 

原子性: 即要麼全部更新成功,要麼要不更新失敗,沒有部分的結果;
 

統一的系統映象: 即不管使用者端連線的是哪臺伺服器,都能看到同樣的服務檢視(也就是無狀態的)
 

可靠性: 一旦寫入操作被執行,那麼這個狀態將會被持久化,直到其它使用者端的修改生效。
 

實時性: 一旦一個事務被成功應用,ZooKeeper 可以保證使用者端立即讀取到這個事務變更後的最新狀態的資料。

1.ZooKeeper 設計目標

  • ZooKeeper 致力於為那些高吞吐的大型分散式系統提供一個高效能、高可用、且具有嚴格順序存取控制能力的分散式協調服務。

1)簡單的資料模型:

ZooKeeper 通過樹形結構來儲存資料,它由一系列被稱為 ZNode 的資料節點組成,類似於常見的檔案系統;

不過和常見的檔案系統不同,ZooKeeper 將資料全量儲存在記憶體中,以此來實現高吞吐,減少存取延遲。

2)可設定 Cluster:

為了保證高可用,最好是以叢集形態部署 ZooKeeper,這樣只要叢集中大部分機器是可用的,那麼 ZooKeeper 本身仍然可用。

上圖中每一個 Server 代表一個安裝 ZooKeeper 服務的伺服器,組成 ZooKeeper 服務的伺服器都會在記憶體中維護當前的伺服器狀態,並且每臺伺服器間都保持著通訊。並通過 Zab 協定來保持資料的一致性。

3)順序存取:

對於來自使用者端的每個更新請求,ZooKeeper 都會分配一個全域性唯一的遞增 ID,這個 ID 決定了所有事務操作的先後順序。

4)高效能高可用

ZooKeeper 將資料全量儲存在記憶體中以保持高效能,並通過服務叢集來實現高可用;由於 ZooKeeper 的所有更新和刪除都是基於事務的,所以其在讀多寫少的應用場景中有著很高的效能表現。

2.核心概念

Cluster 角色:

角色作用
Leader提供讀寫服務,並維護叢集狀態(經過選舉產生)
Follower提供讀寫服務,並定期向 Leader 彙報自己的節點狀態(同時也參加 過半寫成功 的策略和 Leader 的選舉)
OBServer提供讀寫服務,並定期向 Leader 彙報自己的節點狀態(因為不參加策略和選舉,所以可以在不影響寫效能的情況下提升叢集的讀效能)

1)Session 對談

當 Client 通過 TCP 長連線 連線到 ZooKeeper 伺服器時,Session 便開始建立連線,並通過 tickTime(心跳檢測)機制來保持有效的對談狀態。通過這個連線,Client 可以傳送請求並接收響應,同時也可以接收到 Watch 事件的通知。

另外,當由於網路故障或者 Client 主動斷開等原因,導致連線斷開,此時只要在對談超時時間之內重新建立連線,則之間建立的對談依然有效。(這個取決於 tickTime 設定)

2)資料節點

ZooKeeper 資料模型是由一系列基本資料單元 ZNode(資料節點)組成的節點樹,其中根節點為 /(每個節點上都會儲存自己的資料和節點資訊);ZooKeeper 中的節點可以分為兩大類:

持久節點: 節點一旦建立,除非被主動刪除,否則一直存在。

臨時節點: 一旦建立該節點的使用者端對談(Session)失效,則所有該使用者端建立的臨時節點都會被刪除。

3)Watcher

ZooKeeper 中一個常用的功能是 Watcher(事件監聽器),它允許使用者在指定節點上針對感興趣的事件註冊監聽,當事件發生時,監聽器會被觸發,並將事件推播到使用者端。該機制是 ZooKeeper 實現分散式協調服務的重要特性。

4)ACL

命令作用
create可以進行建立操作
read可以進行檢視操作
write可以對建立的內容進行寫入操作
delete可以進行刪除操作
admin可以進行設定許可權操作

命令作用create可以進行建立操作read可以進行檢視操作write可以對建立的內容進行寫入操作delete可以進行刪除操作admin可以進行設定許可權操作

3.Zab 協定介紹

Zab(ZooKeeper Atomic Broadcast 原子廣播)協定是為分散式協調服務 ZooKeeper 專門設計的一種 支援崩潰恢復的原子廣播協定;

在 ZooKeeper 中,主要依賴 Zab 協定來實現分散式資料一致性;

基於 Zab 協定,ZooKeeper 實現了一種主備模式的系統架構來保持叢集中各個副本間的資料一致性。

二、ZooKeeper Cluster 安裝

準備工作:

主機名作業系統IP 地址
ZooKeeperCentOS 7.4192.168.1.1

安裝 JDK:下載地址(需要建立 Oracle 賬號)

[root@ZooKeeper ~]# ls
anaconda-ks.cfg  jdk-8u181-linux-x64.tar.gz
[root@ZooKeeper ~]# tar zxf jdk-8u181-linux-x64.tar.gz 
[root@ZooKeeper ~]# ls
anaconda-ks.cfg  jdk1.8.0_181  jdk-8u181-linux-x64.tar.gz
[root@ZooKeeper ~]# mv jdk1.8.0_181 /usr/local/java
[root@ZooKeeper ~]# cat <<END >> /etc/profile
export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin
END
[root@ZooKeeper ~]# source /etc/profile
[root@ZooKeeper ~]# java -version

1.安裝 ZooKeeper

[root@ZooKeeper ~]# wget http://dlcdn.apache.org/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz
[root@ZooKeeper ~]# ls
anaconda-ks.cfg  apache-zookeeper-3.6.3-bin.tar.gz  jdk-8u181-linux-x64.tar.gz
[root@ZooKeeper ~]# tar zxf apache-zookeeper-3.6.3-bin.tar.gz
[root@ZooKeeper ~]# mv apache-zookeeper-3.6.3-bin /usr/local/zookeeper
[root@ZooKeeper ~]# mkdir /usr/local/zookeeper/data
[root@ZooKeeper ~]# cat <<END >> /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/zookeeper/data
clientPort=2181
END

註解:

tickTime:Client 和伺服器間的通訊對談限制(相當於健康檢查,tickTime 的時間為 ms (1s = 1000ms))

initLimit:Leader 和 Follower 間初始通訊限制。

syncLimit:Leader 和 Follower 間同步通訊限制(當響應時間超於 syncLimit * tickTime 時,Leader 便會將 Follower 進行移除)

dataDir:此目錄用於存放儲存在記憶體資料庫中的快照資訊(當未設定 dataLogDir 引數時,紀錄檔資訊也會存放到此目錄)

clientPort:ZooKeeper 監聽的埠,用於使用者端連線使用。

啟動 ZooKeeper

[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh start						# 啟動
[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh status						# 檢視狀態

連線到 ZooKeeper

[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
Welcome to ZooKeeper!
JLine support is enabled
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: 127.0.0.1:2181(CONNECTED) 0] 

當連線成功後,系統會輸出 ZooKeeper 的相關設定資訊和相關環境,並在螢幕上輸出 Welcome to ZooKeeper! 等資訊。

2.使用 Golang 連線 ZooKeeper 的 API 介面

安裝 Golang

[root@ZooKeeper ~]# git clone https://github.com/samuel/go-zookeeper.git
[root@ZooKeeper ~]# mv go-zookeeper /usr/local/go/src/
package main
import (
    "fmt"
    "time"
    "go-zookeeper/zk"
)
func main() {
    Hosts := []string{"192.168.1.1:2181"}
    conn, _, err := zk.Connect(Hosts,time.Second * 5)
    defer conn.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
}

通過 Golang 實現對 ZooKeeper 的增刪改查:

package main
import (
    "fmt"
    "time"
    "go-zookeeper/zk"
)
var (
    path = "/Zzz"
)
//增
func add(conn *zk.Conn) {
    var data = []byte("Hello ZooKeeper")
    // flags 的四種取值方式:
    // 0 (永久.除非手動刪除)
    // zk.FlagEphemeral = 1 (短暫. session 斷開則該節點也被刪除)
    // zk.FlagSequence = 2 (會自動在節點後面新增序號)
    // 3 (Ephemeral 和 Sequence. 即短暫且自動新增序號)
	var flags int32 = 0
	// 獲取存取控制許可權
	acls := zk.WorldACL(zk.PermAll)
	create, err := conn.Create(path,data,flags,acls)
	if err != nil {
	    fmt.Printf("建立失敗: %vn",err)
		return
    }
	fmt.Printf("建立: %v 成功n",create)
}
// 查
func get(conn *zk.Conn) {
    data, _, err := conn.Get(path)
	if err != nil {
	    fmt.Printf("查詢 %s 失敗,err: %vn",path,err)
	    return
	}
	fmt.Printf("%s 的值為 %sn",path,string(data))
}
// 刪除與增加不同在於其函數中的 Version 引數. 其中 Version 使用 CAS 支援 (可以通過此種方式保證原子性)
// 改
func modify(conn *zk.Conn) {
    new_data := []byte("This is ZooKeeper")
    _, sate, _ := conn.Get(path)
    _, err := conn.Set(path,new_data,sate.Version)
    if err != nil {
	    fmt.Printf("資料修改失敗: %vn",err)
	    return
    }
    fmt.Println("資料修改成功")
}
// 刪
func del(conn *zk.Conn) {
    _, sate, _ := conn.Get(path)
    err := conn.Delete(path,sate.Version)
    if err != nil {
        fmt.Printf("資料刪除失敗: %vn",err)
	    return
    }
    fmt.Println("資料刪除成功")
}
func main() {
    hosts := []string{"192.168.1.1:2181"}
    conn, _, err := zk.Connect(hosts,time.Second * 5)
    defer conn.Close()
    if err != nil {
        fmt.Println(err)
	    return
    }
    /* 增刪改查 */
    add(conn)
    get(conn)
    modify(conn)
    get(conn)
    del(conn)
}

3.設定 ZooKeeper Cluster

在原來的基礎上,在增加兩臺伺服器:

主機名作業系統IP 地址
ZooKeeper-2CentOS 7.4192.168.1.2
ZooKeeper-3CentOS 7.4192.168.1.3

1)將 Java 和 ZooKeeper 傳給新的伺服器:

[root@ZooKeeper ~]# scp -r /usr/local/java root@192.168.1.2:/usr/local/
[root@ZooKeeper ~]# scp -r /usr/local/zookeeper root@192.168.1.2:/usr/local/

2)在新的伺服器上啟動 ZooKeeper:

[root@ZooKeeper ~]# cat <<END >> /etc/profile
export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin
END
[root@ZooKeeper ~]# source /etc/profile
[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh start

3)設定 Cluster 叢集(三臺伺服器上操作一樣)

[root@ZooKeeper ~]# cat <<END >> /usr/local/zookeeper/conf/zoo.cfg
server.1=192.168.1.1:2888:3888
server.2=192.168.1.2:2889:3889
server.3=192.168.1.3:2890:3890
END

4)建立 myid 檔案

[root@ZooKeeper ~]# echo "1" > /usr/local/zookeeper/data/myid
[root@ZooKeeper-2 ~]# echo "2" > /usr/local/zookeeper/data/myid
[root@ZooKeeper-2 ~]# echo "3" > /usr/local/zookeeper/data/myid

需要確保每臺伺服器的 myid 檔案中數位不同,並且和自己所在機器的 zoo.cfgserver.id=host:port:portid 值一樣。

另外,id 的範圍是 1 ~ 255

5)重啟 ZooKeeper 服務

[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh restart			# 三臺伺服器都要重啟

檢視 ZooKeeper 狀態:

驗證:

以上就是ZooKeeper分散式協調服務設計核心概念及安裝設定的詳細內容,更多關於ZooKeeper分散式協調服務核心安裝設定的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com