主頁 >  其他 > 阿里資深JAVA架構師分享分布式服務框架Zookeeper

阿里資深JAVA架構師分享分布式服務框架Zookeeper

2020-09-15 08:40:38 其他

點關注,不迷路!如果本文對你有幫助的話不要忘記點贊支持哦!

Zookeeper 分布式服務框架是 Apache Hadoop 的一個子專案,它主要是用來解決分布式應用中經常遇到的一些資料管理問題,如:統一命名服務、狀態同步服務、集群管理、分布式應用配置項的管理等,本文將從使用者角度詳細介紹 Zookeeper 的安裝和組態檔中各個配置項的意義,以及分析 Zookeeper 的典型的應用場景(組態檔的管理、集群管理、同步鎖、Leader 選舉、佇列管理等),用 Java 實作它們并給出示例代碼,

安裝和配置詳解

本文介紹的 Zookeeper 是以 3.2.2 這個穩定版本為基礎,最新的版本可以通過官網 http://zookeeper.apache.org/來獲取,Zookeeper 的安裝非常簡單,下面將從單機模式和集群模式兩個方面介紹 Zookeeper 的安裝和配置,

單機模式

單機安裝非常簡單,只要獲取到 Zookeeper 的壓縮包并解壓到某個目錄如:/home/zookeeper-3.2.2 下,Zookeeper 的啟動腳本在 bin 目錄下,Linux 下的啟動腳本是 zkServer.sh,在 3.2.2 這個版本 Zookeeper 沒有提供 windows 下的啟動腳本,所以要想在 windows 下啟動 Zookeeper 要自己手工寫一個,如清單 1 所示:
清單 1. Windows 下 Zookeeper 啟動腳本

setlocal 
set ZOOCFGDIR=%~dp0%..\conf 
set ZOO_LOG_DIR=%~dp0%.. 
set ZOO_LOG4J_PROP=INFO,CONSOLE 
set CLASSPATH=%ZOOCFGDIR% 

set CLASSPATH=%~dp0..\*;%~dp0..\lib\*;%CLASSPATH% 
set CLASSPATH=%~dp0..\build\classes;%~dp0..\build\lib\*;%CLASSPATH% 
set ZOOCFG=%ZOOCFGDIR%\zoo.cfg 
set ZOOMAIN=org.apache.zookeeper.server.ZooKeeperServerMain 
java "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" 
-cp "%CLASSPATH%" %ZOOMAIN% "%ZOOCFG%" %* 
endlocal

在你執行啟動腳本之前,還有幾個基本的配置項需要配置一下,Zookeeper 的組態檔在 conf 目錄下,這個目錄下有 zoo_sample.cfg 和 log4j.properties,你需要做的就是將 zoo_sample.cfg 改名為 zoo.cfg,因為 Zookeeper 在啟動時會找這個檔案作為默認組態檔,下面詳細介紹一下,這個組態檔中各個配置項的意義,

tickTime=2000 
dataDir=D:/devtools/zookeeper-3.2.2/build 
clientPort=2181
  • tickTime:這個時間是作為 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳,
  • dataDir:顧名思義就是 Zookeeper 保存資料的目錄,默認情況下,Zookeeper 將寫資料的日志檔案也保存在這個目錄里,
  • clientPort:這個埠就是客戶端連接 Zookeeper 服務器的埠,Zookeeper 會監聽這個埠,接受客戶端的訪問請求,

當這些配置項配置好后,你現在就可以啟動 Zookeeper 了,啟動后要檢查 Zookeeper 是否已經在服務,可以通過 netstat – ano 命令查看是否有你配置的 clientPort 埠號在監聽服務,

集群模式

Zookeeper 不僅可以單機提供服務,同時也支持多機組成集群來提供服務,實際上 Zookeeper 還支持另外一種偽集群的方式,也就是可以在一臺物理機上運行多個 Zookeeper 實體,下面將介紹集群模式的安裝和配置,

Zookeeper 的集群模式的安裝和配置也不是很復雜,所要做的就是增加幾個配置項,集群模式除了上面的三個配置項還要增加下面幾個配置項:

