Zookeeper學習基礎內(nèi)容

[TOC]

一、Zookeeper簡介

ZooKeeper致力于提供一個高性能、高可用,且具備嚴格的順序訪問控制能力的分布式協(xié)調(diào)服務,是雅虎公司創(chuàng)建,是Google的Chubby一個開源的實現(xiàn),也是Hadoop和Hbase的重要組件.

Zookeeper

設計目標:

  • 簡單的數(shù)據(jù)結(jié)構(gòu):共享的樹形結(jié)構(gòu),類似文件系統(tǒng),存儲于內(nèi)存
  • 可以構(gòu)建集群:避免單點故障,3-5臺機器就可以組成集群,超過半數(shù)正常工作就能對外提供服務;
  • 順序訪問:對于每個讀請求,zk會分配一個全局唯一的遞增編號,利用這個特性可以實現(xiàn)高級協(xié)調(diào)服務
  • 高性能:基于內(nèi)存操作,服務于非事務請求,適用于讀操作為主的業(yè)務場景。3臺zk集群能達到13w QPS

二、分布式系統(tǒng)協(xié)調(diào)“方法論”

1.CAP理論

  • C 一致性:數(shù)據(jù)在分布式環(huán)境下的多個副本之間能否保持一致性,這里的一致性更多是指強一致性;
  • A 可用性:分布式系統(tǒng)一直處于可用狀態(tài),對于請求總是能在有限的時間 內(nèi)返回結(jié)果致性;
  • P 分區(qū)容錯性:除非整個網(wǎng)絡故障,分布式系統(tǒng)在任何網(wǎng)絡或者單點故障時,仍能對外提供滿足一致性和可用性的服務;

CAP理論:一個分布式系統(tǒng)不可能同時滿足一致性、可用性和分區(qū)容錯性這三個 基本需求,最多只能同時滿足其中的兩項;

CAP

TIPS:架構(gòu)師的精力往往就花在怎么樣根據(jù)業(yè)務場景在A和C直接尋求平衡;

2.BASE理論

  • Basically Avaliable 基本可用:當分布式系統(tǒng)出現(xiàn)不可預見的故障時,允許損失部分可用性,保障系統(tǒng)的“基本可用”;體現(xiàn)在“時間上的損失”和“功能上的損失”;e.g:部分用戶雙十一高峰期淘寶頁面卡頓或 降級處理;
  • Soft state 軟狀態(tài):允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),既系統(tǒng)的不同節(jié)點的數(shù)據(jù)副本之間的數(shù)據(jù)同步過程存在延時,并認為這種延時不會影響系統(tǒng)可用性;e.g:12306網(wǎng)站賣火車票,請求會進入排隊隊列;
  • Eventually consistent 最終一致性:所有的數(shù)據(jù)在經(jīng)過一段時間的數(shù)據(jù)同步后,最終能夠達到一個一致的狀態(tài);e.g:理財產(chǎn)品首頁充值總金額 短時不一致;

BASE理論:即使無法做到強一致性,但分布式系統(tǒng)可以根據(jù)自己的業(yè)務特點,采 用適當?shù)姆绞絹硎瓜到y(tǒng)達到最終的一致性;

三、分布式環(huán)境協(xié)調(diào)通信應用場景

Zookeeper常應用以下場景:

  • 數(shù)據(jù)發(fā)布訂閱
  • 負載均衡
  • 命名服務
  • Master選舉
  • 集群管理
  • 配置管理
  • 分布式隊列
  • 分布式鎖

四、Zookeeper配置文件詳解

