1. 程式人生 > >ZooKeeper 相關概念以及使用小結

ZooKeeper 相關概念以及使用小結

Dubbo 通過註冊中心在分散式環境中實現服務的註冊與發現,而註冊中心通常採用 ZooKeeper,研究註冊中心相關原始碼繞不開 ZooKeeper,所以學習了 ZooKeeper 的基本概念以及相關 API 操作。

ZooKeeper 相關概念

session

客戶端與服務端採用 TCP 長連線,服務端在為客戶端建立 Session 會分配一個唯一 sessionId。在 Session timeout 時間內,客戶端可以向服務端傳送請求以及接受 watcher 事件通知。

資料結構

Zookeeper 將所有資料儲存在記憶體中,資料模型是一棵樹(Znode Tree),由斜槓(/)的進行分割的路徑,就是一個Znode,例如/foo/path1。

Znode

Znode 將會儲存資料內容以及相關屬性資訊。在 Znode 中使用 Stat 資料結儲存相關屬性資訊。Stat 屬性中有三種版本資訊,分別為 version:當前節點版本資訊,cversion:當前節點子節點版本,aversion 當前節點的 ACL 版本。每次發生改動,版本數值將會單調遞增。

更新,刪除 Znode 可以傳入版本數值,如果版本數值不對,將會導致刪除/更新失敗,這個特性類似於 CAS 操作。

Znode 有以下幾種型別:

  1. 永久節點

一旦建立,將會一直存在,除非手動刪除。dubbo 目錄節點為永久節點。

  1. 臨時節點

臨時節點基於客戶端 Session,Session 有效期內將會一直存在,Session 失效,節點將會自動刪除。

利用這個機制,Dubbo 服務者建立的節點就是臨時節點。如果 Dubbo 服務者程式意外宕機,在 Session 超時之後,也能自動刪除服務節點,自動下線有問題的服務。

3 順序節點

建立順序節點將會自動在名字後追加整形數字,預設長度為 10 位。順序節點也分為永久與臨時。

利用臨時順序節點,我們可以用來實現分散式鎖 七張圖徹底講清楚ZooKeeper分散式鎖的實現原理【石杉的架構筆記】。

Watcher 機制

客戶端可以在指定節點註冊監聽器(Watcher),在觸發特定事件後,ZooKeeper 服務端會將事件通知到客戶端。在 Dubbo 中消費者基於 watcher 機制可以動態感知到新的服務者加入。

ZooKeeper 可以在三種請求中設定監聽,分別為:

  • getData(),獲取節點資料
  • getChildren() 獲取子節點
  • exists() 判斷節點是否存在

通知事件型別分為,增刪改事件,以及子節點變動事件。

需要注意的是,watcher 通知過一次之後將會失效,若想繼續監聽通知,需要重新註冊。

ZooKeeper 原生 API 操作

ZooKeeper 官方提供 Java API 實現,提供相關操作的方法。

建立連線


        ZooKeeper zk=new ZooKeeper("127.0.0.1:2181", 150000, new Watcher() {

            @Override
            public void process(WatchedEvent watchedEvent) {

                System.out.println("已經觸發了" + watchedEvent.getType() + "事件"+watchedEvent);

            }

        });

建立連線需要傳入 ZooKeeper 服務端地址,然後設定 session 超時時間,另外還需要建立一個 Watcher,用於監聽連線事件。建立連線之後,就可以使用該客戶端操作。

CURD 操作


        // 建立永久節點,需要傳入 ACL 許可權列表,以及指定節點型別
        zk.create("/test","test".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.PERSISTENT);

        // 修改節點值。更新節點值需要傳入節點的版本,如果版本與服務端版本不一致,更新失敗,類似 CAS 機制。-1 代表不比較節點版本
        zk.setData("/test","test1".getBytes(),-1);
        // 刪除節點.刪除節點也需要傳入節點版本
        zk.delete("/test",-1);
        // 建立臨時節點
        zk.create("/ephemeral","ephemeral".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.EPHEMERAL);

ZooKeeper 客戶端相關 CRUD 操作如上。可以看到相關操作比較繁瑣,需要傳入引數較多。

watcher

 // 在 exists 註冊 watcher,建立節點,刪除節點,改變節點將會觸發回撥

        zk.exists("/test", new Watcher() {

            @Override
            public void process(WatchedEvent event) {
                System.out.println("回撥例項,型別為:"+event.getType());
            }
        });
        // 獲取節點資料,可以註冊 watcher,刪除節點以及改變節點資料可以觸發回撥
        zk.getData("/test", new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("回撥例項,型別為:"+event.getType());
            }
        },new Stat());

        // 獲取子節點,註冊 watcher,一級子節點變動後將會觸發回撥
        zk.getChildren("/test", new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("回撥例項,型別為:"+event.getType());
            }
        });

ZooKeeper API 可以為三種操作註冊 watcher,一旦相關節點變動將會觸發事件通知。

Curator

