<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試必備,ZooKeeper最全基礎(chǔ)知識!

          共 5469字,需瀏覽 11分鐘

           ·

          2022-01-03 06:32


          一、ZooKeeper總體介紹

          1.1、什么是zookeeper

          ZooKeeper 是一個分布式的,開放源碼的分布式應(yīng)用程序協(xié)同服務(wù)+存儲系統(tǒng),同時是一款世界級的優(yōu)秀開源產(chǎn)品,在大數(shù)據(jù)生態(tài)系統(tǒng)中 Hadoop、Storm、HBase、Spark、Flink、Kafka 隨處都是 ZooKeeper的應(yīng)用場景。特別是在粗粒度分布式鎖、分布式選主、主備高可用切換等不需要高 TPS 的場景下有不可替代的作用。

          1.2、ZooKeeper 應(yīng)用場景

          很多分布式協(xié)調(diào)服務(wù)都可以用 ZooKeeper 來做,其中典型應(yīng)用場景如下:
          1、配置管理:比如微服務(wù)系統(tǒng),各個獨立服務(wù)都要使用集中化的配置管理,這個時候就需要 ZooKeeper。
          2、組成員管理:比如上面講到的 HBase 其實就是用來做集群的組成員管理。
          3、各種分布式鎖:ZooKeeper 適用于存儲和協(xié)同相關(guān)的關(guān)鍵數(shù)據(jù),不適合用于大數(shù)據(jù)量存儲。如果要存 KV 或者大量的業(yè)務(wù)數(shù)據(jù),還是要用數(shù)據(jù)庫或者其他 NoSql 來做。
          4、注冊中心:大多數(shù)中小型公司都用zk來做注冊中心

          至于為什么 ZooKeeper 不適合大數(shù)據(jù)量存儲呢?主要有以下兩個原因:
          1、設(shè)計方面:ZooKeeper 需要把所有的數(shù)據(jù)(它的 data tree)加載到內(nèi)存中。這就決定了ZooKeeper 存儲的數(shù)據(jù)量受內(nèi)存的限制。一般的數(shù)據(jù)庫系統(tǒng)例如 MySQL可以存儲大于內(nèi)存的數(shù)據(jù),這是因為 InnoDB 是基于 B-Tree 的存儲引擎(基于內(nèi)存+磁盤一致性)。
          2、工程方面:ZooKeeper 的設(shè)計目標(biāo)是為協(xié)同服務(wù)提供數(shù)據(jù)存儲,數(shù)據(jù)的高可用性和性能是最重要的系統(tǒng)指標(biāo),處理大數(shù)量不是 ZooKeeper 的首要目標(biāo)。因此,ZooKeeper 不會對大數(shù)量存儲做太多工程上的優(yōu)化。

          二.ZooKeeper源碼環(huán)境

          2.1、ZooKeeper版本選擇

          在了解任何技術(shù)源碼的時候,最重要的兩件事要搞清楚:
          1、版本如何選擇
          2、源碼環(huán)境準(zhǔn)備
          zookeeper的大版本:
          1、zookeeper-3.4.x 企業(yè)最常用,大數(shù)據(jù)技術(shù)組件最常用
          2、zookeeper-3.5.x
          3、zookeeper-3.6.x
          最總結(jié)論:zookeeper-3.4.14.tar.gz,安裝包就是源碼包, ZooKeeper-3.5 以上,源碼 和 安裝包就分開了。

          2.2、 ZooKeeper源碼環(huán)境準(zhǔn)備

          1、準(zhǔn)備一個IDE:IDEA
          2、從官網(wǎng)下載源碼包,IDEA去導(dǎo)入這個源碼項目即可
          3、稍微等待一下,maven去下載一些依賴jar
          4、從官網(wǎng)下載 zookeeper-3.4.14.tar.gz 安裝包,該安裝包直接包含源碼或者從 github 去拉取源碼項目

          三.ZooKeeper基礎(chǔ)之序列化機制

          3.1、序列化使用場景

          1、當(dāng)在網(wǎng)絡(luò)中需要進(jìn)行消息,數(shù)據(jù)傳輸,那么這些數(shù)據(jù)就需要進(jìn)行序列化和反序列化
          2、當(dāng)數(shù)據(jù)需要被持久化到磁盤的時候

          3.2、什么是序列化, 為什么要進(jìn)行序列化操作

          1、序列化是指將我們定義好的 go/php/java 類型轉(zhuǎn)化成數(shù)據(jù)流的形式。之所以這么做是因為在網(wǎng)絡(luò)傳輸過程中,TCP 協(xié)議采用“流通信”的方式,提供了可以讀寫的字節(jié)流
          2、任何一個分布式系統(tǒng)的底層,都必然會有網(wǎng)絡(luò)通信,這就必然要提供一個分布式通信框架和序列化機制。所以我們在看 ZooKeeper 源碼之前,先搞定 ZooKeeper 網(wǎng)絡(luò)通信和序列化。

          3.3、序列化實現(xiàn)方式

          3.3.1、java序列化實現(xiàn)

          Java 中進(jìn)行序列化和反序列化的過程中,主要使用 ObjectInputStream 和 ObjectOutputStream 來進(jìn)行具體的序列化和反序列化。

          3.3.2、hadoop的序列化實現(xiàn)

          3.3.3、ZooKeeper 中的序列化機制

          序列化的 API 主要在 zookeeper-jute 子項目中。

          3.3.4、重點API:

          org.apache.jute.InputArchive:反序列化需要實現(xiàn)的接口,其中各種 read 開頭的方法,都是反序列化方法
          org.apache.jute.OutputArchive:所有進(jìn)行序列化操作的都是實現(xiàn)這個接口,其中各種 write 開頭的方法都是序列化方法。
          org.apache.jute.Index:用于迭代數(shù)據(jù)進(jìn)行反序列化的迭代器
          org.apache.jute.Record:在 ZooKeeper 要進(jìn)行網(wǎng)絡(luò)通信的對象,都需要實現(xiàn)這個接口。里面有序列化和反序列化兩個重要的方法

          四、ZooKeeper基礎(chǔ)之持久化機制

          對于只要底層涉及到關(guān)于數(shù)據(jù)的存儲,讀寫操作, 一般都會有一個持久化機制來保證.那么ZooKeeper的數(shù)據(jù)模型主要涉及兩類知識:數(shù)據(jù)模型?和?持久化機制, 背后是兩套API來支撐

          1、數(shù)據(jù)模型 : ZKDataBase + DataTree + DataNode
          2、持久化機制: TxnLog + SnapLog

          ZooKeeper 本身是一個對等架構(gòu)(內(nèi)部選舉,從所有 learner 中選舉一個 leader, 剩下的成為follower)

          1、每個節(jié)點上都保存了整個系統(tǒng)的所有數(shù)據(jù)(leader存儲了數(shù)據(jù),所有的follower節(jié)點都是leader的副本節(jié)點)
          2、每個節(jié)點上的都把數(shù)據(jù)放在磁盤一份,放在內(nèi)存一份, 保證磁盤跟內(nèi)存一致性,來平衡讀寫性能

          ZooKeeper的數(shù)據(jù)模型,抽象出了重要的三個API用來完成數(shù)據(jù)的管理:

          1、ZKDataBase 負(fù)責(zé)管理 DataTree ,執(zhí)行 DataTree 的相關(guān) 快照和恢復(fù)的操作
          2、DataTree znode系統(tǒng)的完整抽象, 整個數(shù)據(jù)樹結(jié)構(gòu)
          3、DataNode znode 系統(tǒng)中的一個節(jié)點的抽象

          關(guān)于 ZooKeeper 中的數(shù)據(jù)在內(nèi)存中的組織,其實就是一棵樹:

          1、這棵樹就叫做:DataTree (抽象了一棵樹)
          2、這棵樹上的節(jié)點:DataNode (抽象一個節(jié)點)
          3、關(guān)于管理這個 DataTree 的組件就是 ZKDataBase (內(nèi)存數(shù)據(jù)庫:針對 DataTree 能做各種操作)

          ZooKeeper 的持久化的一些操作接口,都在org.apache.zookeeper.server.persistence 包中。




          主要的類的介紹:

          第一組:主要是用來操作日志的(如果客戶端往zk中寫入一條數(shù)據(jù),則記錄一條日志)
          TxnLog,接口,讀取事務(wù)性日志的接口。
          FileTxnLog,實現(xiàn)TxnLog接口,添加了訪問該事務(wù)性日志的API。
          第二組:拍攝快照(當(dāng)內(nèi)存數(shù)據(jù)持久化到磁盤)
          Snapshot,接口類型,持久層快照接口。
          FileSnap,實現(xiàn)Snapshot接口,負(fù)責(zé)存儲、序列化、反序列化、訪問快照。
          第三組;兩個成員變量:TxnLog和SnapShot
          FileTxnSnapLog,封裝了TxnLog和SnapShot。
          第四組:工具類
          Util,工具類,提供持久化所需的API。

          五、ZooKeeper基礎(chǔ)之網(wǎng)絡(luò)通信機制

          Java IO 有幾個種類:

          1、BIO JDK-1.1(編碼簡單,效率低) 阻塞模型
          2、NIO JDK-1.4(效率有提升,編碼復(fù)雜) 基于reactor實現(xiàn)的異步非阻塞網(wǎng)絡(luò)通信模型 通常的IO的選擇:
          1)、原生NIO 2)、基于NIO實現(xiàn)的網(wǎng)絡(luò)通信框架:netty
          3、AIO JDK-1.7(效率最高,編碼復(fù)雜度一般) 真正的異步非阻塞通信模型

          NIO 的三大API:

          1、Buffer
          2、Channel
          3、Selector

          ZooKeeper 中的通信有兩種方式:

          1、NIO,默認(rèn)使用NIO
          2、Netty

          兩個最重要的API:

          ServerCnxn 服務(wù)端的通信組件
          ClientCnxn 客戶端的通信組件

          關(guān)于客戶端和服務(wù)端的一個定義:誰發(fā)請求,誰就是客戶端,誰接收和處理請求,誰就是服務(wù)端

          1、真正的client給zookeeper發(fā)請求
          2、zookeeper中的leader給follower發(fā)命令
          3、zookeeper中的followe給leader發(fā)請求

          ServerCnxn實現(xiàn)包:org.apache.zookeeper.server.ServerCnxn


          ServerCnxn實現(xiàn)包

          詳細(xì)說明:
          Stats,表示ServerCnxn上的統(tǒng)計數(shù)據(jù)。
          Watcher,表示事件處理,監(jiān)聽器
          ServerCnxn,表示服務(wù)器連接,表示一個從客戶端到服務(wù)器的連接。
          ClientCnxn,存在于客戶端用來執(zhí)行通信的組件
          NettyServerCnxn,基于Netty的連接的具體實現(xiàn)。
          NIOServerCnxn,基于NIO的連接的具體實現(xiàn)。

          六、Zookeeper基礎(chǔ)之Watcher工作機制

          客戶端的 Watcher 注冊:

          1、org.apache.zookeeper.ZooKeeper:客戶端基礎(chǔ)類、存儲了ClientCnxn和ZkWatcherManager
          2、ZKWatchManager:ZooKeeper的內(nèi)部類,實現(xiàn)了ClientWatchManager接口,主要用來存儲各種類型的Watcher,主要有三種:dataWatches、existWatches、childWatches以及一個默認(rèn)的defaultWatcher
          3、org.apache.zookeeper.ClientCnxn:與服務(wù)端的交互類,主要包含以下對象:LinkedListoutgoingQueue、SendThread 和 EventThread,其中outgoingQueue未待發(fā)送給服務(wù)端的Packet列表,SendThread線程負(fù)責(zé)和服務(wù)端進(jìn)行請求交互,而EventThread線程則負(fù)責(zé)客戶端Watcher事件的回調(diào)執(zhí)行
          4、WatchRegistration:Zookeeper的內(nèi)容類,包裝了Watcher和clientPath,并且負(fù)責(zé)Watcher的注冊
          5、Packet:ClientCnxn的內(nèi)部類,與Zookeeper服務(wù)端通信的交互類

          兩條主線

          1、實現(xiàn)主線:Watcher + WatchedEvent
          2、管理主線:WatchManager(負(fù)責(zé)響應(yīng)watcher.process(watchedEvent)) + ZKWatchManager(負(fù)責(zé)注冊等相關(guān)管理)

          組件說明:

          Watcher,接口類型,其定義了process方法,需子類實現(xiàn)。
          Event,接口類型,Watcher的內(nèi)部類,無任何方法。
          KeeperState,枚舉類型,Event的內(nèi)部類,表示Zookeeper所處的狀態(tài)。
          EventType,枚舉類型,Event的內(nèi)部類,表示Zookeeper中發(fā)生的事件類型。
          WatchedEvent,表示對ZooKeeper上發(fā)生變化后的反饋,包含了KeeperState和EventType。
          ClientWatchManager,接口類型,表示客戶端的Watcher管理者,其定義了materialized方法,需子類實現(xiàn)。
          ZKWatchManager,Zookeeper的內(nèi)部類,繼承ClientWatchManager。
          MyWatcher,ZooKeeperMain的內(nèi)部類,繼承Watcher。
          ServerCnxn,接口類型,繼承Watcher,表示客戶端與服務(wù)端的一個連接。
          WatchManager,管理Watcher。

          Watcher 主要工作流程:

          1、用戶調(diào)用 Zookeeper 的 getData 方法,并將自定義的 Watcher 以參數(shù)形式傳入,該方法的作用主要是封裝請求,然后調(diào)用 ClientCnxn 的 submitRequest 方法提交請求
          2、 ClientCnxn 在調(diào)用 submitRequest 提交請求時,會將 WatchRegistration(封裝了我們傳入的Watcher 和clientPath )以參數(shù)的形式傳入,submitRequest 方法主要作用是將信息封裝成Packet(ClientCnxn的內(nèi)部類),并將封裝好的 Packet 加入到 ClientCnxn 的待發(fā)送列表中(LinkedList outgoingQueue)
          3、 SendThread 線程不斷地從 outgoingQueue 取出未發(fā)送的 Packet 發(fā)送給客戶端并且將該 Packet加入pendingQueue (等待服務(wù)器響應(yīng)的Packet列表)中,并通過自身的 readResponse 方法接收服務(wù)端的響應(yīng)
          4、SendThread 接收到客戶端的響應(yīng)以后,會調(diào)用 ClientCnxn 的finishPacket 方法進(jìn)行 Watcher方法的注冊
          5、在 finishPacket 方法中,會取出 Packet 中的 WatchRegistration 對象,并調(diào)用其 register 方法,從ZKWatchManager 取出對應(yīng)的 dataWatches、existWatches 或者 childWatches 其中的一個Watcher 集合,然后將自己的 Watcher 添加到該 Watcher 集合中。

          未完待續(xù),下篇接著繼續(xù)分析


          瀏覽 48
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大乐透开奖号码结果 | 肏屄视频免费在线观看 | 欧美成人一区二区三区高清 | 97爱视频 | 人人操 超碰 |