天天看點

Zookeeper總結Zookeeper

覺得有幫助的,請多多支援部落客,點贊關注哦~

文章目錄

  • Zookeeper
    • 一、Zookeeper概述
      • 1、概述
      • 2、特點
      • 3、資料結構
      • 4、應用場景
      • 5、下載下傳位址
    • 二、Zookeeper 安裝
      • 1、本地模式安裝部署
        • 1.1、前置準備
        • 1.2、安裝配置
        • 1.3、啟動Zookeeper
      • 2、zoo.cfg 檔案中配置參數解讀
    • 三、Zookeeper 内部原理
      • 1、選舉機制
      • 2、節點類型
      • 3、stat 結構體
      • 4、監聽器原理
        • 4.1、監聽原理詳解
        • 4.2、常見的監聽
      • 5、寫資料流程
    • 四、Zookeeper分布式安裝部署
      • 1、叢集規劃
      • 2、解壓安裝
      • 3、配置 zoo.cfg 檔案
      • 4、叢集操作
      • 5、啟動zookeeper叢集
      • 6、檢視狀态
    • 五、用戶端指令行操作
      • 1、stat擷取指定節點的狀态資訊 status
      • 2、Is某節點下的所有子節點
      • 3、Is2是Is和stat兩個指令的結合
      • 4、create建立節點
      • 5、修改節點上的資料内容
      • 6、删除節點
      • 7、deleteall遞歸删除節點
      • 8、Znode節點的ACL權限
    • 六、Zookeeper API應用
      • 1、引入依賴
      • 2、代碼測試

Zookeeper

一、Zookeeper概述

1、概述

  1. Zookeeper 是一個開源的分布式的,為分布式應用提供協調服務的 Apache 項目。
  2. Zookeeper 從設計模式角度來了解:是一個基于觀察者模式設計的分布式服務管理架構,它負責存儲和管理大家都關心的資料,然後接受觀察者的注冊,一旦這些資料的狀态發生變化,Zookeeper 就将負責通知已經在 Zookeeper 上注冊的那些觀察者做出相應的反應,進而實作叢集中類似 Master/Slave 管理模式
  3. 主要有:主從模式、監聽模式。
  4. Zookeeper=檔案系統+通知機制
  5. Zookeeper維護一個類似檔案系統的資料結構。

2、特點

  1. Zookeeper:一個上司者(leader),多個跟随者(follower)組成的叢集。
  2. Leader 負責進行投票的發起和決議,更新系統狀态
  3. Follower 用于接收客戶請求并向用戶端傳回結果,在選舉 Leader 過程中參與投票
  4. 叢集中隻要有半數以上節點存活,Zookeeper 叢集就能正常服務。
  5. 全局資料一緻:每個 server 儲存一份相同的資料副本,client 無論連接配接到哪個 server,資料都是一緻的。
  6. 更新請求順序進行,來自同一個 client 的更新請求按其發送順序依次執行。
  7. 資料更新原子性,一次資料更新要麼成功,要麼失敗。
  8. 實時性,在一定時間範圍内,client 能讀到最新資料。

3、資料結構

​ ZooKeeper 資料模型的結構與 Unix 檔案系統很類似,整體上可以看作是一棵樹,每個節點稱做一個 ZNode。

​ 很顯然 zookeeper 叢集自身維護了一套資料結構。這個存儲結構是一個樹形結構,其上的每一個節點,我們稱之為"znode",每一個 znode 預設能夠存儲 1MB 的資料,每個 ZNode都可以通過其路徑唯一辨別

Zookeeper總結Zookeeper

4、應用場景

提供的服務包括:分布式消息同步和協調機制、伺服器節點動态上下線、統一配置管理、負載均衡、叢集管理等。

Zookeeper總結Zookeeper
Zookeeper總結Zookeeper
Zookeeper總結Zookeeper

5、下載下傳位址

官方網站:https://zookeeper.apache.org/

Zookeeper總結Zookeeper
Zookeeper總結Zookeeper

直接下載下傳推薦連結: https://ftp.riken.jp/net/apache/zookeeper/

Zookeeper總結Zookeeper

https://ftp.riken.jp/net/apache/zookeeper/

Zookeeper總結Zookeeper

二、Zookeeper 安裝

1、本地模式安裝部署

1.1、前置準備

安裝JDK,不多說了。。之前的文章有很多遍。
           

1.2、安裝配置