從上面程式碼示例可以看到 ZooKeeper 提供 API 比較複雜且難用。可以使用 Curator 或者 zkclient 這種第三方框架代替原生 API。這類框架封裝 ZooKeeper 原生 API,抽象化相關介面,簡化操作難度。

dubbo 抽象相關 ZooKeeper 操作,並分別使用 Curator 或者 zkclien 實現。在 dubbo 2.6.1 版本之後將會預設使用 Curator,之前版本預設使用 zkclient 。

下面我們使用 Curator 操作 ZooKeeper 。

建立連線

 // 設定重試策略
 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
 // 預設 session 超時時間 60 s
 CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);

Curator 建立連線與原生 API 大致相關,不過需要設定重試策略,第一次連線失敗,Curator 可以重新嘗試連線,直到超過最大連線次數。

節點 CURD 操作

        // 建立目錄節點

        client.create().forPath("/test", "123456789".getBytes());
        // 建立普通節點
        client.create().forPath("/test/normal", "123121".getBytes());
        // 修改普通節點內容
        client.setData().forPath("/test/normal", "1121231231".getBytes());
        // 刪除節點
        client.delete().forPath("/test/normal");

        // 建立臨時節點
        client.create().withMode(CreateMode.EPHEMERAL).forPath("/ephemeral");
        // 建立永久順序節點
        client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/sequential");
        
       // 獲取所有子節點
        List<String> nodes = client.getChildren().forPath("/parent");

Curator CRUD 操作比較簡單,無需設定相關屬性引數。

設定監聽

Curator 相關監聽 API 封裝 zookeeper 原生API,內部增加重複註冊等功能,從而使監聽可以重複使用。

Curator 存在三種類型 API。

  • NodeCache:針對節點增刪改操作。
  • PathChildrenCache:針對節點一級目錄下節點增刪改監聽
  • TreeCache:結合 NodeCachePathChildrenCache 操作,不僅可以監聽當前節點,還可以監聽節點下任意子節點(支援多級)變動。
    //   `NodeCache`使用方式
        NodeCache nodeCache=new NodeCache(client,"/test1",false);
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                System.out.println("當前節點:"+nodeCache.getCurrentData());

            }
        });
        nodeCache.start();

    // PathChildrenCache 使用方式
     PathChildrenCache pathChildrenCache=new PathChildrenCache(client,"/test2",false);
        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
                System.out.println(event);
            }
        });
        pathChildrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);
        System.out.println("註冊watcher成功...");      
    // TreeCache 使用方式
        TreeCache treeCache=new TreeCache(client,"/tree");
        treeCache.getListenable().addListener(new TreeCacheListener() {
            @Override
            public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
                                System.out.println(event);
            }
        });
        treeCache.start();
        System.out.println("註冊watcher成功...");
 

相關推薦

ZooKeeper 相關概念以及使用小結

Dubbo 通過註冊中心在分散式環境中實現服務的註冊與發現,而註冊中心通常採用 ZooKeeper,研究註冊中心相關原始碼繞不開 ZooKeeper,所以學習了 ZooKeeper 的基本概念以及相關 API 操作。 ZooKeeper 相關概念 session 客戶端與服務端採用 TCP 長連線,服務端

流圖、環形複雜度的相關概念以及相關練習

流圖:McCabc方法根據程式控制流的複雜程度定量度量程度的複雜程度,這樣度量出的結果稱為程式的環形複雜度。 環形複雜度:定量度量程式的邏輯複雜度 計算複雜度方法: (1)流圖中線性無關的區域數等於環形複雜度 (2)流圖G的環形複雜度V(G)=E-N+2,其中,E是流圖中的邊數,

Zookeeper概念以及搭建

zookeeper官網: 什麼是Zookeeper ? Zookeeper是Google的chubby一個開源的實現,是hadoop的分散式協調服務。 它包含一個簡單的原語集,分散式應用程式可以基於它實現同步服務,配置維護和命名服務等。 zookeep

zookeeper相關create以及ACL許可權