initLimit=5 
syncLimit=2 
server.1=192.168.211.1:2888:3888 
server.2=192.168.211.2:2888:3888
  • initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 服務器的客戶端,而是 Zookeeper 服務器集群中連接到 Leader 的 Follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數,當已經超過 10 個心跳的時間(也就是 tickTime)長度后 Zookeeper 服務器還沒有收到客戶端的回傳資訊,那么表明這個客戶端連接失敗,總的時間長度就是 5*2000=10 秒
  • syncLimit:這個配置項標識 Leader 與 Follower 之間發送訊息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2*2000=4 秒
  • server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號服務器;B 是這個服務器的 ip 地址;C 表示的是這個服務器與集群中的 Leader 服務器交換資訊的埠;D 表示的是萬一集群中的 Leader 服務器掛了,需要一個埠來重新進行選舉,選出一個新的 Leader,而這個埠就是用來執行選舉時服務器相互通信的埠,如果是偽集群的配置方式,由于 B 都是一樣,所以不同的 Zookeeper 實體通信埠號不能一樣,所以要給它們分配不同的埠號,

除了修改 zoo.cfg 組態檔,集群模式下還要配置一個檔案 myid,這個檔案在 dataDir 目錄下,這個檔案里面就有一個資料就是 A 的值,Zookeeper 啟動時會讀取這個檔案,拿到里面的資料與 zoo.cfg 里面的配置資訊比較從而判斷到底是那個 server,

資料模型

Zookeeper 會維護一個具有層次關系的資料結構,它非常類似于一個標準的檔案系統,如圖 1 所示:
圖 1 Zookeeper 資料結構

Paste_Image.png

Zookeeper 這種資料結構有如下這些特點:

  1. 每個子目錄項如 NameService 都被稱作為 znode,這個 znode 是被它所在的路徑唯一標識,如 Server1 這個 znode 的標識為 /NameService/Server1
  2. znode 可以有子節點目錄,并且每個 znode 可以存盤資料,注意 EPHEMERAL 型別的目錄節點不能有子節點目錄
  3. znode 是有版本的,每個 znode 中存盤的資料可以有多個版本,也就是一個訪問路徑中可以存盤多份資料
  4. znode 可以是臨時節點,一旦創建這個 znode 的客戶端與服務器失去聯系,這個 znode 也將自動洗掉,Zookeeper 的客戶端和服務器通信采用長連接方式,每個客戶端和服務器通過心跳來保持連接,這個連接狀態稱為 session,如果 znode 是臨時節點,這個 session 失效,znode 也就洗掉了
  5. znode 的目錄名可以自動編號,如 App1 已經存在,再創建的話,將會自動命名為 App2
  6. znode 可以被監控,包括這個目錄節點中存盤的資料的修改,子節點目錄的變化等,一旦變化可以通知設定監控的客戶端,這個是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于這個特性實作的,后面在典型的應用場景中會有實體介紹

如何使用

Zookeeper 作為一個分布式的服務框架,主要用來解決分布式集群中應用系統的一致性問題,它能提供基于類似于檔案系統的目錄節點樹方式的資料存盤,但是 Zookeeper 并不是用來專門存盤資料的,它的作用主要是用來維護和監控你存盤的資料的狀態變化,通過監控這些資料狀態的變化,從而可以達到基于資料的集群管理,后面將會詳細介紹 Zookeeper 能夠解決的一些典型問題,這里先介紹一下,Zookeeper 的操作介面和簡單使用示例,

常用介面串列

客戶端要連接 Zookeeper 服務器可以通過創建 org.apache.zookeeper. ZooKeeper 的一個實體物件,然后呼叫這個類提供的介面來和服務器互動,

前面說了 ZooKeeper主要是用來維護和監控一個目錄節點樹中存盤的資料的狀態,所有我們能夠操作ZooKeeper的也和操作目錄節點樹大體一樣,如創建一個目錄節點,給某個目錄節點設定資料,獲取某個目錄節點的所有子目錄節點,給某個目錄節點設定權限和監控這個目錄節點的狀態變化, 這些介面如下表所示:

表 1 org.apache.zookeeper. ZooKeeper 方法串列
方法名
方法功能描述

String create(String path, byte[] data, List<ACL> acl, CreateMode createMode)

創建一個給定的目錄節點 path, 并給它設定資料,CreateMode 標識有四種形式的目錄節點,分別是 PERSISTENT:持久化目錄節點,這個目錄節點存盤的資料不會丟失;PERSISTENT_SEQUENTIAL:順序自動編號的目錄節點,這種目錄節點會根據當前已近存在的節點數自動加 1,然后回傳給客戶端已經成功創建的目錄節點名;EPHEMERAL:臨時目錄節點,一旦創建這個節點的客戶端與服務器埠也就是 session 超時,這種節點會被自動洗掉;EPHEMERAL_SEQUENTIAL:臨時自動編號節點
<br >

