文章目錄
- Question1:簡要介紹一下Zookeeper架構?
- Answer1:
- Question2:談一談對 ZAB協議 的認識?
- Answer2:
- 第一,事務編號Zxid(事務請求 計數器 + epoch)
- 第二,epoch
- 第三,ZAB協議兩種模式
- 第四,ZAB協議四個階段(整個選主過程只與followers和leader有關,observer沒有選舉權)
- 第五,ZAB協議的JAVA 實現(FLE-發現階段和同步合併爲Recovery Phase(恢復階段))
- Question3:詳細介紹一下Zookeeper集羣的整個投票流程?
- Answer3:
- Question4:介紹一下Zookeeper工作原理(或談一談原子廣播)?
- Answer4:
- Question5:介紹一下Znode目錄節點
- Answer5:
面向面試的博客,以問答式Q/A方式呈現。
Question1:簡要介紹一下Zookeeper架構?
Answer1:
Zookeeper 直譯爲動物園管理員,是一個集羣管理工具,一般用於大數據集羣管理,也可以管理其他集羣,如Solr索引庫集羣。
Zookeeper 是一個分佈式協調服務,可用於服務發現,分佈式鎖,分佈式領導選舉,配置管理等。Zookeeper 提供了一個類似於 Linux 文件系統的樹形結構(可認爲是輕量級的內存文件系統,但只適合存少量信息,完全不適合存儲大量文件或者大文件),同時提供了對於每個節點的監控與通知機制。
Zookeeper 集羣是一個基於主從複製的高可用集羣,其架構如圖所示:
每個服務器承擔如下三種角色中的一種:Leader Follower Observer。
Leader:
1、維持心跳:一個 Zookeeper 集羣同一時間只會有一個實際工作的 Leader,它會發起並維護與各 Follwer 及 Observer 間的心跳(就是上圖中的ping 和 ack 交互)。
2、寫操作過半數寫入成功才提交:所有的寫操作必須要通過 Leader 完成再由 Leader 將寫操作廣播給其它服務器。只要有超過半數節點(不包括 observer 節點)寫入成功,該寫請求就會被提交(類 2PC 協議)。
Follower:
1、維持心跳:一個 Zookeeper 集羣可能同時存在多個 Follower,它會響應 Leader 的心跳。
2、讀請求自己處理,寫請求轉發給Leader:Follower 可直接處理並返回客戶端的讀請求,同時會將寫請求轉發給 Leader 處理。
3、投票選舉Leader:負責在 Leader 處理寫請求時對請求進行投票。
Observer:
1、維持心跳:一個 Zookeeper 集羣可能同時存在多個 Observer,它會響應 Leader 的心跳。
2、讀請求自己處理,寫請求轉發給Leader:Observer 可直接處理並返回客戶端的讀請求,同時會將寫請求轉發給 Leader 處理。
3、無投票權:不負責在 Leader 處理寫請求時對請求進行投票。
角色與 Follower 類似,但是無投票權。Zookeeper 需保證高可用和強一致性,爲了支持更多的客戶端,需要增加更多 Server;Server 增多,投票階段延遲增大,影響性能;引入 Observer,Observer 不參與投票; Observers 接受客戶端的連接,並將寫請求轉發給 leader 節點; 加入更多 Observer 節點,提高伸縮性,同時不影響吞吐率。
Question2:談一談對 ZAB協議 的認識?
Answer2:
第一,事務編號Zxid(事務請求 計數器 + epoch)
在 ZAB ( ZooKeeper Atomic Broadcast , ZooKeeper 原子消息廣播協議) 協議的事務編號 Zxid 設計中,Zxid 是一個 64 位的數字,其中低 32 位是一個簡單的單調遞增的計數器,針對客戶端每一個事務請求,計數器加 1;而高 32 位則代表 Leader 週期 epoch 的編號,每個當選產生一個新的 Leader 服務器,就會從這個 Leader 服務器上取出其本地日誌中最大事務的 ZXID,並從中讀取epoch 值,然後加 1,以此作爲新的 epoch,並將低 32 位從 0 開始計數。
Zxid(Transaction id)類似於 RDBMS 中的事務 ID,用於標識一次更新操作的Proposal(提議)ID。爲了保證順序性,該 zkid 必須單調遞增。
第二,epoch
epoch:可以理解爲當前集羣所處的年代或者週期,每個 leader 就像皇帝,都有自己的年號,所以每次改朝換代,leader 變更之後,都會在前一個年代的基礎上加 1。這樣就算舊的 leader 崩潰恢復之後,也沒有人聽他的了,因爲 follower 只聽從當前年代的 leader 的命令。
第三,ZAB協議兩種模式
Zab協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啓動或者在領導者崩潰後,Zab 就進入了恢復模式,當領導者被選舉出來,且大多數 Server 完成了和 leader 的狀態同步以後,恢復模式就結束了。狀態同步保證了 leader 和 Server 具有相同的系統狀態。
第四,ZAB協議四個階段(整個選主過程只與followers和leader有關,observer沒有選舉權)
第一階段,Leader election (選舉階段 - 選出準 Leader ):節點在一開始都處於選舉階段,只要有一個節點得到超半數節點的票數,它就可以當選準 leader。只有到達 廣播階段(broadcast) 準 leader 纔會成爲真正的 leader。這一階段的目的是就是爲了選出一個準 leader,然後進入下一個階段。
第二階段,Discovery (發現階段 - 接受提議、生成 epoch 、接受 epoch ):在這個階段,followers 跟準 leader 進行通信,同步 followers最近接收的事務提議。這個一階段的主要目的是發現當前大多數節點接收的最新提議,並且準 leader 生成新的 epoch,讓 followers 接受,更新它們的 accepted Epoch。
一個 follower 只會連接一個 leader,如果有一個節點 f 認爲另一個 follower p 是 leader,f 在嘗試連接 p 時會被拒絕,f 被拒絕之後,它(指f)就會進入重新選舉階段,直到連接到它(指f)支持的leader。
第三階段,Synchronization (同步階段 - 同步 follower 副本 ):同步階段主要是利用 leader 前一階段獲得的最新提議歷史,同步集羣中所有的副本。只有當大多數節點都同步完成,準 leader 纔會成爲真正的 leader。follower 只會接收 zxid 比自己的 lastZxid 大的提議。
第四階段,Broadcast(廣播階段 -leader 消息廣播 ):到了這個階段,Zookeeper 集羣才能正式對外提供事務服務,並且 leader 可以進行消息廣播。同時如果有新的節點加入,還需要對新節點進行同步。
ZAB 提交事務並不像 2PC 一樣需要全部 follower 都 ACK,只需要得到超過半數的節點的 ACK 就可以了。
第五,ZAB協議的JAVA 實現(FLE-發現階段和同步合併爲Recovery Phase(恢復階段))
協議的 Java 版本實現跟上面的定義有些不同,選舉階段使用的是 Fast Leader Election(FLE),它包含了選舉的發現職責。因爲 FLE 會選舉擁有最新提議歷史的節點作爲 leader,這樣就省去了發現最新提議的步驟。實際的實現將 發現階段 和 同步合併爲 Recovery Phase(恢復階段)。所以,ZAB 的實現只有三個階段:Fast Leader Election;Recovery Phase;Broadcast Phase。
Question3:詳細介紹一下Zookeeper集羣的整個投票流程?
Answer3:
每個 sever 首先給自己投票,然後用自己的選票和其他 sever 選票對比,權重大的勝出,使用權重較大的更新自身選票箱。具體選舉過程如下:
- 每個 Server 啓動以後都詢問其它的 Server 它要投票給誰。對於其他 server 的詢問,server 每次根據自己的狀態都回復自己推薦的 leader 的 id 和上一次處理事務的 zxid(系統啓動時每個 server 都會推薦自己)。
- 收到所有 Server 回覆以後,就計算出 zxid 最大的那個 Server,並將這個 Server 相關信息設置成下一次要投票的 Server。
- 計算這過程中獲得票數最多的的 server 爲獲勝者,如果獲勝者的票數超過半數,則改server 被選爲 leader。否則,繼續這個過程,直到 leader 被選舉出來。
- leader 就會開始等待 server 連接。
- Follower 連接 leader,將最大的 zxid 發送給 leader。
- Leader 根據 follower 的 zxid 確定同步點,至此選舉階段完成。
- 選舉階段完成 Leader 同步後通知 follower 已經成爲 uptodate 狀態。
- Follower 收到 uptodate 消息後,又可以重新接受 client 的請求進行服務了。
舉例:目前有 5 臺服務器,每臺服務器均沒有數據,它們的編號分別是 1,2,3,4,5,按編號依次啓動,它們的選舉過程如下:
- 服務器 1 啓動,給自己投票,然後發投票信息,由於其它機器還沒有啓動所以它收不到反饋信息,服務器 1 的狀態一直屬於 Looking。
- 服務器 2 啓動,給自己投票,同時與之前啓動的服務器 1 交換結果,由於服務器 2 的編號大所以服務器 2 勝出,但此時投票數沒有大於半數,所以兩個服務器的狀態依然是LOOKING。
- 服務器 3 啓動,給自己投票,同時與之前啓動的服務器 1,2 交換信息,由於服務器 3 的編號最大所以服務器 3 勝出,此時投票數正好大於半數,所以服務器 3 成爲領導者,服務器1,2 成爲小弟。
- 服務器 4 啓動,給自己投票,同時與之前啓動的服務器 1,2,3 交換信息,儘管服務器 4 的編號大,但之前服務器 3 已經勝出,所以服務器 4 只能成爲小弟。
- 服務器 5 啓動,後面的邏輯同服務器 4 成爲小弟。
Question4:介紹一下Zookeeper工作原理(或談一談原子廣播)?
Answer4:
Zookeeper整個工作流程步驟如下:
步驟一:Zookeeper 的核心是原子廣播,這個機制保證了各個 server 之間的同步。實現這個機制的協議叫做 Zab 協議。Zab 協議有兩種模式,它們分別是恢復模式和廣播模式。
步驟二:當服務啓動或者在領導者崩潰後,Zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 的完成了和 leader 的狀態同步以後,恢復模式就結束了。
步驟三:狀態同步保證了 leader 和 server 具有相同的系統狀態。
步驟四:一旦 leader 已經和多數的 follower 進行了狀態同步後,他就可以開始廣播消息了,即進入廣播狀態。這時候當一個 server 加入 zookeeper 服務中,它會在恢復模式下啓動,發現 leader,並和 leader 進行狀態同步。待到同步結束,它也參與消息廣播。Zookeeper服務一直維持在 Broadcast 狀態,直到 leader 崩潰了或者 leader 失去了大部分的followers 支持。
步驟五:廣播模式需要保證 proposal 被按順序處理,因此 zk 採用了遞增的事務 id 號(zxid)來保證。所有的提議(proposal)都在被提出的時候加上了 zxid。
步驟六:實現中 zxid 是一個 64 爲的數字,它高 32 位是 epoch 用來標識 leader 關係是否改變,每次一個 leader 被選出來,它都會有一個新的 epoch。低 32 位是個遞增計數。
步驟七:當 leader 崩潰或者 leader 失去大多數的 follower,這時候 zk 進入恢復模式,恢復模式需要重新選舉出一個新的 leader,讓所有的 server 都恢復到一個正確的狀態。
Question5:介紹一下Znode目錄節點
Answer5:
Znode有四種形式的目錄節點,如下:
- PERSISTENT:持久的節點。
- EPHEMERAL:暫時的節點。
- PERSISTENT_SEQUENTIAL:持久化順序編號目錄節點。
- EPHEMERAL_SEQUENTIAL:暫時化順序編號目錄節點。