序號 參數(shù)名 說明
1 clientPort 客戶端連接server的端口,即對外服務端口,一般設置為2181
2 dataDir 存儲快照文件snapshot的目錄。默認情況下,事務日志也會存儲在這里。建議同時配置參數(shù)dataLogDir, 事務日志的寫性能直接影響zk性能。
3 tickTime ZK中的一個時間單元。ZK中所有時間都是以這個時間單元為基礎,進行整數(shù)倍配置的。例如,session的最小超時時間是2*tickTime
4 dataLogDir 事務日志輸出目錄。盡量給事務日志的輸出配置單獨的磁盤或是掛載點,這將極大的提升ZK性能
5 globalOutstandingLimit 最大請求堆積數(shù)。默認是1000。ZK運行的時候, 盡管server已經(jīng) 沒有空閑來處理更多的客戶端請求了,但是還是允許客戶端將請求提交到服務器上來,以提高吞吐性能。當然,為了防止Server內(nèi)存 溢出,這個請求堆積數(shù)還是需要限制下的。(Java system property: zookeeper.globalOutstandingLimit.)
6 preAllocSize 預先開辟磁盤空間,用于后續(xù)寫入事務日志。默認是64M,每個事務日志大小就是64M。如果ZK的快照頻率較大的話,建議適當減小 這個參數(shù)。(Java system property: zookeeper.preAllocSize)
7 snapCount 每進行snapCount次事務日志輸出后,觸發(fā)一次快照(snapshot),此時,ZK會生成一個snapshot.文件,同時創(chuàng)建一個新的事務日志文件log.。 默認是100000.(真正的代碼實現(xiàn)中,會進行一定的隨機數(shù)處理,以避 免 所 有 服 務 器 在 同 一 時 間 進 行 快 照 而 影 響 性 能 )(Java system property: zookeeper.snapCount)
8 traceFile 用于記錄所有請求的log,一般調(diào)試過程中可以使用,但是生產(chǎn)環(huán)境不建 議使用,會嚴重影響性能。(Java system property:? requestTraceFile)
9 maxClientCnxns 單個客戶端與單臺服務器之間的連接數(shù)的限制,是ip級別的,默認是60如果設置為0,那么表明不作任何限制。請注意這個限制的使用范圍,僅僅是單臺客戶端機器與單臺ZK服務器之間的連接數(shù)限制,不是針對指定客戶端IP,也不是ZK集群的連接數(shù)限制,也不是單臺ZK對所有客戶端的 連接數(shù)限制。
10 clientPortAddress 對于多網(wǎng)卡的機器,可以為每個IP指定不同的監(jiān)聽端口。默認情況是所 有IP都監(jiān)聽 clientPort指定的端口。 New in 3.3.0
11 minSessionTimeou tmaxSessionTimeout Session超時時間限制,如果客戶端設置的超時時間不在這個范圍,那么會被強制設置為最大或最小時間。默認的Session超時時間是在2* tickTime ~ 20 * tickTime 這 個 范 圍 New in 3.3.0
12 fsync.warningthresholdms 事務日志輸出時,如果調(diào)用fsync方法超過指定的超時時間,那么會在日志中輸出警告信息,默認是1000ms
13 autopurge.purgeInterval 清理任務的時間間隔,單位為hours
14 autopurge.snapRetainCount zkserver啟動時會開啟一個org.apache.zookeeper.server.DatadirCleanupManager的線程,用于清理"過期"的snapshot文件和其相應的txn log file,此參數(shù)用于設定需要被retain保留的文件個數(shù)(從QuorumPeerMain跟蹤代碼)
15 electionAlg 選舉算法,默認為3,可以選擇(0,1,2,3), 0表示使用原生的UDP(LeaderElection), 1表示使用費授權的UDP 2表示使用授權的UDP(AuthFastLeaderElection) 3基于TCP的快速選舉(FastLeaderElection)
16 initLimit Leader與learner建立連接中 socket通訊read所阻塞的時間(initLimit * tickTime) 如果是Leaner數(shù)量較多或者leader的數(shù)量很大, 可以增加此值
17 SyncLimit learner與leader建立連接中,socket通訊read阻塞的時間.其中包括數(shù)據(jù)同步/數(shù)據(jù)提交等
18 peerType zkserver 類型 observer 觀察者, participant參與者 ,默認為參與者
19 leaderServes 系統(tǒng)屬性 zookeeper.leaderServes leader是否接受client請求,默認為yes即leader可以接受client的連接,在zk cluster 環(huán)境中,當節(jié)點數(shù)為>3時,建議關閉
20 cnxTimeout 系統(tǒng)屬性:zookeeper.cnxTimeout leader選舉時socket連接打開的時長,只有在electionAlg=3有效
21 skipACL 系統(tǒng)屬性:zookeeper.skipACL 默認為no,是否跳過ACL檢查
22 forceSync 系統(tǒng)屬性:zookeeper.forceSync 默認yes 在update執(zhí)行之前,是否強制對操作立即持久寫入txn log文件.關閉此選項,會造成服務器失效后,尚未持久化的數(shù)據(jù)丟失
23 jute.maxbuffer 每個節(jié)點最大數(shù)據(jù)量,是默認是1M。這個限制必須在server和client 端都進行設置才會生效。