Stat exists(String path, boolean watch)

判斷某個 path 是否存在,并設定是否監控這個目錄節點,這里的 watcher 是在創建 ZooKeeper 實體時指定的 watcher,exists方法還有一個多載方法,可以指定特定的 watcher
<br >

Stat exists(String path, Watcher watcher)

多載方法,這里給某個目錄節點設定特定的 watcher,Watcher 在 ZooKeeper 是一個核心功能,Watcher 可以監控目錄節點的資料變化以及子目錄的變化,一旦這些狀態發生變化,服務器就會通知所有設定在這個目錄節點上的 Watcher,從而每個客戶端都很快知道它所關注的目錄節點的狀態發生變化,而做出相應的反應
<br >

void delete(String path, int version)

洗掉 path 對應的目錄節點,version 為 -1 可以匹配任何版本,也就洗掉了這個目錄節點所有資料
<br >

List<String> getChildren(String path, boolean watch)

獲取指定 path 下的所有子目錄節點,同樣 getChildren方法也有一個多載方法可以設定特定的 watcher 監控子節點的狀態
<br >

Stat setData(String path, byte[] data, int version)

給 path 設定資料,可以指定這個資料的版本號,如果 version 為 -1 怎可以匹配任何版本
<br >

byte[] getData(String path, boolean watch, Stat stat)

獲取這個 path 對應的目錄節點存盤的資料,資料的版本等資訊可以通過 stat 來指定,同時還可以設定是否監控這個目錄節點資料的狀態
<br >

void addAuthInfo(String scheme, byte[] auth)

客戶端將自己的授權資訊提交給服務器,服務器將根據這個授權資訊驗證客戶端的訪問權限,
<br >

Stat setACL(String path, List<ACL> acl, int version)    

給某個目錄節點重新設定訪問權限,需要注意的是 Zookeeper 中的目錄節點權限不具有傳遞性,父目錄節點的權限不能傳遞給子目錄節點,目錄節點 ACL 由兩部分組成:perms 和 id,
Perms 有 ALL、READ、WRITE、CREATE、DELETE、ADMIN 幾種
而 id 標識了訪問目錄節點的身份串列,默認情況下有以下兩種:
ANYONE_ID_UNSAFE = new Id("world", "anyone") 和 AUTH_IDS = new Id("auth", "") 分別表示任何人都可以訪問和創建者擁有訪問權限,
<br >

List<ACL> getACL(String path, Stat stat)

獲取某個目錄節點的訪問權限串列

除了以上這些上表中列出的方法之外還有一些多載方法,如都提供了一個回呼類的多載方法以及可以設定特定 Watcher 的多載方法,具體的方法可以參考 org.apache.zookeeper. ZooKeeper 類的 API 說明,

基本操作

下面給出基本的操作 ZooKeeper 的示例代碼,這樣你就能對 ZooKeeper 有直觀的認識了,下面的清單包括了創建與 ZooKeeper 服務器的連接以及最基本的資料操作:
清單 2. ZooKeeper 基本的操作示例

// 創建一個與服務器的連接
ZooKeeper zk = new ZooKeeper("localhost:" + CLIENT_PORT, 
       ClientBase.CONNECTION_TIMEOUT, new Watcher() { 
           // 監控所有被觸發的事件
           public void process(WatchedEvent event) { 
               System.out.println("已經觸發了" + event.getType() + "事件!"); 
           } 
       }); 
// 創建一個目錄節點
zk.create("/testRootPath", "testRootData".getBytes(), Ids.OPEN_ACL_UNSAFE,
  CreateMode.PERSISTENT); 
// 創建一個子目錄節點
zk.create("/testRootPath/testChildPathOne", "testChildDataOne".getBytes(),
  Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); 
System.out.println(new String(zk.getData("/testRootPath",false,null))); 
// 取出子目錄節點串列
System.out.println(zk.getChildren("/testRootPath",true)); 
// 修改子目錄節點資料
zk.setData("/testRootPath/testChildPathOne","modifyChildDataOne".getBytes(),-1); 
System.out.println("目錄節點狀態:["+zk.exists("/testRootPath",true)+"]"); 
// 創建另外一個子目錄節點
zk.create("/testRootPath/testChildPathTwo", "testChildDataTwo".getBytes(), 
  Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); 
