首頁>技術>

面試的時候,面試官只要看到你簡歷的上寫的有Zookeeper(熟悉、掌握)之類,那你至少要準備接下來的11連問。

NO1:說說zookeeper是什麼?

ZooKeeper是一個分散式的,開放原始碼的分散式應用程式協調服務,是Google的Chubby一個開源的實現(Chubby是不開源的),它是叢集的管理者,監視著叢集中各個節點的狀態根據節點提交的反饋進行下一步合理操作。最終,將簡單易用的介面和效能高效、功能穩定的系統提供給使用者 。

Zookeeper一個最常用的使用場景就是用於擔任服務生產者和服務消費者的註冊中心,服務生產者將自己提供的服務註冊到Zookeeper中心,服務的消費者在進行服務呼叫的時候先到Zookeeper中查詢服務,獲取到服務生產者的詳細資訊之後,再去呼叫服務生產者的內容與資料,簡單示例圖如下:

NO2:瞭解Zookeeper的系統架構嗎?

ZooKeeper 的架構圖中我們需要了解和掌握的主要有:

(1)ZooKeeper分為伺服器端(Server) 和客戶端(Client),客戶端可以連線到整個 ZooKeeper服務的任意伺服器上(除非 leaderServes 引數被顯式設定, leader 不允許接受客戶端連線)。

(2)客戶端使用並維護一個 TCP 連線,透過這個連線傳送請求、接受響應、獲取觀察的事件以及傳送資訊。如果這個 TCP 連線中斷,客戶端將自動嘗試連線到另外的 ZooKeeper伺服器。客戶端第一次連線到 ZooKeeper服務時,可以接受這個連線的 ZooKeeper伺服器會為這個客戶端建立一個會話。當這個客戶端連線到另外的伺服器時,這個會話會被新的伺服器重新建立。

(3)上圖中每一個Server代表一個安裝Zookeeper服務的機器,即是整個提供Zookeeper服務的叢集(或者是由偽叢集組成);

(4)組成ZooKeeper服務的伺服器必須彼此瞭解。它們維護一個記憶體中的狀態影象,以及持久儲存中的事務日誌和快照, 只要大多數伺服器可用,ZooKeeper服務就可用;

(5)ZooKeeper 啟動時,將從例項中選舉一個 leader,Leader 負責處理資料更新等操作,一個更新操作成功的標誌是當且僅當大多數Server在記憶體中成功修改資料。每個Server 在記憶體中儲存了一份資料。

(6)Zookeeper是可以叢集複製的,叢集間透過Zab協議(Zookeeper Atomic Broadcast)來保持資料的一致性;

(7)Zab協議包含兩個階段:leader election階段和Atomic Brodcast階段。

a) 叢集中將選舉出一個leader,其他的機器則稱為follower,所有的寫操作都被傳送給leader,並透過brodcast將所有的更新告訴給follower。b) 當leader崩潰或者leader失去大多數的follower時,需要重新選舉出一個新的leader,讓所有的伺服器都恢復到一個正確的狀態。c) 當leader被選舉出來,且大多數伺服器完成了 和leader的狀態同步後,leadder election 的過程就結束了,就將會進入到Atomic brodcast的過程。d) Atomic Brodcast同步leader和follower之間的資訊,保證leader和follower具有形同的系統狀態。NO3:能說說Zookeeper的工作原理?

Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。

Zab協議有兩種模式,它們 分別是恢復模式(選主)和廣播模式(同步)。

Zab協議 的全稱是 Zookeeper Atomic Broadcast** (Zookeeper原子廣播)。Zookeeper 是透過 Zab 協議來保證分散式事務的最終一致性。Zab協議要求每個 Leader 都要經歷三個階段:發現,同步,廣播。

當服務啟動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和 leader的狀態同步以後,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。