五、Zookeeper特性

1.會話(Session)

客戶端與服務端的一次會話連接,本質(zhì)是TCP長連接,通過會話可以進行心跳檢測和數(shù)據(jù)傳輸;


會話

2.數(shù)據(jù)節(jié)點(znode)

ZooKeeper的視圖結(jié)構(gòu)和標準的Unix文件系統(tǒng)類似,其中每個節(jié)點稱為“數(shù)據(jù)節(jié)點”或ZNode,每個znode可以存儲數(shù)據(jù),還可以掛載子節(jié)點,因此可以稱之為“樹”

特性:

  • 在Zookeeper中,znode是一個跟Unix文件系統(tǒng)路徑相似的節(jié)點,可以往這個節(jié)點存儲或獲取數(shù)據(jù)。
  • 通過客戶端可對znode進行增刪改 查的操作,還可以注冊watcher監(jiān) 控znode的變化。

Zookeeper節(jié)點類型

  • 持久節(jié)點(Persistent)
  • 持久順序節(jié)點(Persistent_Sequential)
  • 臨時節(jié)點(Ephemeral)
  • 臨時順序節(jié)點(Ephemeral_Sequential)

對于持久接地啊和臨時節(jié)點,同一個Znode下,節(jié)點的名稱是唯一的 -實現(xiàn)分布式鎖的基礎

Znode

Zookeeper節(jié)點狀態(tài)屬性

Zookeeper節(jié)點屬性

3.版本

4.Watcher

事件監(jiān)聽器,客戶端可以在節(jié)點上注冊監(jiān)聽器,當特定的事件發(fā)生后,zk會通知到感興趣的客戶 端;eventType: NodeCreated、NodeDeleted、NodeDataChanged、NodeChildrenChange

5.ACL

Zk采用ACL(access control lists)策略來控制權限,5種權限:create、read,write,delete,admin。

ACL機制,表示為scheme:id:permissions,第一個字段表示采用哪一種機制,第二個id表示用戶,permissions表示相關權限(如只讀,讀寫,管理等)。zookeeper提供了如下幾種機制( scheme):

  • world: 它下面只有一個id, 叫anyone, world:anyone代表任何人,zookeeper中對所有人有權限的結(jié)點就是屬于world:anyone的

  • auth: 它不需要id, 只要是通過authentication的user都有權限(zookeeper支持通過kerberos來進行authencation, 也支持username/password形式的authentication)

  • digest: 它對應的id為username:BASE64(SHA1(password)),它需要先通過username:password形式的authentication

  • ip: 它對應的id為客戶機的IP地址,設置的時候可以設置一個ip段,比如ip:192.168.1. 0/16, 表示匹配前16個bit的IP段

  • super: 在這種scheme情況下,對應的id擁有超級權限,可以做任何事情(cdrwa)

6.集群角色

六、常用客戶端命令

1.服務端常用命令

在準備好相應的配置之后可以直接通過zkServer.sh 這個腳本進行服務的相關操作:

  • 啟動ZK服務: sh bin/zkServer.sh start
  • 查看ZK服務狀態(tài): sh bin/zkServer.sh status
  • 停止Zk服務: sh bin/zkServer.sh stop
  • 重啟ZK服務: sh bin/zkServer.sh restart

2.客戶端常用命令

使用zkCli.sh -server 127.0.0.1:2181 連接到Zookeeper服務

  • 顯示根目錄下文件、文件
ls/
  • 顯示根目錄下、文件
ls2 /

查看當前節(jié)點數(shù)據(jù)并能看到更新次數(shù)等數(shù)據(jù)

  • 創(chuàng)建文件并設置初始內(nèi)容
create /zk "test"

創(chuàng)建一個新的znode節(jié)點“zk" 以及與它關聯(lián)的字符串

  • 獲取文件
get /zk

確認znode是否包含創(chuàng)建的字符串

  • 修改文件內(nèi)容
set /zk "zkbak"

對zk所關聯(lián)的字符串進行設置和修改

  • 刪除文件
delete /zk