客戶端 初始化zookeeper 建立zookeeper節點 api: create(final String path, byte data[], List<ACL> acl, CreateMode create

軟件測試相關概念以及原則

優點 正常 源代碼 說明 例如 phpunit 度量 業務 java 軟件測試:使用人工或自動的手段來運行或測量軟件系統的過程,以檢驗軟件系統是否滿足規定的要求,並找出與預期結果之間的差異。 軟件測試的測試對象:軟件概要設計、軟件詳細設計、軟件運行環境、可運行程序、軟件源

軟體測試相關概念以及原則(二)

敏捷測試:1、強調從客戶角度進行測試      2、重點關注迭代測試新功能,不再強調測試階段      3、儘早測試,不間斷測試,具備條件即測試      4、強調持續反饋      5、預防缺陷重於發現缺陷 敏捷測試 VS 傳統測試 傳統測試:1、測試是質量的最後保護者      2、嚴格的變

UNIX C 學習筆記一:UNIX/Linux發展歷史以及相關概念

一、UNIX 與 Linux 的發展歷史 Unix 作業系統是一個強大的多使用者,多工作業系統,支援多種處理器架構,按照作業系統的分類,屬於分時作業系統,最早由 Ken Thompson, Dennis Titchie 和 Douglas Mcllroy 於 1969年在 AT&

JPA概念以及相關知識點

JPA : 物件關係對映ORM(Hibernate)的規範(持久化) OMR是什麼??  --> 物件關係對映Object Relational Mapping Hibernate --> ORM框架(實現了ORM規範)加快了操作資料庫的速度  -- 其中單表操作

Python中建立程序的方法,以及併發並行,殭屍程序,孤兒程序的相關概念

一、併發與並行 並行:多個計算機核心在同時處理多個任務,這時多個任務間是並行關係 併發:同時處理多個任務,但是核心在多個任務間不斷地切換,達到好像都在處理執行的效果,但實際一個時間點核心只能處理其中一個任務。 二、程序 程序與執行緒是實現多工程式設計的實施方案 程序與執

mybatis中的相關概念小結

上一篇文章中總結了mybatis的入門原始dao開發和mapper代理開發,忽略了很多概念性的東西,以及相關相似概念的區別,因此筆者在此,進行相關基本概念的總結,用於自我學習的記錄。(ps:概念性的東西是基礎,是往後理解其思想的基本必備知識) parameterType:對映

異常的概念以及分類與相關處理方式

異常 異常的概念 異常指的並不是語法錯誤,語法錯了,編譯不通過,不會產生位元組碼檔案,根本不能執行 異常本身是一個類,產生異常就是建立異常物件,並丟擲一個異常物件,java處理異常的方式是終端處理 異常分類

k8s架構以及相關概念普及

為什麼要使用k8s 瞭解openstack 在k8s和容器docker出來之前,最火的技術莫過於開源雲平臺openstack了,那麼openstack做了什麼事情呢?利用虛擬化技術實現資源的彈性使用,如果你是做開發的,你肯定知道資料庫連線池,誰需要誰就拿走連線

RBD儲存的接收以及相關概念(讀書筆記)

RDB進行持久化    RDB持久化可以手動執行,也可以根據伺服器配置選項定期執行。該功能可以將某個時間點上的資料庫狀態儲存到一個RDB儲存到一個檔案中。    RDB持久化功能所生產的RDB檔案是一個經過壓縮的二進位制檔案,通過該檔案可以還原生成RDB檔案資料庫狀態   

java 大資料以及Hadoop相關概念介紹

一、大資料的基本概念1.1、什麼是大資料大資料指的就是要處理的資料是TB級別以上的資料。大資料是以TB級別起步的。在計算機當中,存放到硬碟上面的檔案都會佔用一定的儲存空間,例如:​ 檔案佔用的儲存空間代表的就是該檔案的大小,在計算機當中,檔案的大小可以採用以下單位來表示,各個

學習android 筆記(4):如何獲取螢幕的相關屬性以及dp 、dip、dpi 、px的概念

<span style="font-size:24px;">DisplayMetrics dm = new DisplayMetrics(); getWindowManager().g

位元組對齊概念以及相關深入

文章最後本人做了一幅圖,一看就明白了,這個問題網上講的不少,但是都沒有把問題說透。   一、概念       對齊跟資料在記憶體中的位置有關。如果一個變數的記憶體地址正好位於它長度的整數倍,他就被稱做自然對齊。比如在32位cpu下,假設一個整型變數的地址為0x00000

WebSocket-01 概念以及相關

寫在前面         本人是搞技術的,由衷的喜歡技術。其實我想大多數開發人員喜歡技術的並不多,多數為了工作而不得不學習新的技術。但是我是那種喜歡技術的,除了工作中會用的新計劃我會去研究,業餘時間我也喜歡研究和學習新的技術。當然,鄙人學習新的技術本質的目的不是在於跳槽,起初

Spark 介紹以及相關概念

Spark起源: Apache Spark 是專為大規模資料處理而設計的快速通用的計算引擎。Spark是UC Berkeley 加州大學伯克利AMP lab (加州大學伯克利分校的AMP實驗室)所開源的類Hadoop MapReduce的通用並行框架,Spar

java多執行緒核心api以及相關概念(一)

這篇部落格總結了對執行緒核心api以及相關概念的學習,黑體字可以理解為重點,其他的都是我對它的理解 個人認為這些是學習java多執行緒的基礎,不理解熟悉這些,後面的也不可能學好滴 目錄 1.什麼是執行緒以及優點 二,多執行緒如何使用 三,執行緒安全問題, 四,synchronized執行過程敘述

RRTI的概念以及Class對象作用

eat 有趣的 getclass 2種 init null java虛擬機 class對象 小例子   深入理解Class對象    RRTI的概念以及Class對象作用    認識Class對象之前,先來了解一個概念,RTTI(Run-Time Type Identifi