為了保證事務的順序一致性,zookeeper採用了遞增的事務id號(zxid)來標識事務。所有的提議(proposal)都在被提出的時候加 上了zxid。實現中zxid是一個64位的數字,它高32位是epoch用來標識leader關係是否改變,每次一個leader被選出來,它都會有一 個新的epoch,標識當前屬於那個leader的統治時期。第32位用於遞增計數。

epoch:可以理解為皇帝的年號,當新的皇帝leader產生後,將有一個新的epoch年號。

每個Server在工作過程中有三種狀態:

LOOKING:當前Server不知道leader是誰,正在搜尋。LEADING:當前Server即為選舉出來的leader。FOLLOWING:leader已經選舉出來,當前Server與之同步。NO4:Zookeeper為什麼要這麼設計?

ZooKeeper設計的目的是提供高效能、高可用、順序一致性的分散式協調服務、保證資料最終一致性。

高效能(簡單的資料模型)

採用樹形結構組織資料節點;全量資料節點,都儲存在記憶體中;Follower 和 Observer 直接處理非事務請求;

高可用(構建叢集)

半數以上機器存活,服務就能正常執行自動進行 Leader 選舉

順序一致性(事務操作的順序)

透過提議投票方式,保證事務提交的可靠性提議投票方式,只能保證 Client 收到事務提交成功後,半數以上節點能夠看到最新資料NO5:你知道Zookeeper中有哪些角色?

系統模型:

領導者(leader)

Leader伺服器為客戶端提供讀服務和寫服務。負責進行投票的發起和決議,更新系統狀態。

學習者(learner)

跟隨者(follower) Follower伺服器為客戶端提供讀服務,參與Leader選舉過程,參與寫操作“過半寫成功”策略。觀察者(observer) Observer伺服器為客戶端提供讀服務,不參與Leader選舉過程,不參與寫操作“過半寫成功”策略。用於在不影響寫效能的前提下提升叢集的讀效能。

客戶端(client):服務請求發起方。

NO6:你熟悉Zookeeper節點ZNode和相關屬性嗎?

節點有哪些型別?

Znode兩種型別:

Znode有四種形式:

持久化目錄節點(PERSISTENT):客戶端與Zookeeper斷開連線後,該節點依舊存在持久化順序編號目錄節點(PERSISTENT_SEQUENTIAL)客戶端與Zookeeper斷開連線後,該節點依舊存在,只是Zookeeper給該節點名稱進行順序編號:臨時目錄節點(EPHEMERAL)客戶端與Zookeeper斷開連線後,該節點被刪除:臨時順序編號目錄節點(EPHEMERAL_SEQUENTIAL)客戶端與Zookeeper斷開連線後,該節點被刪除,只是Zookeeper給該節點名稱進行順序編號

「注意」:建立ZNode時設定順序標識,ZNode名稱後會附加一個值,順序號是一個單調遞增的計數器,由父節點維護。

節點屬性有哪些

一個znode節點不僅可以儲存資料,還有一些其他特別的屬性。接下來我們建立一個/test節點分析一下它各個屬性的含義。

    [zk: localhost:2181(CONNECTED) 6] get /test    456    cZxid = 0x59ac //    ctime = Mon Mar 30 15:20:08 CST 2020    mZxid = 0x59ad    mtime = Mon Mar 30 15:22:25 CST 2020    pZxid = 0x59ac    cversion = 0    dataVersion = 2    aclVersion = 0    ephemeralOwner = 0x0    dataLength = 3    numChildren = 0  

屬性說明

NO7:請簡述Zookeeper的選主流程

Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。Zab協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啟動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和leader的狀態同步以後,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。leader選舉是保證分散式資料一致性的關鍵。

出現選舉主要是兩種場景:初始化、leader不可用。

當zk叢集中的一臺伺服器出現以下兩種情況之一時,就會開始leader選舉。

(1)伺服器初始化啟動。

(2)伺服器執行期間無法和leader保持連線。

而當一臺機器進入leader選舉流程時,當前叢集也可能處於以下兩種狀態。

(1)叢集中本來就已經存在一個leader。

(2)叢集中確實不存在leader。