# 上傳到Linux
[[email protected] model]$ rz
# 解壓到model
[[email protected] model]$ tar -zxvf apache-zookeeper-3.5.7-bin -C ../model
# 重命名
[[email protected] model]$ mv apache-zookeeper-3.5.7-bin/ zookeeper-3.5.7

# 修改配置檔案zoo.cfg(類似mapred-site.xml)
# 1、建立目錄
[[email protected] zookeeper-3.5.7]$ mkdir data
# 2、進入conf
[[email protected] zookeeper-3.5.7]$ cd conf
# 3、複制zoo_sample.cfg
[[email protected] conf]$ cp zoo_sample.cfg zoo.cfg 
# 4、修改zoo.cfg
[[email protected] conf]$ vi zoo.cfg 
	dataDir=/opt/model/zookeeper-3.5.7/data
           
Zookeeper總結Zookeeper
# 配置環境變量
[[email protected] conf]$ sudo vim /etc/profile
[[email protected] conf]$ source /etc/profile
[[email protected] conf]$ echo $ZOOKEEPER_HOME
/opt/model/zookeeper-3.5.7
           
Zookeeper總結Zookeeper

1.3、啟動Zookeeper

# 啟動zookeeper
[[email protected] bin]$ zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

# 檢視程序是否啟動
[[email protected] bin]$ jps
2251 QuorumPeerMain
2317 Jps

# 檢視zookeeper狀态
[[email protected] bin]$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: standalone

# 啟動用戶端操作
[[email protected] bin]$ zkCli.sh 
# 建立node2節點
[zk: localhost:2181(CONNECTED) 0] create /node2
Created /node2
# 檢視/下節點
[zk: localhost:2181(CONNECTED) 1] ls /
[node2, zookeeper]
# 退出用戶端
[zk: localhost:2181(CONNECTED) 2] quit

# 停止zookeeper
[[email protected] bin]$ zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED

           

2、zoo.cfg 檔案中配置參數解讀

  1. tickTime:通信心跳數,Zookeeper伺服器心跳時間,機關毫秒

    Zookeeper使用的基本時間,伺服器之間或用戶端與伺服器之間維持心跳的時間間隔,也就是每個tickTime時間就會發送一個心跳,時間機關為毫秒。

    它用于心跳機制,并且設定最小的session逾時時間為兩倍心跳時間。(session的最小逾時時間是2*tickTime)

  2. initLimit:LF初始通信時限

    叢集中的follower跟随者伺服器(F)與leader上司者伺服器(L)之間初始連接配接時能容忍的最多心跳數(tickTime的數量),用它來限定叢集中的Zookeeper伺服器連接配接到Leader的時限。

    投票選舉新leader的初始化時間

    Follower在啟動過程中,會從Leader同步所有最新資料,然後确定自己能夠對外服務的起始狀态。

    Leader允許F在initLimit時間内完成這個工作。

  3. syncLimit:LF 同步通信時限

    叢集中Leader與Follower之間的最大響應時間機關,假如響應超過syncLimit * tickTime,Leader認為Follwer死掉,從伺服器清單中删除Follwer。

    在運作過程中,Leader負責與ZK叢集中所有機器進行通信,例如通過一些心跳檢測機制,來檢測機器的存活狀态。

    如果L發出心跳包在syncLimit之後,還沒有從F那收到響應,那麼就認為這個F已經不線上了。

  4. dataDir:資料檔案目錄+資料持久化路徑

    儲存記憶體資料庫快照資訊的位置,如果沒有其他說明,更新的事務日志也儲存到資料庫。

  5. clientPort:用戶端連接配接端口

    監聽用戶端連接配接的端口

三、Zookeeper 内部原理