System.out.println(new String(zk.getData("/testRootPath/testChildPathTwo",true,null))); 
// 洗掉子目錄節點
zk.delete("/testRootPath/testChildPathTwo",-1); 
zk.delete("/testRootPath/testChildPathOne",-1); 
// 洗掉父目錄節點
zk.delete("/testRootPath",-1); 
// 關閉連接
zk.close();

輸出的結果如下:

已經觸發了 None 事件!
testRootData 
[testChildPathOne] 
目錄節點狀態:[5,5,1281804532336,1281804532336,0,1,0,0,12,1,6] 
已經觸發了 NodeChildrenChanged 事件!
testChildDataTwo 
已經觸發了 NodeDeleted 事件!
已經觸發了 NodeDeleted 事件!

當對目錄節點監控狀態打開時,一旦目錄節點的狀態發生變化,Watcher 物件的 process 方法就會被呼叫,

上述面試題答案都整理成檔案筆記, 也還整理了一些面試資料&最新2020收集的一些大廠的面試真題(都整理成檔案,小部分截圖),有需要的可以 點擊進入暗號:csdn ,


ZooKeeper 典型的應用場景

Zookeeper 從設計模式角度來看,是一個基于觀察者模式設計的分布式服務管理框架,它負責存盤和管理大家都關心的資料,然后接受觀察者的注冊,一旦這些資料的狀態發生變化,Zookeeper 就將負責通知已經在 Zookeeper 上注冊的那些觀察者做出相應的反應,從而實作集群中類似 Master/Slave 管理模式,關于 Zookeeper 的詳細架構等內部細節可以閱讀 Zookeeper 的原始碼

下面詳細介紹這些典型的應用場景,也就是 Zookeeper 到底能幫我們解決那些問題?下面將給出答案,

統一命名服務(Name Service)

分布式應用中,通常需要有一套完整的命名規則,既能夠產生唯一的名稱又便于人識別和記住,通常情況下用樹形的名稱結構是一個理想的選擇,樹形的名稱結構是一個有層次的目錄結構,既對人友好又不會重復,說到這里你可能想到了 JNDI,沒錯 Zookeeper 的 Name Service 與 JNDI 能夠完成的功能是差不多的,它們都是將有層次的目錄結構關聯到一定資源上,但是 Zookeeper 的 Name Service 更加是廣泛意義上的關聯,也許你并不需要將名稱關聯到特定資源上,你可能只需要一個不會重復名稱,就像資料庫中產生一個唯一的數字主鍵一樣,

Name Service 已經是 Zookeeper 內置的功能,你只要呼叫 Zookeeper 的 API 就能實作,如呼叫 create 介面就可以很容易創建一個目錄節點,

配置管理(Configuration Management)

配置的管理在分布式應用環境中很常見,例如同一個應用系統需要多臺 PC Server 運行,但是它們運行的應用系統的某些配置項是相同的,如果要修改這些相同的配置項,那么就必須同時修改每臺運行這個應用系統的 PC Server,這樣非常麻煩而且容易出錯,

像這樣的配置資訊完全可以交給 Zookeeper 來管理,將配置資訊保存在 Zookeeper 的某個目錄節點中,然后將所有需要修改的應用機器監控配置資訊的狀態,一旦配置資訊發生變化,每臺應用機器就會收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置資訊應用到系統中,

圖 2. 配置管理結構圖

Paste_Image.png

集群管理(Group Membership)

Zookeeper 能夠很容易的實作集群管理的功能,如有多臺 Server 組成一個服務集群,那么必須要一個“總管”知道當前集群中每臺機器的服務狀態,一旦有機器不能提供服務,集群中其它集群必須知道,從而做出調整重新分配服務策略,同樣當增加集群的服務能力時,就會增加一臺或多臺 Server,同樣也必須讓“總管”知道,

Zookeeper 不僅能夠幫你維護當前的集群中機器的服務狀態,而且能夠幫你選出一個“總管”,讓這個總管來管理集群,這就是 Zookeeper 的另一個功能 Leader Election,