首先第一種情況,通常是叢集中某一臺機器啟動比較晚,在它啟動之前,叢集已經正常工作,即已經存在一臺leader伺服器。當該機器試圖去選舉leader時,會被告知當前伺服器的leader資訊,它僅僅需要和leader機器建立連線,並進行狀態同步即可。

重點是leader不可用了,此時的選主制度。

投票資訊中包含兩個最基本的資訊。

sid:即server id,用來標識該機器在叢集中的機器序號。

zxid:即zookeeper事務id號。

ZooKeeper狀態的每一次改變, 都對應著一個遞增的Transaction id,,該id稱為zxid.,由於zxid的遞增性質, 如果zxid1小於zxid2,,那麼zxid1肯定先於zxid2發生。建立任意節點,或者更新任意節點的資料, 或者刪除任意節點,都會導致Zookeeper狀態發生改變,從而導致zxid的值增加。

以(sid,zxid)的形式來標識一次投票資訊。

例如:如果當前伺服器要推舉sid為1,zxid為8的伺服器稱為leader,那麼投票資訊可以表示為(1,8)

叢集中的每臺機器發出自己的投票後,也會接受來自叢集中其他機器的投票。每臺機器都會根據一定的規則,來處理收到的其他機器的投票,以此來決定是否需要變更自己的投票。

規則如下:

(1)初始階段,都會給自己投票。

(2)當接收到來自其他伺服器的投票時,都需要將別人的投票和自己的投票進行pk,規則如下:

優先檢查zxid。zxid比較大的伺服器優先作為leader。如果zxid相同的話,就比較sid,sid比較大的伺服器作為leader。

NO8:有了解過watch機制嗎?

簡單地說:client端會對某個znode 註冊一個watcher事件,當該znode發生變化時,這些client會收到ZooKeeper的通知,然後client可以根據znode變化來做出業務上的改變等。

經典使用場景:zookeeper為dubbo提供服務的註冊與發現,作為註冊中心,但是大家有沒有想過zookeeper為啥能夠實現服務的註冊與發現嗎?

這就不得不說一下zookeeper的靈魂 Watcher(監聽者)。

什麼是watcher?

watcher 是zooKeeper中一個非常核心功能 ,客戶端watcher 可以監控節點的資料變化以及它子節點的變化,一旦這些狀態發生變化,zooKeeper服務端就會通知所有在這個節點上設定過watcher的客戶端 ,從而每個客戶端都很快感知,它所監聽的節點狀態發生變化,而做出對應的邏輯處理。

簡單的介紹了一下watcher ,那麼我們來分析一下,zookeeper是如何實現服務的註冊與發現。zookeeper的服務註冊與發現,主要應用的是zookeeper的znode節點資料模型和watcher機制,大致的流程如下:

服務註冊:服務提供者(Provider)啟動時,會向zookeeper服務端註冊服務資訊,也就是建立一個節點,例如:使用者註冊服務com.xxx.user.register,並在節點上儲存服務的相關資料(如服務提供者的ip地址、埠等)。服務發現:服務消費者(Consumer)啟動時,根據自身配置的依賴服務資訊,向zookeeper服務端獲取註冊的服務資訊並設定watch監聽,獲取到註冊的服務資訊之後,將服務提供者的資訊快取在本地,並進行服務的呼叫。服務通知:一旦服務提供者因某種原因宕機不再提供服務之後,客戶端與zookeeper服務端斷開連線,zookeeper服務端上服務提供者對應服務節點會被刪除(例如:使用者註冊服務com.xxx.user.register),隨後zookeeper服務端會異步向所有消費使用者註冊服務com.xxx.user.register,且設定了watch監聽的服務消費者發出節點被刪除的通知,消費者根據收到的通知拉取最新服務列表,更新本地快取的服務列表。

上邊的過程就是zookeeper可以實現服務註冊與發現的大致原理。

watcher有哪些型別?