1、選舉機制

  1. 半數機制(Paxos 協定):叢集中半數以上機器存活,叢集可用。是以 zookeeper适合裝在奇數台機器上。
  2. Zookeeper 雖然在配置檔案中并沒有指定 master 和 slave。但是,zookeeper 工作時,是有一個節點為 leader,其他則為 follower,Leader 是通過内部的選舉機制臨時産生的。
  3. 以一個簡單的例子來說明整個選舉的過程。

    假設有五台伺服器組成的 zookeeper 叢集,它們的 id 從 1-5,同時它們都是最新啟動的,也就是沒有曆史資料,在存放資料量這一點上,都是一樣的。假設這些伺服器依序啟動,來看看會發生什麼。

    Zookeeper總結Zookeeper
  • 伺服器 1 啟動,此時隻有它一台伺服器啟動了,它發出去的報沒有任何響應,是以它的選舉狀态一直是 LOOKING 狀态。
  • 伺服器 2 啟動,它與最開始啟動的伺服器 1 進行通信,互相交換自己的選舉結果,由于兩者都沒有曆史資料,是以 id 值較大的伺服器 2 勝出,但是由于沒有達到超過半數以上的伺服器都同意選舉它(這個例子中的半數以上是 3),是以伺服器 1、2 還是繼續保持LOOKING 狀态。
  • 伺服器 3 啟動,根據前面的理論分析,伺服器 3 成為伺服器 1、2、3 中的老大,而與上面不同的是,此時有三台伺服器選舉了它,是以它成為了這次選舉的 leader。
  • 伺服器 4 啟動,根據前面的分析,理論上伺服器 4 應該是伺服器 1、2、3、4 中最大的,但是由于前面已經有半數以上的伺服器選舉了伺服器 3,是以它隻能接收當小弟的命了。
  • 伺服器 5 啟動,同 4 一樣當小弟。

2、節點類型

1、Znode 有兩種類型:

  1. 短暫(ephemeral):用戶端和伺服器端斷開連接配接後,建立的節點自己删除
  2. 持久(persistent):用戶端和伺服器端斷開連接配接後,建立的節點不删除

2、Znode 有四種形式的目錄節點(預設是 persistent )

  1. 持久化目錄節點(PERSISTENT)

    用戶端與 zookeeper 斷開連接配接後,該節點依舊存在

  2. 持久化順序編号目錄節點(PERSISTENT_SEQUENTIAL)

    用戶端與 zookeeper 斷開連接配接後,該節點依舊存在,隻是 Zookeeper 給該節點名稱進行順序編号

  3. 臨時目錄節點(EPHEMERAL)

    用戶端與 zookeeper 斷開連接配接後,該節點被删除

  4. 臨時順序編号目錄節點(EPHEMERAL_SEQUENTIAL)

    用戶端與 zookeeper 斷開連接配接後,該節點被删除,隻是 Zookeeper 給該節點名稱進行順序編号

Zookeeper總結Zookeeper

3、建立 znode 時設定順序辨別,znode 名稱後會附加一個值,順序号是一個單調遞增的計數器,由父節點維護

4、在分布式系統中,順序号可以被用于為所有的事件進行全局排序,這樣用戶端可以通過順序号推斷事件的順序

3、stat 結構體

  • 1)czxid- 引起這個 znode 建立的 zxid,建立節點的事務的 zxid每次修改 ZooKeeper 狀态都會收到一個 zxid 形式的時間戳,也就是 ZooKeeper 事務 ID。

    事務 ID 是 ZooKeeper 中所有修改總的次序。每個修改都有唯一的 zxid,如果 zxid1 小于 zxid2,那麼 zxid1 在 zxid2 之前發生。

  • 2)ctime - znode 被建立的毫秒數(從 1970 年開始)
  • 3)mzxid - znode 最後更新的 zxid
  • 4)mtime - znode 最後修改的毫秒數(從 1970 年開始)
  • 5)pZxid-znode 最後更新的子節點 zxid
  • 6)cversion - znode 子節點變化号,znode 子節點修改次數
  • 7)dataversion - znode 資料變化号
  • 8)aclVersion - znode 通路控制清單的變化号
  • 9)ephemeralOwner- 如果是臨時節點,這個是 znode 擁有者的 session id。如果不是臨時節點則是 0。
  • 10)dataLength- znode 的資料長度
  • 11)numChildren - znode 子節點數量

4、監聽器原理

Zookeeper總結Zookeeper

4.1、監聽原理詳解

  1. 首先要有一個 main()線程
  2. 在 main 線程中建立 Zookeeper 用戶端,這時就會建立兩個線程,一個負責網絡連接配接通信(connet),一個負責監聽(listener)。
  3. 通過 connect 線程将注冊的監聽事件發送給 Zookeeper。
  4. 在 Zookeeper 的注冊監聽器清單中将注冊的監聽事件添加到清單中。
  5. Zookeeper 監聽到有資料或路徑變化,就會将這個消息發送給 listener 線程。
  6. listener 線程内部調用了 process()方法。