它們的實作方式都是在 Zookeeper 上創建一個 EPHEMERAL 型別的目錄節點,然后每個 Server 在它們創建目錄節點的父目錄節點上呼叫 getChildren(String path, boolean watch) 方法并設定 watch 為 true,由于是 EPHEMERAL 目錄節點,當創建它的 Server 死去,這個目錄節點也隨之被洗掉,所以 Children 將會變化,這時 getChildren上的 Watch 將會被呼叫,所以其它 Server 就知道已經有某臺 Server 死去了,新增 Server 也是同樣的原理,

Zookeeper 如何實作 Leader Election,也就是選出一個 Master Server,和前面的一樣每臺 Server 創建一個 EPHEMERAL 目錄節點,不同的是它還是一個 SEQUENTIAL 目錄節點,所以它是個 EPHEMERAL_SEQUENTIAL 目錄節點,之所以它是 EPHEMERAL_SEQUENTIAL 目錄節點,是因為我們可以給每臺 Server 編號,我們可以選擇當前是最小編號的 Server 為 Master,假如這個最小編號的 Server 死去,由于是 EPHEMERAL 節點,死去的 Server 對應的節點也被洗掉,所以當前的節點串列中又出現一個最小編號的節點,我們就選擇這個節點為當前 Master,這樣就實作了動態選擇 Master,避免了傳統意義上單 Master 容易出現單點故障的問題,

圖 3. 集群管理結構圖

Paste_Image.png

這部分的示例代碼如下,完整的代碼請看附件:

清單 3. Leader Election 關鍵代碼

void findLeader() throws InterruptedException { 
    byte[] leader = null; 
    try { 
        leader = zk.getData(root + "/leader", true, null); 
    } catch (Exception e) { 
        logger.error(e); 
    } 
    if (leader != null) { 
        following(); 
    } else { 
        String newLeader = null; 
        try { 
            byte[] localhost = InetAddress.getLocalHost().getAddress(); 
            newLeader = zk.create(root + "/leader", localhost, 
            ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); 
        } catch (Exception e) { 
            logger.error(e); 
        } 
        if (newLeader != null) { 
            leading(); 
        } else { 
            mutex.wait(); 
        } 
    } 
}

共享鎖(Locks)

共享鎖在同一個行程中很容易實作,但是在跨行程或者在不同 Server 之間就不好實作了,Zookeeper 卻很容易實作這個功能,實作方式也是需要獲得鎖的 Server 創建一個 EPHEMERAL_SEQUENTIAL 目錄節點,然后呼叫 getChildren方法獲取當前的目錄節點串列中最小的目錄節點是不是就是自己創建的目錄節點,如果正是自己創建的,那么它就獲得了這個鎖,如果不是那么它就呼叫 exists(String path, boolean watch) 方法并監控 Zookeeper 上目錄節點串列的變化,一直到自己創建的節點是串列中最小編號的目錄節點,從而獲得鎖,釋放鎖很簡單,只要洗掉前面它自己所創建的目錄節點就行了,

圖 4. Zookeeper 實作 Locks 的流程圖

Paste_Image.png

同步鎖的實作代碼如下,完整的代碼請看附件:
清單 4. 同步鎖的關鍵代碼

void getLock() throws KeeperException, InterruptedException{ 
    List<String> list = zk.getChildren(root, false); 
    String[] nodes = list.toArray(new String[list.size()]); 
    Arrays.sort(nodes); 
    if(myZnode.equals(root+"/"+nodes[0])){ 
        doAction(); 
    } 
    else{ 
        waitForLock(nodes[0]); 
    } 
} 

void waitForLock(String lower) throws InterruptedException, KeeperException {
    Stat stat = zk.exists(root + "/" + lower,true); 
    if(stat != null){ 
        mutex.wait(); 
    } 
    else{ 
        getLock(); 
    } 
}

佇列管理

Zookeeper 可以處理兩種型別的佇列:

  1. 當一個佇列的成員都聚齊時,這個佇列才可用,否則一直等待所有成員到達,這種是同步佇列,
  2. 佇列按照 FIFO 方式進行入隊和出隊操作,例如實作生產者和消費者模型,

同步佇列用 Zookeeper 實作的實作思路如下:
創建一個父目錄 /synchronizing,每個成員都監控標志(Set Watch)位目錄 /synchronizing/start 是否存在,然后每個成員都加入這個佇列,加入佇列的方式就是創建 /synchronizing/member_i 的臨時目錄節點,然后每個成員獲取 / synchronizing 目錄的所有目錄節點,也就是 member_i,判斷 i 的值是否已經是成員的個數,如果小于成員個數等待 /synchronizing/start 的出現,如果已經相等就創建 /synchronizing/start,