將創(chuàng)建的znode節(jié)點進行刪除,如果存在子節(jié)點則刪除會失敗

  • 遞歸刪除
rmr /zk

將剛才創(chuàng)建的znode刪除,同時刪除子節(jié)點

  • 退出客戶端
quit
  • 幫助命令
help

七、ACL 常用命令

1. getAcl

獲取指定節(jié)點的ACL信息

2.setACL

設置指定節(jié)點的ACL信息

3.addauth

注冊會話授權信息

八、Zookeeper常用命令

  • 查看哪個節(jié)點被選擇作為follower或者leader
echo stat|nc 127.0.0.1 2181 
  • 測試是否啟動了該Server,若回復imok表示已經(jīng)啟動
echo ruok|nc 127.0.0.1 2181
  • 列出未經(jīng)處理的會話和臨時節(jié)點
echo kill | nc 127.0.0.1 2181 
  • 輸出相關服務配置的詳細信息
echo conf | nc 127.0.0.1 2181 
  • 列出所有連接到服務器的客戶端的完全的連接 / 會話的詳細信息
echo cons | nc 127.0.0.1 2181
  • 輸出關于服務環(huán)境的詳細信息(區(qū)別于 conf 命令)
echo envi |nc 127.0.0.1 2181 
  • 列出未經(jīng)處理的請求
echo reqs | nc 127.0.0.1 2181 
  • 列出服務器 watch 的詳細信息
echo wchs | nc 127.0.0.1 2181 
  • 通過 session 列出服務器 watch 的詳細信息,它的輸出是一個與 watch相關的會話的列表
echo wchc | nc 127.0.0.1 2181 
  • 通過路徑列出服務器 watch 的詳細信息。它輸出一個與 session 相關的路 徑
echo wchp | nc 127.0.0.1 2181 

九、Zookeeper 日志可視化

  • 事務日志可視化(LogFormatter)
java -cp ../../zookeeper-3.4.6.jar;../../lib/slf4j-api-1.6.1.jar  org.apache.zookeeper.server.LogFormatter log.xxxx

  • 數(shù)據(jù)快照可視化( SnapshotFormatter)
java -cp ../../zookeeper-3.4.6.jar;../../lib/slf4j-api-1.6.1.jar org.apache.zookeeper.server.SnapshotFormatter  snapshot.xxxx

十、Zookeeper客戶端簡介

1.Zookeeper 客戶端

zookeeper官方提供的java客戶端API;

核心API

  • 創(chuàng)建會話
public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,  long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)

  • 創(chuàng)建節(jié)點
public String void create(final String path, byte data[], List<ACL> acl,  CreateMode  createMode,   StringCallback cb, Object ctx)

  • 讀取數(shù)據(jù)
public List<String> void getChildren(final String path, Watcher watcher,  Stat stat, Children2Callback cb, Object ctx)

public List<String>  void getData(final String path, Watcher watcher,  Stat stat, DataCallback cb, Object ctx)

  • 更新數(shù)據(jù)
public Static void setData(final String path, byte data[], int version,  StatCallback cb, Object ctx)

  • 檢測節(jié)點是否存在
public Static void exists(final String path, Watcher watcher,  StatCallback cb, Object ctx)

  • 權限控制
public void addAuthInfo(String scheme, byte auth[])

  • Watch

org.apache.zookeeper.Watcher(KeeperState、EventType)

(1)沒有專門的API去注冊watcher,依附于增刪改查API;

(2)watch是一次性產(chǎn)品

(3)watch的process方法中,可對不同事件進行處理;

原生客戶端開發(fā)弊端

  • 會話的鏈接是異步的
  • 序列化支持不透明
  • Watch需要重復注冊
  • Session 重連機制
  • 開發(fā)復雜性較高

2.ZkClient

開源的zk客戶端,在原生API基礎上封裝,是一個更易于使用的zookeeper客戶端;
引入Maven依賴

<!-- zkclient依賴 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>

核心API

  • 創(chuàng)建會話(同步,重試)
public ZkClient(final String zkServers, final int sessionTimeout,final int connectionTimeout, final ZkSerializer zkSerializer,  final long operationRetryTimeout)

  • 創(chuàng)建節(jié)點(同步、遞歸創(chuàng)建)
