
這樣學習ZooKeeper離大廠所需技能要求還遠嗎,開發者、管理者、維護員等不同角色學習ZooKeeper的關注點不同,本篇則兼顧多方的角度切入并深入了解ZooKeeper,了解其功能、特性、應用場景、叢集部署,逐漸引出分布式理論核心知識點,最後深入到架構原理,引出分布式一緻性協定Paxos算法、Raft協定以及ZooKeeper獨創的Zab協定,如何選主如何寫資料,可謂覆寫到大廠面試方方面面的考點。Apache ZooKeeper是一種用于建構分布式應用的高性能、高度可靠、開源的分布式協調服務,提供如配置資訊維護、命名、分布式同步、組服務等功能,可以實作如分布式共識、組管理、上司選舉和到場協定;同時也是Google的Chubby一個Java語言版的開源實作。ZooKeeper翻譯為中文則為動物園管理者,而衆所周知ZooKeeper是大資料生态下的重要元件,是大資料生态的基石之一,而我們也知道大部分大資料生态下元件是以動物命名并作為其Logo,比如Hive、Hbase、Flink等,是以ZooKeeper命名就更加生動貼切。
概述
**本人部落格網站 **IT小神 www.itxiaoshen.com
定義
Apache ZooKeeper官網 https://zookeeper.apache.org/ 最新版本3.7.0
Apache ZooKeeper是一種用于建構分布式應用的高性能、高度可靠、開源的分布式協調服務,提供如配置資訊維護、命名、分布式同步、組服務等功能,可以實作如分布式共識、組管理、上司選舉和到場協定;同時也是Google的Chubby一個Java語言版的開源實作。
ZooKeeper翻譯為中文則為動物園管理者,而衆所周知ZooKeeper是大資料生态下的重要元件,是大資料生态的基石之一,而我們也知道大部分大資料生态下元件是以動物命名并作為其Logo,比如Hive、Hbase、Flink等,是以ZooKeeper命名就更加生動貼切。
文檔概述
ZooKeeper 3.7.0官方文檔 http://zookeeper.apache.org/doc/r3.7.0/index.html
主要以概覽、開發者、管理者和維護操作員這三塊為主體,我們本篇主要學習ZooKeeper 原理和大廠名企面試相關知識,至于開發實戰應用部分後續再另外闡述。
- 了解功能、特性、應用場景、架構和原理。
- 了解語言的開發API,官網用戶端API支援語言有Java和C;而我們從事Java技術棧的開發人員更多使用的是Apache Curator(Netflix公司開源的一套ZooKeeper的用戶端架構,為開發人員屏蔽底層細節的開發工作如連接配接重連、反複注冊Watcher和NodeExistsException異常,也封裝了一些進階特性如分布式鎖、Cache事件監聽、選舉、分布式Barrier等,可謂是ZooKeeper開發使用的利器)。
- 介紹部署和維護操作的使用文檔、動态配置、Cli指令行界面使用指南、腳本工具使用、監控等
叢集安裝
ZooKeeper官方下載下傳位址 http://zookeeper.apache.org/releases.html
我們下載下傳二進制包即可,官方也同時提供源碼檔案。
#單機版使用比較簡單,下載下傳解壓、執行啟動腳本檔案就完成了。zookeeper重要就是分布式和高可靠性,如果自己都是單點那就說不過去了,索引我們這裡進行叢集部署,準備三台虛拟機,使用xshell批量執行所有視窗的指令,可以提高部署效率,每台虛拟機先安裝jdk環境,這個已準備好,然後建立目錄下載下傳zookeeper的二進制檔案
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz
#解壓檔案
tar -xvf apache-zookeeper-3.7.0-bin.tar.gz
#進入zookeeper根目錄
cd apache-zookeeper-3.7.0-bin/
#建立資料目錄和日志目錄
mkdir data log
#進入配置檔案
cd conf/
#重命名配置檔案
mv zoo_sample.cfg zoo.cfg
#修改配置檔案的内容為如下:
vim zoo.cfg
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
#存放資料檔案
dataDir=/home/commons/apache-zookeeper-3.7.0-bin/data
#存放日志檔案
dataLogDir=/home/commons/apache-zookeeper-3.7.0-bin/log
# the port at which the clients will connect
clientPort=2181
#zookeeper cluster,2888為選舉端口,3888為心跳端口
server.1=192.168.50.34:2888:3888
server.2=192.168.50.35:2888:3888
server.3=192.168.50.36:2888:3888
#在我們配置的dataDir指定的目錄下面,建立一個myid檔案,裡面内容為一個數字,用來辨別目前主機,這個也是zookeeper用來上司選取算法輸入參數之一,conf/zoo.cfg檔案中配置的server.X中X為什麼數字,則myid檔案中就輸入這個數字:分别在三台上執行各自對應myid。
echo "1" >/home/commons/apache-zookeeper-3.7.0-bin/data/myid
echo "2" >/home/commons/apache-zookeeper-3.7.0-bin/data/myid
echo "3" >/home/commons/apache-zookeeper-3.7.0-bin/data/myid
#進入bin檔案夾下執行啟動腳本
./zkServer.sh start
#通過jps或者ps檢視zookeeper程序情況
ps -ef |grep zookeeper
#檢視目前節點的狀态,從下面的結果得出36是叢集的leader,另外兩個節點是follower
./zkServer.sh status
#通過用戶端腳本,可以在任何一個結點上建立到叢集的連接配接進而操作整個ZooKeeper叢集
./zkCli.sh -server 192.168.50.34:2181
#建立目錄
create /itxs "hello zookeeper"
#檢視目錄,當我們連接配接到叢集其他節點如35或36上再次檢視節點的資料也是相同的,也即是zookeeper實作叢集内部的資料同步
get /itxs
還可以使用zookeeper-dev-ZooInspector.jar可視化用戶端工具,搜尋名稱下載下傳即可
#help幫助指令
help
#檢視節點詳細資料
stat /temp
#節點詳細說明
1)czxid-建立節點的事務zxid
每次修改ZooKeeper狀态都會收到一個zxid形式的時間戳,也就是ZooKeeper事務ID。
事務ID是ZooKeeper中所有修改總的次序。每個修改都有唯一的zxid,如果zxid1小于zxid2,那麼zxid1在zxid2之前發生。
2)ctime - znode被建立的毫秒數(從1970年開始)
3)mzxid - znode最後更新的事務zxid
4)mtime - znode最後修改的毫秒數(從1970年開始)
5)pZxid-znode最後更新的子節點zxid
6)cversion - znode子節點變化号,znode子節點修改次數
7)dataversion - znode資料變化号
8)aclVersion - znode通路控制清單的變化号
9)ephemeralOwner- 如果是臨時節點,這個是znode擁有者的session id。如果不是臨時節點則是0。
10)dataLength- znode的資料長度
11)numChildren - znode子節點數量
大廠面試題
分布式基礎理論
ZooKeeper可以說是分布式理論中最典型的中間件教科書,為了更好了解分布式領域技術,我們需要先了解CAP、BASE這兩個分布式基礎理論,也是高頻出現在大廠或名企的面試中特别是大中型的網際網路企業。
- CAP理論
- 一緻性(Consistency):資料在多個副本之間是否能夠保持一緻的特性。(當一個系統在一緻狀态下更新後,應保持系統中所有資料仍處于一緻的狀态)
- 可用性(Availability):系統提供的服務必須一直處于可用狀态,對每一個操作的請求必須在有限時間内傳回結果。好的可用性主要是指系統能夠很好的為使用者服務,不出現使用者操作失敗或者通路逾時等使用者體驗不好的情況
- 分區容錯性(Tolerance of network Partition):分布式系統在遇到網絡分區故障時,仍然需要保證對外提供一緻性和可用性的服務,除非整個網絡都發生故障;比如節點1和節點3出現故障,但是依然能夠很好地對外提供服務。
- CAP理論是指在一個分布式系統中最多隻能同時滿足一緻性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項
Apache ZooKeeper原理剖析及分布式理論名企高頻面試v3.7.0 - 對于分布式系統來說,P(分區容忍性)是基本要求必須要保證的,否則就失去了價值,是以剩下要麼CP組合,要麼是AP組合。是以設計分布式資料系統,就是在一緻性和可用性之間取一個平衡,對于大多數場景并不需要強一緻性,是以犧牲一緻性而換取高可用性,這個也是目前多數分布式資料庫産品的方向。但這裡很多人不要産生了誤區,犧牲一緻性并不是不要一緻性,而是在可用性前提下盡可能提高資料一緻性,而資料一緻性從強到弱可以分為強一緻性、最終一緻性、弱一緻性。
- 強一緻性
- 對于關系型資料庫,要求更新過的資料能被後續的通路都能看到,這是強一緻性。比如小林更新values0到values1,那麼小李讀取值時也應該是values1。
- 弱一緻性
- 如果能容忍後續的部分或者全部通路不到,則是弱一緻性。比如小林更新values0到values1,可以容忍那麼小李讀取值時是values0。
- 最終一緻性
- 如果經過一段時間後要求能通路到更新後的資料,則是最終一緻性。比如小林更新values0到values1,可以使得小李在一段時間之後讀取值時是values1。
- 強一緻性
- BASE理論
- BASE包含 Basically Available(基本可用)、Soft state(軟狀态)和 Eventually consistent (最終一緻性)這三個短語的縮寫。
Apache ZooKeeper原理剖析及分布式理論名企高頻面試v3.7.0 - BASE理論是是eBay 的架構師 Dan Pritchett 提出,對CAP中AP的一個擴充,通過犧牲強一緻性來獲得可用性,當出現故障允許部分不可用但要保證核心功能可用,允許資料在一段時間内是不一緻的,但最終達到一緻狀态。滿足BASE理論的事務,我們稱之為“柔性事務”。
- Basically Available 基本可用:分布式系統在出現故障時,允許損失部分可用功能,保證核心功能可用。可以展現在時間上的損失和功能上的損失。如部分使用者雙十一淘寶頁面卡頓或降級處理。
- Soft state 軟狀态:由于不要求強一緻性,是以BASE允許系統中存在中間狀态(也叫軟狀态),即系統的不同節點的資料副本之間的資料同步過程存在延遲,這個狀态不影響系統可用性,如訂單的"支付中"、“資料同步中”等狀态,待資料最終一緻後狀态改為“成功”狀态。
- Eventually consistent 最終一緻性:最終一緻是指經過一段時間後,所有節點資料都将會達到一緻。如訂單的"支付中"狀态,最終會變為“支付成功”或者"支付失敗",使訂單狀态與實際交易結果達成一緻,但需要一定時間的延遲、等待。
ZooKeeper節點有哪些類型?
ZooKeeper支援7種znode類型,千萬不要再回答隻有4種了
- PERSISTENT(持久化目錄節點)
- 用戶端與zookeeper斷開連接配接後,該節點依舊存在,隻要不手動删除該節點,他将永遠存在,預設類型。
- PERSISTENT_SEQUENTIAL(持久化順序目錄節點)
- 用戶端與zookeeper斷開連接配接後,該節點依舊存在,Zookeeper還會給該節點名稱進行順序編号,單調遞增。
- EPHEMERAL(臨時目錄節點)
- 用戶端與zookeeper斷開連接配接後,該節點被删除。
- EPHEMERAL_SEQUENTIAL(臨時順序目錄節點)
- 用戶端與zookeeper斷開連接配接後,該節點被删除,Zookeeper還會給該節點名稱進行順序編号,單調遞增。
- Container (容器節點)
- zookeeper 3.5.3 版本新增的,容器節點主要用來容納位元組點,如果沒有給其建立子節點,容器節點表現和持久化節點一樣,如果給容器節點建立了子節點,後續又把子節點清空,容器節點也會被zookeeper删除。特殊用途對于諸如leader、lock等非常有用,服務端會定期掃描這些節點,當該節點下面沒有子節點時(或其他條件時)服務端會自動删除節點。
- PERSISTENT_WITH_TTL(持久化TTL節點)
- zookeeper的擴充類型,如果znode在給定的TTL内沒有被修改,它将在沒有子節點時被删除。需要額外配置才能啟用,必須在zookeeper的bin/zkService.sh中的啟動zookeeper的java環境中設定環境變量zookeeper.extendedTypesEnabled=true(具體做法在下邊),基本和容器相同,當超過 TTL 時間節點下面都沒有再建立子節點時會被删除,但是當建立子節點會重置該逾時時間。
- PERSISTENT_SEQUENTIAL_WITH_TTL(持久化順序TTL節點)
- 和TTL節點類似,隻是多了順序性,該特性是由父節點維護的一個自增整型數字。
ZooKeeper常見應用場景?
- 命名服務
- 依賴Zookeeper可以生成全局唯一的節點ID,來對分布式系統中的資源進行管理。
- 分布式協調
- 這是Zookeeper的核心使用了,利用Watch的監聽機制,一個系統的某個節點狀态發生改變,另外系統可以得到通知。
- 叢集管理
- 分布式叢集中狀态的監控和管理,使用Zookeeper來存儲。
- 分布式鎖
- 利用Zookeeper建立臨時順序節點的特性。
- 保持獨占:每個znode都可以看作一把鎖,在createZnode的時候,每個用戶端都去建立/distribute_lock,最終建立成功的那個用戶端就擁有了這把鎖,用完之後删除/distribute_lock即可。
- 控制時序:在/distribute_lock下面建立臨時順序節點,編号最小的擁有這把鎖,用完删除。
- 利用Zookeeper建立臨時順序節點的特性。
- 注冊中心
- 擔任服務生産者和服務消費者的注冊中心,服務生産者将自己提供的服務注冊到Zookeeper中心,服務的消費者在進行服務調用的時候先到Zookeeper中查找服務,擷取到服務生産者的詳細資訊之後,再去調用服務生産者的内容與資料。
Apache ZooKeeper原理剖析及分布式理論名企高頻面試v3.7.0
- 擔任服務生産者和服務消費者的注冊中心,服務生産者将自己提供的服務注冊到Zookeeper中心,服務的消費者在進行服務調用的時候先到Zookeeper中查找服務,擷取到服務生産者的詳細資訊之後,再去調用服務生産者的内容與資料。
- 資料釋出訂閱
- 常見的場景是配置中心,釋出者把資料釋出到 ZooKeeper 的一個或一系列的節點上,供訂閱者進行資料訂閱,達到動态擷取資料的目的。采用的是推拉結合的方式:
- 推: 服務端會推給注冊了監控節點的用戶端 Wathcer 事件通知。
- 拉: 用戶端獲得通知後,然後主動到服務端拉取最新的資料。
- 常見的場景是配置中心,釋出者把資料釋出到 ZooKeeper 的一個或一系列的節點上,供訂閱者進行資料訂閱,達到動态擷取資料的目的。采用的是推拉結合的方式:
- 分布式隊列
- 同步隊列:當一個隊列的所有成員都聚集時,這個隊列才可用;隻需要在約定目錄下建立一個Watcher監聽,當達到指定數量時,就觸發Watcher通知機制。
- FIFO隊列:與分布式鎖差不多,入隊時有編号,出隊時按編号依次出隊。
- 負載均衡、選主等
ZooKeeper有哪些核心功能?
ZooKeeper提供檔案系統、通知機制和叢集管理核心功能
- 檔案系統
- zookeeper叢集是有一個叫做命名節點空間的概念,其中節點就是znode,在zookeeper的檔案系統中有兩種節點,一是資料節點,二是目錄節點,但是隻有資料節點能存放資料。
Apache ZooKeeper原理剖析及分布式理論名企高頻面試v3.7.0 - zookeeper叢集為了維護高吞吐和低延遲的特性,就維護了這樣樹狀的目錄結構,而且資料節點的存儲量不能太大,最多為1M。
- 通知機制
- 當某個client監聽某個節點時,當該節點發生變化時(有可能是增加子節點,或者節點值變了等),zk就會通知監聽該節點的用戶端來處理。
-
- zk本身是一個叢集結構,有一個leader節點,負責寫請求,多個follower負責響應讀請求。并且在leader節點故障時,會自動根據選舉機制從剩下的follower中選出新的leader。
ZooKeeper的資料模型?
在 Zookeeper 中,可以說 Zookeeper 中的所有存儲的資料是由 znode 組成的,節點也稱為 znode,并以 key/value 形式存儲資料。整體結構類似于 linux 檔案系統的模式以樹形結構存儲。其中根路徑以 / 開頭。通過get指令可以擷取如下資訊
說說ZooKeeper的Zab協定?
zookeeper非常核心就是原子廣播保證各個server之間的同步,而實作這個機制就是Zab協定(全稱 Zookeeper Atomic Broadcast),Zab協定是為分布式協調服務Zookeeper專門設計的一種支援崩潰恢複的原子廣播協定;ZAB協定包括兩種基本的模式:崩潰恢複和消息廣播:
- 當整個zookeeper叢集剛剛啟動或者Leader伺服器當機、重新開機或者網絡故障導緻不存在過半的伺服器與Leader伺服器保持正常通信時,所有程序(伺服器)進入崩潰恢複模式,首先選舉産生新的Leader伺服器,然後叢集中Follower伺服器開始與新的Leader伺服器進行資料同步。
- 當叢集中超過半數機器與該Leader伺服器完成資料同步之後,退出恢複模式進入消息廣播模式,Leader伺服器開始接收用戶端的事務請求生成事物提案來進行事務請求處理。
Zab 協定的原理可細分為四個階段:選舉(Leader Election)、發現(Discovery)、同步(Synchronization)和廣播(Broadcast)
- Leader election(選舉階段)
- 節點在一開始都處于選舉階段,隻要有一個節點得到超過半數節點的票數,它就可以當選準 Leader。
- Discovery(發現階段)
- 在這個階段,Followers跟準Leader進行通信,同步Followers最近接收的事務提議。
- Synchronization(同步階段)
- 同步階段主要是利用Leader前一階段獲得的最新提議曆史,同步叢集中所有的副本。同步完成之後準Leader才會成為真正的Leader。
- Broadcast(廣播階段)
- 到了這個階段,Zookeeper叢集才能正式對外提供事務服務,并且Leader 可以進行消息廣播。同時如果有新的節點加入,還需要對新節點進行同步。
說說Zookeeper Watch機制?
用戶端注冊監聽他關心的目錄節點,當目錄節點發生變化(資料改變、被删除、子目錄節點增加删除)時,Zookeeper會通知用戶端。client端會對某個znode建立一個watcher事件,當該znode發生變化時,zk會主動通知watch這個znode的client,然後client根據znode的變化來做出業務上的改變等。首先用戶端會向服務端注冊一個Watcher監聽,當服務端的某些指令觸發了這個Watcher的話,服務端就會向用戶端傳回一個消息通知,用戶端接收到消息之後便可以做出業務上的改變,主要流程如下:
- 用戶端注冊Watcher:用戶端先向Zookeeper服務端成功注冊想要監聽的節點狀态。
- 首先會通路getData()/getChildren()/exist()三個API,傳入Watcher對象。
- 标記請求request,将Watcher封裝成WatcherRegistration對象。
- 再封裝成Packet對象,服務端發送request。
- 接收到服務端的request請求之後,将Watcher注冊到zkWatcherManager中進行管理。
- 将結果傳回給用戶端,注冊成功。
- 服務端觸發Watcher:同時用戶端本地會存儲該監聽器相關的資訊在WatchManager中。
- 首先根據用戶端的請求判斷是否需要注冊Watcher。
- 比如服務端觸發了setData()/delete()/create()方法,會觸發一個叫做NodeDataChanged()的事件。
- 服務端會将觸發的事件類型、節點的路徑封裝成一個叫做WatchedEvent的對象。
- 再向zkWatcherManager中的WatcherTable中根據節點路徑查找。若找不到,說明用戶端沒有注冊過Watche,若找到,将Watcher從WatcherTable中删除(說明Watcher監聽是一次性的)。
- 調用process方法觸發Watcher,主要是通過Servercnxn的TCP連接配接來通知用戶端。
- 用戶端回調Watcher:當Zookeeper服務端監聽的資料狀态發生變化時,Zookeeper就會主動通知發送相應事件資訊給相關會話用戶端,從WatherManager中取出對應Wather對象執行回調邏輯。
- 用戶端有個SendThread來接收Watcher通知的線程,接收的通知之後會交由EventThread線程處理。
- 用戶端的Watcher監聽也是一次性的,一旦觸發也會被删除。
分布式一緻性算法和共識機制?
Paxos 分布式一緻性算法,強一緻算法,也是一種分布式共識算法,基于提案及核心理念也都是基于多數派原則,大部分也是基于2pc兩階段送出(投票-執行)、3pc三階段提(交投票-預送出-執行)的演變,上面說的Zab與Paxos 具有一些相似之處,而從設計上看ZAB協定和 Raft本質 更是比較類似。Paxos 協定有三大分支包括basic、multi、fast,都是比較難以了解,而Raft協定則是Paxos簡化版或者變種版,很多開源中間件如Nacos、Etcd、Redis哨兵叢集、Consul、Tidb都有Raft協定的實作。Raft原理中主要涉及兩大活動選主和日志複制:
- Raft中有三個角色leader follower candidate,所有節點預設為跟随者,follower可以成為候選者,發起投票,過半就成為leader,之後上司者就開始向其關注者發送條目資訊,這些消息是以心跳逾時指定間隔發送,然後關注者回複每個附加條目資訊,所有更改都通過leader。
- Raft選舉逾時follower等待成為candidate的逾時時間,Term任期編号自增。逾時時鐘做随機,新的leader同步所有資料資訊包括任期,每個節點有一個倒計時器(election timeout),時間随機在150~300ms,當收到選舉請求和leader的心跳重置,發送term編号,每個編号跟随者發送一次不再回複發送,也即是每個任期隻投票一次,重票則重新進行新任期選舉;網絡分區後,任期較低的一邊同步任期高的資料。
ZooKeeper叢集有哪幾種角色?
- leader角色
- 事務請求的唯一排程和處理者,保證叢集事務處理的順序性。
- 叢集内部各服務的排程者。
- 處理所有的事務請求(寫請求),也可以處理讀請求,叢集中隻能有一個Leader,發起投票。
- Follower角色
- 處理用戶端的非事務請求,轉發事務請求給Leader伺服器。
- 參與事務請求Proposal的投票。
- 參與Leader選舉投票。
- 隻處理讀請求,同時作為 Leader的候選節點,即如果Leader當機,Follower節點要參與到新的Leader選舉中,有可能成為新的Leader節點。
- Observer角色
- 不參與任何形式的投票選舉。
- 隻能處理讀請求。
說說Zookeeper 下 Server工作狀态?
Zookeeper伺服器具有四種狀态,分别是LOOKING、FOLLOWING、LEADING、OBSERVING。
- LOOKING:尋找Leader狀态。當伺服器處于該狀态時,它會認為目前叢集中沒有Leader,是以需要進入Leader選舉狀态。
- FOLLOWING:跟随者狀态。表明目前伺服器角色是Follower。
- LEADING:上司者狀态。表明目前伺服器角色是Leader。
- OBSERVING:觀察者狀态。表明目前伺服器角色是Observer。
ZooKeeper是如何保證事務的順序一緻性的?。
- zookeeper采用全局遞增的事務id(zxid)來保證事務的順序一緻性的。
- 所有的提議在被提出的都會攜帶這個zxid,zxid是一個64位的數字;高32位是個epoch(時期,紀元,世,新時代)值,表示leader選舉周期,每進行一次leader選舉,該數字就會+1;後32位用來表示遞增計數,當産生新的提議時,會依據資料庫的兩階段送出過程,首先會像其它節點發送執行請求,如果超過半數以上的機器正确執行,那麼該事務就可以被執行。
Zookeeper的架構與叢集規則?
一個上司者和多個跟随者,超過半數過半機制,每個節點有一份全量資料,更新請求轉發且按順序依次執行,資料更新原子性原則,實時性(用戶端可以讀取最新資料,有序性是zookeeper中非常重要的一個特性,所有的更新都是全局有序的,每個更新都有一個唯一的zxid,而讀請求隻會相對于更新有序,也就是讀請求的傳回結果中會帶有這個zookeeper最新的zxid;Zookeeper是可以叢集複制的,叢集間通過Zab協定(Zookeeper Atomic Broadcast)來保持資料的一緻性。
叢集機器台數規則為2N+1台,N>0,也即是叢集數量建議為基數台,最小叢集為3台,最低生産環境一般建議三個機房,每個機房分别為3、2、2。由于設計和實作Zookeeper叢集也不會出現腦裂問題(當出現網絡分區割斷後分布式現象問題)。
- 首先我們知道zookeeper選舉的規則可用節點數量 > 總節點數量/2,叢集中隻要有過半的機器是正常工作的,那麼整個叢集對外就是可用的。
- 比如标記一個寫是否成功是要在超過一半節點發送寫請求成功時才認為有效。同樣,Zookeeper選擇上司者節點也是在超過一半節點同意時才有效。最後,Zookeeper是否正常是要根據是否超過一半的節點正常才算正常。
- 2n和2n-1的容忍度是一樣的,都是n-1,是以不需要增加一個不必要的zookeeper節點。
- zookeeper的選舉政策也是需要半數以上的節點同意才能當選leader,如果是偶數節點可能導緻票數相同的情況。
Zookeeper如何選舉新的leader?
當Zookeeper叢集在啟動時,或者當leader節點出現網絡中斷、崩潰等情況時,Zookeeper就會進入恢複模式并選舉産生新的 Leader。
- SID: ServerID,用來唯一辨別一台Zookeeper叢集中的機器,全局唯一,serverid也即是myid,在配置檔案中指定。
- ZXID:事務ID,用來唯一辨別一次伺服器狀态的變更,在同一時刻中叢集内部每一台機器的ZXID未必完全一緻。
大體過程:Leader收到消息請求先生成全局自增zxid,然後為每個follower建立FIFO隊列保證有序,将消息作為提案發給所有follower, follower收到提案先寫磁盤然後回複ack給leader,當leader收到半數以上follower的ack後向follower發送commit請求,同時本地執行存儲和業務響應結果,follower收到後commit送出更新記憶體,執行投票不需要觀察者的ack但觀察者必須同步leader資料。
- 第一步:每個Server發出一個投票提議,并且先投自己。
- 第二步:接收來自各個伺服器的投票,節點進行投票。
- 第三步:PK選票并更新選票(pk進行改票,集合zxid,serverid根據資料最近原則),存記憶體、磁盤。
- 第四步:統計所有投票,判斷是否有過半機器接收到相同的投票資訊;核心是集合2pc兩階段送出和過半機制,并通過原子廣播保證資料同步。
- 第五步:改變伺服器狀态,選主完成并且有一半節點和leadder資料同步完成退出恢複模式,一旦确定Leader,每個伺服器更新自己的狀态。
說說Zookeeper寫資料流程?
- Client向Zookeeper的Server1上寫資料,發送一個寫請求。
- 如果Server1不是Leader,那麼Server1會把接收到的請求進一步轉發給Leader,因為每個Zookeeper叢集裡面有一個是Leader。
- Leader會将寫請求廣播給各個Server,各個Server寫成功後會通知Leader。
- 當Leader收到大多數Server資料寫成功了,就說明資料寫成功了.如果這裡有五個節點的話,隻要有三個節點資料寫成功了.那麼就認為資料寫成功了。
- 寫成功以後,Leader就會告訴Server1資料寫成功了。
- Server1會進一步通知Client資料寫成功了,這時就認為整個寫操作成功。
zookeeper資料同步的實作方式?
zookeeper實作資料同步有4種方式,即直接差異化同步、先復原再差異化同步、僅復原同步、全量同步;首先先從learner(follower和observer節點的統稱)節點擷取最後一次操作資料的zxid,再從leader節點中擷取最小的minZxid和最大的maxZxid。
- 如果minZxid<zxid<maxZxid -->采用直接差異化同步
- 如果leader伺服器發現learner伺服器包含了自己不存在的資料,那麼learner伺服器需要復原到leader包含的資料然後在差異化處理 -->先復原再差異化同步
- 如果zxid>maxZxid -->僅復原同步即可
- 如果zxid<minZxid -->全量同步
說說對于zookeeper權限控制清單(ACL)的認識?
zookeeper的權限控制清單包含三個部分
- 授權模式
- IP:授權模式精确到IP粒度。
- Digest:相當于username:password,最常用的一種授權模式。
- World:相當于最特殊的Digest模式world:everyone,最開放的一種授權模式。
- Super:超級使用者。
- 授權對象:被授予權限的使用者例如某個IP
- 權限
- Create:建立。
- Delete:删除。
- Read:讀。
- Write:寫。
- Admin:管理
本篇先到這裡,後續再抽時間針對分布式理論如一緻性算法和分布式幂等設計等作進一步詳細分析