znode節點可以設定兩類watch,一種是DataWatches,基於znode節點的資料變更從而觸發 watch 事件,觸發條件getData()、exists()、setData()、 create()。

另一種是Child Watches,基於znode的孩子節點發生變更觸發的watch事件,觸發條件 getChildren()、 create()。

watcher有什麼特性?

watch對節點的監聽事件是一次性的!客戶端在指定的節點設定了監聽watch,一旦該節點資料發生變更通知一次客戶端後,客戶端對該節點的監聽事件就失效了。

如果還要繼續監聽這個節點,就需要我們在客戶端的監聽回撥中,再次對節點的監聽watch事件設定為True。否則客戶端只能接收到一次該節點的變更通知。

NO9:那你說說Zookeeper有哪些應用場景?

資料釋出與訂閱

釋出與訂閱即所謂的配置管理,顧名思義就是將資料釋出到ZooKeeper節點上,供訂閱者動態獲取資料,實現配置資訊的集中式管理和動態更新。例如全域性的配置資訊,地址列表等就非常適合使用。

資料釋出/訂閱的一個常見的場景是配置中心,釋出者把資料釋出到 ZooKeeper 的一個或一系列的節點上,供訂閱者進行資料訂閱,達到動態獲取資料的目的。

配置資訊一般有幾個特點:

資料量小的KV資料內容在執行時會發生動態變化叢集機器共享,配置一致

ZooKeeper 採用的是推拉結合的方式。

推: 服務端會推給註冊了監控節點的客戶端 Wathcer 事件通知答: 客戶端獲得通知後,然後主動到服務端拉取最新的資料

命名服務

作為分散式命名服務,命名服務是指透過指定的名字來獲取資源或者服務的地址,利用ZooKeeper建立一個全域性的路徑,這個路徑就可以作為一個名字,指向叢集中的叢集,提供的服務的地址,或者一個遠端的物件等等。

統一命名服務的命名結構圖如下所示:

1、在分散式環境下,經常需要對應用/服務進行統一命名,便於識別不同服務。

類似於域名與IP之間對應關係,IP不容易記住,而域名容易記住。透過名稱來獲取資源或服務的地址,提供者等資訊。

2、按照層次結構組織服務/應用名稱。

可將服務名稱以及地址資訊寫到ZooKeeper上,客戶端透過ZooKeeper獲取可用服務列表類。

配置管理

程式分散式的部署在不同的機器上,將程式的配置資訊放在ZooKeeper的znode下,當有配置發生改變時,也就是znode發生變化時,可以透過改變zk中某個目錄節點的內容,利用watch通知給各個客戶端 從而更改配置。

ZooKeeper配置管理結構圖如下所示:

1、分散式環境下,配置檔案管理和同步是一個常見問題。

可將配置資訊寫入ZooKeeper上的一個Znode。各個節點監聽這個Znode。一旦Znode中的資料被修改,ZooKeeper將通知各個節點。

叢集管理

所謂叢集管理就是:是否有機器退出和加入、選舉master。

叢集管理主要指叢集監控和叢集控制兩個方面。前者側重於叢集執行時的狀態的收集,後者則是對叢集進行操作與控制。開發和運維中,面對叢集,經常有如下需求:

希望知道叢集中究竟有多少機器在工作對叢集中的每臺機器的執行時狀態進行資料收集對叢集中機器進行上下線的操作

叢集管理結構圖如下所示:

1、分散式環境中,實時掌握每個節點的狀態是必要的,可根據節點實時狀態做出一些調整。

2、可交由ZooKeeper實現。

可將節點資訊寫入ZooKeeper上的一個Znode。監聽這個Znode可獲取它的實時狀態變化。

3、典型應用

Hbase中Master狀態監控與選舉。

利用ZooKeeper的強一致性,能夠保證在分散式高併發情況下節點建立的全域性唯一性,即:同時有多個客戶端請求建立 /currentMaster 節點,最終一定只有一個客戶端請求能夠建立成功

分散式通知與協調