用下面的流程圖更容易理解:

Paste_Image.png

同步佇列的關鍵代碼如下,完整的代碼請看附件:

清單 5. 同步佇列

void addQueue() throws KeeperException, InterruptedException{ 
    zk.exists(root + "/start",true); 
    zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE, 
    CreateMode.EPHEMERAL_SEQUENTIAL); 
    synchronized (mutex) { 
        List<String> list = zk.getChildren(root, false); 
        if (list.size() < size) { 
            mutex.wait(); 
        } else { 
            zk.create(root + "/start", new byte[0], Ids.OPEN_ACL_UNSAFE,
             CreateMode.PERSISTENT); 
        } 
    } 
}

當佇列沒滿是進入 wait(),然后會一直等待 Watch 的通知,Watch 的代碼如下:

public void process(WatchedEvent event) { 
    if(event.getPath().equals(root + "/start") &&
     event.getType() == Event.EventType.NodeCreated){ 
        System.out.println("得到通知"); 
        super.process(event); 
        doAction(); 
    } 
}

FIFO 佇列用 Zookeeper 實作思路如下:
實作的思路也非常簡單,就是在特定的目錄下創建 SEQUENTIAL 型別的子目錄 /queue_i,這樣就能保證所有成員加入佇列時都是有編號的,出佇列時通過 getChildren( ) 方法可以回傳當前所有的佇列中的元素,然后消費其中最小的一個,這樣就能保證 FIFO,

下面是生產者和消費者這種佇列形式的示例代碼,完整的代碼請看附件:
清單 6. 生產者代碼

boolean produce(int i) throws KeeperException, InterruptedException{ 
    ByteBuffer b = ByteBuffer.allocate(4); 
    byte[] value; 
    b.putInt(i); 
    value = b.array(); 
    zk.create(root + "/element", value, ZooDefs.Ids.OPEN_ACL_UNSAFE, 
                CreateMode.PERSISTENT_SEQUENTIAL); 
    return true; 
}

清單 7. 消費者代碼

int consume() throws KeeperException, InterruptedException{ 
    int retvalue = -1; 
    Stat stat = null; 
    while (true) { 
        synchronized (mutex) { 
            List<String> list = zk.getChildren(root, true); 
            if (list.size() == 0) { 
                mutex.wait(); 
            } else { 
                Integer min = new Integer(list.get(0).substring(7)); 
                for(String s : list){ 
                    Integer tempValue = new Integer(s.substring(7)); 
                    if(tempValue < min) min = tempValue; 
                } 
                byte[] b = zk.getData(root + "/element" + min,false, stat); 
                zk.delete(root + "/element" + min, 0); 
                ByteBuffer buffer = ByteBuffer.wrap(b); 
                retvalue = buffer.getInt(); 
                return retvalue; 
            } 
        } 
    } 
}

總結

Zookeeper 作為 Hadoop 專案中的一個子專案,是 Hadoop 集群管理的一個必不可少的模塊,它主要用來控制集群中的資料,如它管理 Hadoop 集群中的 NameNode,還有 Hbase 中 Master Election、Server 之間狀態同步等,

本文介紹的 Zookeeper 的基本知識,以及介紹了幾個典型的應用場景,這些都是 Zookeeper 的基本功能,最重要的是 Zoopkeeper 提供了一套很好的分布式集群管理的機制,就是它這種基于層次型的目錄樹的資料結構,并對樹中的節點進行有效管理,從而可以設計出多種多樣的分布式的資料管理模型,而不僅僅局限于上面提到的幾個常用應用場景,


到此這篇關于文章就結束了!

點關注,不迷路!如果本文對你有幫助的話不要忘記點贊支持哦!

上述面試題答案都整理成檔案筆記, 也還整理了一些面試資料&最新2020收集的一些大廠的面試真題(都整理成檔案,小部分截圖),有需要的可以 點擊進入暗號:csdn ,

希望對大家有所幫助,有用的話點贊給我支持!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/44783.html

標籤:其他

上一篇:【Redis】求求你,別再問跳表了

下一篇:Vuex基礎淺析

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more