ZooKeeper 提供了什麼?

  1. ZooKeeper 提供了什麼? 
    1.文件系統
    2.通知機制
  2. Zookeeper 文件系統
    Zookeeper 提供一個多層級的節點命名空間(節點稱爲 znode)。與文件系統不同的是,這些節點都可以設置關聯的數據,而文件系統中只有文件節點可以存放數據而目錄節點不行。
    Zookeeper 爲了保證高吞吐和低延遲,在內存中維護了這個樹狀的目錄結構,這種特性使得 Zookeeper 不能用於存放大量的數據,每個節點的存放數據上限爲1M。
  3. ZAB 協議?
    ZAB 協議是爲分佈式協調服務 Zookeeper 專門設計的一種支持崩潰恢復的原子廣播協議。
    ZAB 協議包括兩種基本的模式:崩潰恢復和消息廣播。
    當整個 zookeeper 集羣剛剛啓動或者 Leader 服務器宕機、重啓或者網絡故障導致不存在過半的服務器與 Leader 服務器保持正常通信時,所有進程(服務器)進入崩潰恢復模式,首先選舉產生新的 Leader 服務器,然後集羣中 Follower 服務器開始與新的 Leader 服務器進行數據同步,當集羣中超過半數機器與該 Leader服務器完成數據同步之後,退出恢復模式進入消息廣播模式,Leader 服務器開始接收客戶端的事務請求生成事物提案來進行事務請求處理。 
  4. 四種類型的數據節點 Znode 
    1、PERSISTENT-持久節點
    除非手動刪除,否則節點一直存在於 Zookeeper 上 
    2、EPHEMERAL-臨時節點
    臨時節點的生命週期與客戶端會話綁定,一旦客戶端會話失效(客戶端與zookeeper 連接斷開不一定會話失效),那麼這個客戶端創建的所有臨時節點都會被移除。 
    3、PERSISTENT_SEQUENTIAL-持久順序節點
    基本特性同持久節點,只是增加了順序屬性,節點名後邊會追加一個由父節點維護的自增整型數字。 
    4、EPHEMERAL_SEQUENTIAL-臨時順序節點
    基本特性同臨時節點,增加了順序屬性,節點名後邊會追加一個由父節點維護的自增整型數字。 
  5. Zookeeper Watcher 機制 -- 數據變更通知 
    Zookeeper 允許客戶端向服務端的某個 Znode 註冊一個 Watcher 監聽,當服務端的一些指定事件觸發了這個 Watcher,服務端會向指定客戶端發送一個事件通知來實現分佈式的通知功能,然後客戶端根據 Watcher 通知狀態和事件類型做出業務上的改變。 
    工作機制: 
    1.客戶端註冊 watcher
    2.服務端處理 watcher
    3.客戶端回調 watcher 
    Watcher 特性總結:
    1、一次性
    無論是服務端還是客戶端,一旦一個 Watcher 被觸發,Zookeeper 都會將其從相應的存儲中移除。這樣的設計有效的減輕了服務端的壓力,不然對於更新非常頻繁的節點,服務端會不斷的向客戶端發送事件通知,無論對於網絡還是服務端的壓力都非常大。
    2、客戶端串行執行
    客戶端 Watcher 回調的過程是一個串行同步的過程。
    3、輕量 
    3.1、Watcher 通知非常簡單,只會告訴客戶端發生了事件,而不會說明事件的具體內容。
    3.2、客戶端向服務端註冊 Watcher 的時候,並不會把客戶端真實的 Watcher 對象實體傳遞到服務端,僅僅是在客戶端請求中使用 boolean 類型屬性進行了標記。
    4、watcher event 異步發送 watcher 的通知事件從 server 發送到 client 是異步的,這就存在一個問題,不同的客戶端和服務器之間通過 socket 進行通信,由於網絡延遲或其他因素導致客戶端在不通的時刻監聽到事件,由於 Zookeeper 本身提供了 ordering guarantee,即客戶端監聽事件後,纔會感知它所監視 znode發生了變化。所以我們使用 Zookeeper 不能期望能夠監控到節點每次的變化。Zookeeper 只能保證最終的一致性,而無法保證強一致性。
    5、註冊 watcher getData、exists、getChildren
    6、觸發 watcher create、delete、setData
    7、當一個客戶端連接到一個新的服務器上時,watch 將會被以任意會話事件觸發。當與一個服務器失去連接的時候,是無法接收到 watch 的。而當 client 重新連接時,如果需要的話,所有先前註冊過的 watch,都會被重新註冊。通常這是完全透明的。只有在一個特殊情況下,watch 可能會丟失:對於一個未創建的 znode的 exist watch,如果在客戶端斷開連接期間被創建了,並且隨後在客戶端連接上之前又刪除了,這種情況下,這個 watch 事件可能會被丟失。 
  6. 客戶端註冊 Watcher 實現
    1.調用 getData()/getChildren()/exist()三個 API,傳入 Watcher 對象
    2.標記請求 request,封裝 Watcher 到 WatchRegistration
    3.封裝成 Packet 對象,發服務端發送 request
    4.收到服務端響應後,將 Watcher 註冊到 ZKWatcherManager 中進行管理
    5.請求返回,完成註冊。 
  7. 服務端處理 Watcher 實現
    1、服務端接收 Watcher 並存儲
    接收到客戶端請求,處理請求判斷是否需要註冊 Watcher,需要的話將數據節點的節點路徑和 ServerCnxn(ServerCnxn 代表一個客戶端和服務端的連接,實現了 Watcher 的 process 接口,此時可以看成一個 Watcher 對象)存儲在WatcherManager 的 WatchTable 和 watch2Paths 中去。
    2、Watcher 觸發
    以服務端接收到 setData() 事務請求觸發 NodeDataChanged 事件爲例: 
    2.1 封裝 WatchedEvent 
    將通知狀態(SyncConnected)、事件類型(NodeDataChanged)以及節點路徑封裝成一個 WatchedEvent 對象 
    2.2 查詢 Watcher
    從 WatchTable 中根據節點路徑查找 Watcher 
    2.3 沒找到;說明沒有客戶端在該數據節點上註冊過 Watcher 
    2.4 找到;提取並從 WatchTable 和 Watch2Paths 中刪除對應 Watcher(從這裏可以看出 Watcher 在服務端是一次性的,觸發一次就失效了) 
    3、調用 process 方法來觸發 Watcher
    這裏 process 主要就是通過 ServerCnxn 對應的 TCP 連接發送 Watcher 事件通知。 
  8. 客戶端回調 Watcher 
    客戶端 SendThread 線程接收事件通知,交由 EventThread 線程回調 Watcher。
    客戶端的 Watcher 機制同樣是一次性的,一旦被觸發後,該 Watcher 就失效了。 
  9. ACL 權限控制機制 
    UGO(User/Group/Others) 
    目前在 Linux/Unix 文件系統中使用,也是使用最廣泛的權限控制方式。是一種粗粒度的文件系統權限控制模式。
    ACL(Access Control List)訪問控制列表 
    包括三個方面: 
    權限模式(Scheme)
    1、IP:從 IP 地址粒度進行權限控制
    2、Digest:最常用,用類似於 username:password 的權限標識來進行權限配
    置,便於區分不同應用來進行權限控制
    3、World:最開放的權限控制方式,是一種特殊的 digest 模式,只有一個權限標
    識“world:anyone”
    4、Super:超級用戶
    授權對象
    授權對象指的是權限賦予的用戶或一個指定實體,例如 IP 地址或是機器燈。
    權限 Permission 
    1.CREATE:數據節點創建權限,允許授權對象在該 Znode 下創建子節點
    2.DELETE:子節點刪除權限,允許授權對象刪除該數據節點的子節點
    3.READ:數據節點的讀取權限,允許授權對象訪問該數據節點並讀取其數據內容或子節點列表等
    4.WRITE:數據節點更新權限,允許授權對象對該數據節點進行更新操作
    5.ADMIN:數據節點管理權限,允許授權對象對該數據節點進行 ACL 相關設置操作 
  10. Chroot 特性
    3.2.0 版本後,添加了 Chroot 特性,該特性允許每個客戶端爲自己設置一個命名空間。如果一個客戶端設置了 Chroot,那麼該客戶端對服務器的任何操作,都將會被限制在其自己的命名空間下。 
    通過設置 Chroot,能夠將一個客戶端應用於 Zookeeper 服務端的一顆子樹相對應,在那些多個應用公用一個 Zookeeper 進羣的場景下,對實現不同應用間的相互隔離非常有幫助。
  11. 會話管理
    分桶策略:將類似的會話放在同一區塊中進行管理,以便於 Zookeeper 對會話進
    行不同區塊的隔離處理以及同一區塊的統一處理。
    分配原則:每個會話的“下次超時時間點”(ExpirationTime) 
    計算公式: 
    ExpirationTime = currentTime + sessionTimeout
    ExpirationTime = (ExpirationTime
     / ExpirationInrerval + 1) *
    ExpirationInterval , ExpirationInterval 是指 Zookeeper 會話超時檢查時間
    間隔,默認 tickTime複製代碼
  12. 服務器角色
    Leader
    1、事務請求的唯一調度和處理者,保證集羣事務處理的順序性
    2、集羣內部各服務的調度者 
    Follower 
    1、處理客戶端的非事務請求,轉發事務請求給 Leader 服務器
    2、參與事務請求 Proposal 的投票
    3、參與 Leader 選舉投票 
    Observer
    1.3.0 版本以後引入的一個服務器角色,在不影響集羣事務處理能力的基礎上提升集羣的非事務處理能力
    2.處理客戶端的非事務請求,轉發事務請求給 Leader 服務器
    3.不參與任何形式的投票 
  13. Zookeeper 下 Server 工作狀態
    服務器具有四種狀態,分別是 LOOKING、FOLLOWING、LEADING、OBSERVING。 
    1.LOOKING:尋找 Leader 狀態。當服務器處於該狀態時,它會認爲當前集羣中沒有 Leader,因此需要進入 Leader 選舉狀態。
    2.FOLLOWING:跟隨者狀態。表明當前服務器角色是 Follower。
    3.LEADING:領導者狀態。表明當前服務器角色是 Leader。
    4.OBSERVING:觀察者狀態。表明當前服務器角色是 Observer。 
  14. 數據同步
    整個集羣完成 Leader 選舉之後,Learner(Follower 和 Observer 的統稱)迴向Leader 服務器進行註冊。當 Learner 服務器想 Leader 服務器完成註冊後,進入數據同步環節。 
    數據同步流程:(均以消息傳遞的方式進行) 
    Learner 向 Learder 註冊
    數據同步
    同步確認
    Zookeeper 的數據同步通常分爲四類:
    1.直接差異化同步(DIFF 同步)
    2.先回滾再差異化同步(TRUNC+DIFF 同步)
    3.僅回滾同步(TRUNC 同步)
    4.全量同步(SNAP 同步) 
    在進行數據同步前,Leader 服務器會完成數據同步初始化:
    peerLastZxid: 
    從 learner 服務器註冊時發送的 ACKEPOCH 消息中提取 lastZxid(該Learner 服務器最後處理的 ZXID) 
    minCommittedLog:
    Leader 服務器 Proposal 緩存隊列 committedLog 中最小 ZXID 
    maxCommittedLog: 
    Leader 服務器 Proposal 緩存隊列 committedLog 中最大 ZXID 
    直接差異化同步(DIFF 同步)
    場景:peerLastZxid 介於 minCommittedLog 和 maxCommittedLog之間 
    先回滾再差異化同步(TRUNC+DIFF 同步)
    場景:當新的 Leader 服務器發現某個 Learner 服務器包含了一條自己沒有的事務記錄,那麼就需要讓該 Learner 服務器進行事務回滾--回滾到 Leader服務器上存在的,同時也是最接近於 peerLastZxid 的 ZXID
    僅回滾同步(TRUNC 同步)
    場景:peerLastZxid 大於 maxCommittedLog
    全量同步(SNAP 同步)
    場景一:peerLastZxid 小於 minCommittedLog
    場景二:Leader 服務器上沒有 Proposal 緩存隊列且 peerLastZxid 不等於 lastProcessZxid
  15. zookeeper 是如何保證事務的順序一致性的? 
    zookeeper 採用了全局遞增的事務 Id 來標識,所有的 proposal(提議)都在被提出的時候加上了 zxid,zxid 實際上是一個 64 位的數字,高 32 位是 epoch(時期; 紀元; 世; 新時代)用來標識 leader 週期,如果有新的 leader 產生出來,epoch會自增,低 32 位用來遞增計數。當新產生 proposal 的時候,會依據數據庫的兩階段過程,首先會向其他的 server 發出事務執行請求,如果超過半數的機器都能執行並且能夠成功,那麼就會開始執行。
  16. 分佈式集羣中爲什麼會有 Master? 
    在分佈式環境中,有些業務邏輯只需要集羣中的某一臺機器進行執行,其他的機器可以共享這個結果,這樣可以大大減少重複計算,提高性能,於是就需要進行leader 選舉。 
  17. zk 節點宕機如何處理?
    Zookeeper 本身也是集羣,推薦配置不少於 3 個服務器。Zookeeper 自身也要保證當一個節點宕機時,其他節點會繼續提供服務。
    如果是一個 Follower 宕機,還有 2 臺服務器提供訪問,因爲 Zookeeper 上的數據是有多個副本的,數據並不會丟失;
    如果是一個 Leader 宕機,Zookeeper 會選舉出新的 Leader。
    ZK 集羣的機制是隻要超過半數的節點正常,集羣就能正常提供服務。只有在 ZK節點掛得太多,只剩一半或不到一半節點能工作,集羣才失效。所以
    3 個節點的 cluster 可以掛掉 1 個節點(leader 可以得到 2 票>1.5)
    2 個節點的 cluster 就不能掛掉任何 1 個節點了(leader 可以得到 1 票<=1)
  18. zookeeper 負載均衡和 nginx 負載均衡區別 
    zk 的負載均衡是可以調控,nginx 只是能調權重,其他需要可控的都需要自己寫插件;但是 nginx 的吞吐量比 zk 大很多,應該說按業務選擇用哪種方式。 
  19. Zookeeper 有哪幾種幾種部署模式?
    部署模式:單機模式、僞集羣模式、集羣模式。
  20. 集羣最少要幾臺機器,集羣規則是怎樣的? 
    集羣規則爲 2N+1 臺,N>0,即 3 臺。
  21. 集羣支持動態添加機器嗎?
    其實就是水平擴容了,Zookeeper 在這方面不太好。兩種方式:
    全部重啓:關閉所有 Zookeeper 服務,修改配置之後啓動。不影響之前客戶端的會話。 
    逐個重啓:在過半存活即可用的原則下,一臺機器重啓不影響整個集羣對外提供服務。這是比較常用的方式。 
    3.5 版本開始支持動態擴容。
  22. Zookeeper 對節點的 watch監聽通知是永久的嗎?爲什麼不是永久的? 
    不是。官方聲明:一個 Watch 事件是一個一次性的觸發器,當被設置了 Watch的數據發生了改變的時候,則服務器將這個改變發送給設置了 Watch 的客戶端,以便通知它們。
    爲什麼不是永久的,舉個例子,如果服務端變動頻繁,而監聽的客戶端很多情況下,每次變動都要通知到所有的客戶端,給網絡和服務器造成很大壓力。
    一般是客戶端執行 getData(“/節點 A”,true),如果節點 A 發生了變更或刪除,客戶端會得到它的 watch 事件,但是在之後節點 A 又發生了變更,而客戶端又沒有設置 watch 事件,就不再給客戶端發送。
    在實際應用中,很多情況下,我們的客戶端不需要知道服務端的每一次變動,我只要最新的數據即可。
  23. Zookeeper 的 java 客戶端都有哪些? 
    java 客戶端:zk 自帶的 zkclient 及 Apache 開源的 Curator。
  24. chubby 是什麼,和 zookeeper 比你怎麼看? 
    chubby 是 google 的,完全實現 paxos 算法,不開源。zookeeper 是 chubby的開源實現,使用 zab 協議,paxos 算法的變種。
  25. 說幾個 zookeeper 常用的命令。
    常用命令:ls get set create delete 等。
  26. ZAB 和 Paxos 算法的聯繫與區別?
    相同點: 
    1、兩者都存在一個類似於 Leader 進程的角色,由其負責協調多個 Follower 進程的運行
    2、Leader 進程都會等待超過半數的 Follower 做出正確的反饋後,纔會將一個提案進行提交
    3、ZAB 協議中,每個 Proposal 中都包含一個 epoch 值來代表當前的 Leader週期,Paxos 中名字爲 Ballot
    不同點: 
    ZAB 用來構建高可用的分佈式數據主備系統(Zookeeper),Paxos 是用來構建分佈式一致性狀態機系統。 
  27. Zookeeper 的典型應用場景
    Zookeeper 是一個典型的發佈/訂閱模式的分佈式數據管理與協調框架,開發人員可以使用它來進行分佈式數據的發佈和訂閱。
    通過對 Zookeeper 中豐富的數據節點進行交叉使用,配合 Watcher 事件通知機制,可以非常方便的構建一系列分佈式應用中年都會涉及的核心功能,如:
    1.數據發佈/訂閱
    2.負載均衡
    3.命名服務
    4.分佈式協調/通知
    5.集羣管理
    6.Master 選舉
    7.分佈式鎖
    8.分佈式隊列 
  28. 數據發佈/訂閱
    介紹 
    數據發佈/訂閱系統,即所謂的配置中心,顧名思義就是發佈者發佈數據供訂閱者進行數據訂閱。
    目的 
    動態獲取數據(配置信息)
    實現數據(配置信息)的集中式管理和數據的動態更新
    設計模式 
    Push 模式
    Pull 模式 
    數據(配置信息)特性
    1.數據量通常比較小
    2.數據內容在運行時會發生動態更新
    3.集羣中各機器共享,配置一致 
    如:機器列表信息、運行時開關配置、數據庫配置信息等
    基於 Zookeeper 的實現方式 
    數據存儲:將數據(配置信息)存儲到 Zookeeper 上的一個數據節點
    數據獲取:應用在啓動初始化節點從 Zookeeper 數據節點讀取數據,並在該節點上註冊一個數據變更 Watcher
    數據變更:當變更數據時,更新 Zookeeper 對應節點數據,Zookeeper會將數據變更通知發到各客戶端,客戶端接到通知後重新讀取變更後的數據即可。 
  29. 負載均衡
    zk 的命名服務
    命名服務是指通過指定的名字來獲取資源或者服務的地址,利用 zk 創建一個全局的路徑,這個路徑就可以作爲一個名字,指向集羣中的集羣,提供的服務的地址,或者一個遠程的對象等等。 
    分佈式通知和協調
    對於系統調度來說:操作人員發送通知實際是通過控制檯改變某個節點的狀態,然後 zk 將這些變化發送給註冊了這個節點的 watcher 的所有客戶端。對於執行情況彙報:每個工作進程都在某個目錄下創建一個臨時節點。並攜帶工作的進度數據,這樣彙總的進程可以監控目錄子節點的變化獲得工作進度的實時的全局情況。 
    zk 的命名服務(文件系統) 
    命名服務是指通過指定的名字來獲取資源或者服務的地址,利用 zk 創建一個全局的路徑,即是唯一的路徑,這個路徑就可以作爲一個名字,指向集羣中的集羣,提供的服務的地址,或者一個遠程的對象等等。 
    zk 的配置管理(文件系統、通知機制)
    程序分佈式的部署在不同的機器上,將程序的配置信息放在 zk 的 znode 下,當有配置發生改變時,也就是 znode 發生變化時,可以通過改變 zk 中某個目錄節點的內容,利用 watcher 通知給各個客戶端,從而更改配置。
    Zookeeper 集羣管理(文件系統、通知機制)
    所謂集羣管理無在乎兩點:是否有機器退出和加入、選舉 master。
    對於第一點,所有機器約定在父目錄下創建臨時目錄節點,然後監聽父目錄節點的子節點變化消息。一旦有機器掛掉,該機器與 zookeeper 的連接斷開,其所創建的臨時目錄節點被刪除,所有其他機器都收到通知:某個兄弟目錄被刪除,於是,所有人都知道:它上船了。
    新機器加入也是類似,所有機器收到通知:新兄弟目錄加入,highcount 又有了,對於第二點,我們稍微改變一下,所有機器創建臨時順序編號目錄節點,每次選取編號最小的機器作爲 master 就好。
    Zookeeper 分佈式鎖(文件系統、通知機制)
    有了 zookeeper 的一致性文件系統,鎖的問題變得容易。鎖服務可以分爲兩類,一個是保持獨佔,另一個是控制時序。 
    對於第一類,我們將 zookeeper 上的一個 znode 看作是一把鎖,通過 createznode的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那個客戶端也即擁有了這把鎖。用完刪除掉自己創建的 distribute_lock 節點就釋放出鎖。 
    對於第二類, /distribute_lock 已經預先存在,所有客戶端在它下面創建臨時順序編號目錄節點,和選 master 一樣,編號最小的獲得鎖,用完刪除,依次方便。
    Zookeeper 隊列管理(文件系統、通知機制)
    兩種類型的隊列:
    1、同步隊列,當一個隊列的成員都聚齊時,這個隊列纔可用,否則一直等待所有成員到達。 
    2、隊列按照 FIFO 方式進行入隊和出隊操作。
    第一類,在約定目錄下創建臨時目錄節點,監聽節點數目是否是我們要求的數目。 
    第二類,和分佈式鎖服務中的控制時序場景基本原理一致,入列有編號,出列按編號。在特定的目錄下創建 PERSISTENT_SEQUENTIAL 節點,創建成功時Watcher 通知等待的隊列,隊列刪除序列號最小的節點用以消費。此場景下Zookeeper 的 znode 用於消息存儲,znode 存儲的數據就是消息隊列中的消息內容,SEQUENTIAL 序列號就是消息的編號,按序取出即可。由於創建的節點是持久化的,所以不必擔心隊列消息的丟失問題。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章