1、分散式環境中,經常存在一個服務需要知道它所管理的子服務的狀態。

a)NameNode需知道各個Datanode的狀態。

b)JobTracker需知道各個TaskTracker的狀態。

2、心跳檢測機制可透過ZooKeeper來實現。

3、資訊推送可由ZooKeeper來實現,ZooKeeper相當於一個釋出/訂閱系統。

分散式鎖

處於不同節點上不同的服務,它們可能需要順序地訪問一些資源,這裡需要一把分散式的鎖。

分散式鎖具有以下特性:寫鎖、讀鎖、時序鎖。

寫鎖:在zk上建立的一個臨時的無編號的節點。由於是無序編號,在建立時不會自動編號,導致只能客戶端有一個客戶端得到鎖,然後進行寫入。

讀鎖:在zk上建立一個臨時的有編號的節點,這樣即使下次有客戶端加入是同時建立相同的節點時,他也會自動編號,也可以獲得鎖物件,然後對其進行讀取。

時序鎖:在zk上建立的一個臨時的有編號的節點根據編號的大小控制鎖。

分散式佇列

分散式佇列分為兩種:

1、當一個佇列的成員都聚齊時,這個佇列才可用,否則一直等待所有成員到達,這種是同步佇列。

a)一個job由多個task組成,只有所有任務完成後,job才執行完成。

b)可為job建立一個/job目錄,然後在該目錄下,為每個完成的task建立一個臨時的Znode,一旦臨時節點數目達到task總數,則表明job執行完成。

2、佇列按照FIFO方式進行入隊和出隊操作,例如實現生產者和消費者模型。

NO10:知道監聽器的原理嗎?建立一個Main()執行緒。在Main()執行緒中建立兩個執行緒,一個負責網路連線通訊(connect),一個負責監聽(listener)。透過connect執行緒將註冊的監聽事件傳送給Zookeeper。將註冊的監聽事件新增到Zookeeper的註冊監聽器列表中。Zookeeper監聽到有資料或路徑發生變化時,把這條訊息傳送給Listener執行緒。Listener執行緒內部呼叫process()方法。NO11:為什麼Zookeeper叢集的數目,一般為奇數個?

首先需要明確zookeeper選舉的規則:leader選舉,要求可用節點數量 > 總節點數量/2。

比如:標記一個寫是否成功是要在超過一半節點發送寫請求成功時才認為有效。同樣,Zookeeper選擇領導者節點也是在超過一半節點同意時才有效。最後,Zookeeper是否正常是要根據是否超過一半的節點正常才算正常。這是基於CAP的一致性原理。

zookeeper有這樣一個特性:叢集中只要有過半的機器是正常工作的,那麼整個叢集對外就是可用的。

也就是說如果有2個zookeeper,那麼只要有1個死了zookeeper就不能用了,因為1沒有過半,所以2個zookeeper的死亡容忍度為0;

同理,要是有3個zookeeper,一個死了,還剩下2個正常的,過半了,所以3個zookeeper的容忍度為1;

同理:

2->0;兩個zookeeper,最多0個zookeeper可以不可用。3->1;三個zookeeper,最多1個zookeeper可以不可用。4->1;四個zookeeper,最多1個zookeeper可以不可用。5->2;五個zookeeper,最多2個zookeeper可以不可用。6->2;兩個zookeeper,最多0個zookeeper可以不可用。

....

會發現一個規律,2n和2n-1的容忍度是一樣的,都是n-1,所以為了更加高效,何必增加那一個不必要的zookeeper呢。

zookeeper的選舉策略也是需要半數以上的節點同意才能當選leader,如果是偶數節點可能導致票數相同的情況。

總結

很多面試官,面試套路基本就是這個,從背景到原理,到架構體系,再到Zookeeper固有特點、最後要求面試者能說出Zookeeper的實際應用場景。

「你多學一樣本事,就少說一句求人的話。」

19
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 如何使用 RestSharp 呼叫 WebAPI 介面