String create(final String path, Object data, final CreateMode mode)
public void createPersistent(String path,boolean createParents,List<ACL> acl)  
public void createPersistent(String path, Object data, List<ACL> acl)

public String createPersistentSequential(String path,Object data,List<ACL> acl) 
public String createPersistentSequential(String path,Object data,List<ACL> acl  
public String createEphemeralSequential(String path,Object data,List<ACL> acl)

  • 刪除節(jié)點(同步,遞歸調(diào)用)
public boolean delete(String path,int version) 
public boolean deleteRecursive(String path)
  • 獲取節(jié)點(同步,避免不存在異常)
public List<String> getChildren(String path)

public <T> T readData(String path, boolean returnNullIfPathNotExists) 
public <T> T readData(String path, Stat stat)

  • 更新節(jié)點(同步、實現(xiàn)CAS、狀態(tài)返回)
public void writeData(String path, Object datat, int expectedVersion)

public Stat writeDataReturnStat(String path,Object datat,int expectedVersion)

  • 檢測節(jié)點存在(同步)
public boolean exists(String path)

  • 權限控制(同步)
public void addAuthInfo(String scheme, final byte[] auth);  
public void setAcl(final String path, final List<ACL> acl);
  • 監(jiān)聽器


    監(jiān)聽器

3.Cuator

開源的zk客戶端,在原生API基礎上封裝,apache頂級項目;

  • Curator采用Fluent風格API
<!-- curator依賴 -->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.0.0</version>
</dependency>

序列化支持不好

Curator 核心API

  • 創(chuàng)建會話(同步、重試)
CuratorFrameworkFactory.newClient(String connectString, int sessionTimeoutM int connectionTimeoutMs, RetryPolicy retryPolicy)

CuratorFrameworkFactory.builder().connectString("192.168.11.56:2180")
.sessionTimeoutMs(30000).connectionTimeoutMs(30000)
.canBeReadOnly(false)
.retryPolicy(new ExponentialBackoffRetry(1000, Integer.MAX_VALUE))
.build();

retryPolicy 連接策略:
RetryOneTime: 只重連一次.
RetryNTime: 指定重連的次數(shù)N.
RetryUtilElapsed: 指定最大重連超時時間和重連時間間隔,間歇性重連直到超時或者鏈接成功.
ExponentialBackoffRetry: 基于"backoff"方式重連,和RetryUtilElapsed的區(qū)別是重連的時間間隔是動態(tài)
BoundedExponentialBackoffRetry: 同ExponentialBackoffRetry,增加了最大重試次數(shù)的控制.
  • 創(chuàng)建節(jié)點
client.create().creatingParentIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(aclList)
.forPath(path, "hello, zk".getBytes());

  • 刪除節(jié)點
client.delete().guaranteed().deletingChildrenIfNeeded()
.withVersion(version).forPath(path)

  • 獲取節(jié)點
client.getData().storingStatIn(stat).forPath(path);
client.getChildren().forPath(path);

  • 更新節(jié)點
client.setData().withVersion(version).forPath(path, data)

  • 判斷節(jié)點是否存在
client.checkExists().forPath(path);

  • 設置權限
Build.authorization(String scheme, byte[] auth)

client.setACL().withVersion(version)
.withACL(ZooDefs.Ids.CREATOR_ALL_ACL)
.forPath(path);

  • 監(jiān)聽器(避免重復監(jiān)聽)
Cache是curator中對事件監(jiān)聽的包裝,對事件的監(jiān)聽可以近似看做是本地緩存視圖和遠程zk視圖的對比過程

- NodeCache 節(jié)點緩存用于處理節(jié)點本身的變化 ,回調(diào)接口NodeCacheListener
- PathChildrenCache 子節(jié)點緩存用于處理節(jié)點的子節(jié)點變化,回調(diào)接口 PathChildrenCacheListener
- TreeCache NodeCache和PathChildrenCache的結(jié)合體,回調(diào)接口TreeCacheListener
  • 事務支持(保證一組操作的原子性)
Collection<CuratorTransactionResult> results =  client.transaction().forOperations(operations);

  • 異步支持
    引入BackgroundCallback接口,用于處理異步接口調(diào)用之后服務端返回的結(jié)果信息
public void processResult(CuratorFramework client, CuratorEvent event)

CuratorEventType 事件類型
org.apache.zookeeper.KeeperException.Code

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容