4.2、常見的監聽

  1. 監聽節點資料的變化:get path [watch](過時);get -s -w path(推薦)
  2. 監聽子節點增減的變化:ls path [watch](過時);ls -w path(推薦)

5、寫資料流程

Zookeeper總結Zookeeper

ZooKeeper 的寫資料流程主要分為以下幾步:

  1. 比如 Client 向 ZooKeeper 的 Server1 上寫資料,發送一個寫請求。
  2. 如果 Server1 不是 Leader,那麼 Server1 會把接受到的請求進一步轉發給 Leader,因為每個 ZooKeeper 的 Server 裡面有一個是 Leader。這個 Leader 會将寫請求廣播給各個Server,比如 Server1 和 Server2, 各個 Server 寫成功後就會通知 Leader。
  3. 當 Leader 收到大多數 Server 資料寫成功了,那麼就說明資料寫成功了。如果這裡三個節點的話,隻要有兩個節點資料寫成功了,那麼就認為資料寫成功了。寫成功之後,Leader 會告訴 Server1 資料寫成功了。
  4. Server1 會進一步通知 Client 資料寫成功了,這時就認為整個寫操作成功。ZooKeeper整個寫資料流程就是這樣的。

四、Zookeeper分布式安裝部署

1、叢集規劃

在 biubiubiu01、biubiubiu02和 biubiubiu03三個節點上部署 Zookeeper。

首先隻在biubiubiu01上部署,完畢後,分發到biubiubiu02、biubiubiu03。

2、解壓安裝

# 操作biubiubiu01
# 上傳zookeeper檔案
[[email protected] software]$ rz
# 解壓到model下
[[email protected] software]$ tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C ../model
# 重命名
[[email protected] model]$ mv apache-zookeeper-3.5.7-bin.tar.gz zookeeper-3.5.7
# 建立檔案夾data
[[email protected] zookeeper-3.5.7]$ mkdir data

           

3、配置 zoo.cfg 檔案

# 複制/opt/model/zookeeper-3.5.7/conf 這個目錄下的 zoo_sample.cfg 為 zoo.cfg
[[email protected] conf]$ cp zoo_sample.cfg zoo.cfg 
# 修改zoo.cfg
[[email protected] conf]$ vi zoo.cfg 
dataDir=/opt/model/zookeeper-3.5.7/data
# zookeeper叢集配置
server.1=biubiubiu01:2888:3888
server.2=biubiubiu02:2888:3888
server.3=biubiubiu03:2888:3888

           
Zookeeper總結Zookeeper

配置參數解讀:

Server.A=B:C:D。

  • A 是一個數字,表示這個是第幾号伺服器;
  • B 是這個伺服器的 ip 位址;
  • C 是這個伺服器與叢集中的 Leader 伺服器交換資訊的端口;
  • D 是萬一叢集中的 Leader 伺服器挂了,需要一個端口來重新進行選舉,選出一個新的Leader,而這個端口就是用來執行選舉時伺服器互相通信的端口。

叢集模式下配置一個檔案 myid,這個檔案在 data目錄下,這個檔案裡面有一個資料就是 A 的值,Zookeeper 啟動時讀取此檔案,拿到裡面的資料與 zoo.cfg 裡面的配置資訊比較進而判斷到底是哪個 server。

4、叢集操作

# 在data下建立myid檔案并添加資料1(重要!資料可以随便寫,
# 但是必須與檔案中添加的server對應的編号:如1相同,必須有序123、246...)
[[email protected] data]$ vi myid
1

# 将biubiubiu01配置好的zookeeper下發到biubiubiu02、biubiubiu03
[[email protected] model]$ scp -r zookeeper-3.5.7/ biubiubiu02:/opt/model
[[email protected] model]$ scp -r zookeeper-3.5.7/ biubiubiu03:/opt/model
# 注意:必須分别修改 myid 檔案中内容為 2、3
# 啟動前,可以分别配置一下環境變量,友善使用。
# 不要忘了source
           
Zookeeper總結Zookeeper

5、啟動zookeeper叢集

# 分别啟動zookeeper
[[email protected] model]$ zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[[email protected] data]$ zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[[email protected] data]$ zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

# 分别jsp
[[email protected] model]$ jps
3361 Jps
3318 QuorumPeerMain

           

6、檢視狀态

# 檢視狀态:誰是leader,誰是follower
[[email protected] model]$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower

[[email protected] data]$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader

[[email protected] data]$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/model/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower

           

五、用戶端指令行操作

詳細了解參數,見上邊 stat 結構體。

指令基本文法 功能描述
help 顯示所有操作指令
ls [-w] path 使用 ls 指令來檢視目前路徑下所有子節點[-w:監聽]

ls2 path [watch] (舊)

== ls -s -w path(新)

檢視目前節點資料并能看到更新次數等資料[-w監聽]
create [-s] [-e] path data 普通建立:-s 順序節點;-e 臨時節點;path 路徑;data 資料

get path [watch] (舊)

==get -s -w path (新)

獲得節點的資料值[-w監聽節點資料的變化]
set path data 設定節點的具體值
stat path 檢視節點狀态
delete path [version] 删除指定路徑節點,若有子節點,必須先删子節點
rmr path(舊)==deleteall path 遞歸删除

1、stat擷取指定節點的狀态資訊 status

Zookeeper總結Zookeeper

2、Is某節點下的所有子節點

Zookeeper總結Zookeeper

3、Is2是Is和stat兩個指令的結合

Zookeeper總結Zookeeper

4、create建立節點

Zookeeper總結Zookeeper

5、修改節點上的資料内容

Zookeeper總結Zookeeper

6、删除節點

Zookeeper總結Zookeeper

7、deleteall遞歸删除節點

Zookeeper總結Zookeeper

8、Znode節點的ACL權限

傳統的linux檔案操作:檔案操作的指令+權限指令(chmod、chown)
zookeeper的權限操作(ACL:access  control   list):
1)節點能進行什麼操作:create、read、write、delete(前4個是對目前節點) 、admin(子節點)
2)身份的認證(4種方式):
	wor1d:預設方式,相當于全世界都能通路
	auth:代表已經認證通過的使用者
	digest:即使用者名:密碼這種方式認證
	ip:使用Ip位址認證

檢視某個節點的資料資訊:    get   path
檢視某個節點的權限資訊:  getAcl  path

基于auth的方式授權:2步
1)建立使用者
     addauth  digest   使用者名:密碼
2)給對應的path賦權限:
	 setAcl  路徑   auth:使用者名:密碼:crdwa

基于ip:setAcl /node03 ip: 127.0.0.1:cdrwa,192.168.159.191:cr,192.168.159.192:rw
           
Zookeeper總結Zookeeper
Zookeeper總結Zookeeper

六、Zookeeper API應用

1、引入依賴

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.5.7</version>
        </dependency>

    </dependencies>
           

2、代碼測試

package com.biubiubiu;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.util.List;

public class TestZookeeper {
    public static void main(String[] args) throws Exception {
        //1)建立ZookeeperClient
        //sessionTimeout容忍時間,如果超過這個時間沒有連接配接到zk叢集,則會報異常,可以根據機器配置适當延長時間。
        ZooKeeper zkClient = new ZooKeeper("192.168.153.231:2181,192.168.153.232:2181,192.168.153.233:2181", 5000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                //根據實際情況
                System.out.println("執行watcher:" + event.getType() + ",path:" + event.getPath() + ",stat:" + event.getState().toString());
            }
        });
        //2)執行操作
        //2.1)測試檢視節點是否存在   //znode01
//        Stat stat = zkClient.exists("/znode01", false);
//        if (stat == null) {
//            System.out.println("znode01節點不存在");
//        } else {
//            System.out.println("znode01節點存在");
//        }

        //2.2)建立節點
//        zkClient.create("/znode01", "hello".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//        System.out.println("建立znode01成功");
//
        //2.3)檢視子清單: ls /
//        List<String> nodes = zkClient.getChildren("/", false);
//        for (String node : nodes) {
//            System.out.println(node);
//        }

        //2.4)檢視某節點的資料
//        byte [] data=zkClient.getData("/znode01",true,null);//null是資料的最新版本
//        System.out.println("修改之前的資料是:"+new String(data));
//
//        //進行修改資料
//        zkClient.setData("/znode01","newDatadata".getBytes(),-1);
//
//
//        byte [] data2=zkClient.getData("/znode01",true,null);//null是資料的最新版本
//        System.out.println("修改之後的資料是:"+new String(data2));


        //删除節點
        zkClient.delete("/znode01", -1);
        System.out.println("删除成功!");


        zkClient.close();
    }
}

           

覺得有幫助的,請多多支援部落客,點贊關注哦~