摘要:作為整個集群的主節點,負責響應所有對狀態變更的請求。選舉是最重要的技術之一,也是保障分布式數據一致性的關鍵所在。這是由于半數以上投票通過決定的。另外需要注意的是,和構成集群的法定人數,也就是說,只有他們才參與新的選舉響應的提議。
前言
提到ZooKeeper,相信大家都不會陌生。Dubbo,Kafka,Hadoop等等項目里都能看到它的影子。但是你真的了解 ZooKeeper 嗎?如果面試官讓你給他講講 ZooKeeper 是個什么東西,你能回答到什么地步呢?
而且,同樣是ZooKeeper,一線架構師和你的理解又有哪些不同呢?
如何從一個問題及思考方式了解架構的本質?
如何剖析ZooKeeper為什么這么設計?
ZooKeeper到底能干嘛?
如果你已經工作了2-3年,有沒有思考過上述3個問題?
——如果有,你的答案會是?
——如果沒有,為什么?
下面,我主要介紹一下ZooKeeper是什么以及ZooKeeper的作用,前面兩個問題,我會在文末給出答案。
一、ZooKeeper是什么ZooKeeper 是一個分布式的,開放源碼的分布式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個為分布式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。
官網:http://zookeeper.apache.org/
源碼:https://github.com/apache/zookeeper
ZooKeeper翻譯成中文是“動物園管理員”,至于為什么這么翻譯,感興趣的話可以去看看《從Paxos到Zookeeper 》 ,本文中很多的名詞介紹也來自本書。
三、ZooKeeper的特性順序一致性,從同一個客戶端發起的事務請求,最終將會嚴格地按照其發起順序被應用到Zookeeper中去。
原子性,所有事務請求的處理結果在整個集群中所有機器上的應用情況是一致的,即整個集群要么都成功應用了某個事務,要么都沒有應用。
單一視圖,無論客戶端連接的是哪個 Zookeeper 服務器,其看到的服務端數據模型都是一致的。
可靠性,一旦服務端成功地應用了一個事務,并完成對客戶端的響應,那么該事務所引起的服務端狀態變更將會一直被保留,除非有另一個事務對其進行了變更。
實時性,Zookeeper 保證在一定的時間段內,客戶端最終一定能夠從服務端上讀取到最新的數據狀態。
四、ZooKeeper的設計目標簡單的數據結構
Zookeeper 使得分布式程序能夠通過一個共享的樹形結構的名字空間來進行相互協調,即Zookeeper 服務器內存中的數據模型由一系列被稱為ZNode的數據節點組成,Zookeeper 將全量的數據存儲在內存中,以此來提高服務器吞吐、減少延遲的目的。
可以構建集群
Zookeeper 集群通常由一組機器構成,組成 Zookeeper 集群的而每臺機器都會在內存中維護當前服務器狀態,并且每臺機器之間都相互通信。
順序訪問
對于來自客戶端的每個更新請求,Zookeeper 都會分配一個全局唯一的遞增編號,這個編號反映了所有事務操作的先后順序。
高性能
Zookeeper 和Redis一樣全量數據存儲在內存中,100%讀請求壓測QPS 12-13W。
Zookeeper 是一個由多個 server 組成的集群,一個 leader,多個 follower。(這個不同于我們常見的Master/Slave模式)leader 為客戶端服務器提供讀寫服務,除了leader外其他的機器只能提供讀服務。
每個 server 保存一份數據副本全數據一致,分布式讀 follower,寫由 leader 實施更新請求轉發,由 leader 實施更新請求順序進行,來自同一個 client 的更新請求按其發送順序依次執行數據更新原子性,一次數據更新要么成功,要么失敗。全局唯一數據視圖,client 無論連接到哪個 server,數據視圖都是一致的實時性,在一定事件范圍內,client 能讀到最新數據。
Leader:是整個 Zookeeper 集群工作機制中的核心 。Leader 作為整個 ZooKeeper 集群的主節點,負責響應所有對 ZooKeeper 狀態變更的請求。
主要工作:
事務請求的唯一調度和處理,保障集群處理事務的順序性。
集群內各服務器的調度者。
Leader 選舉是 Zookeeper 最重要的技術之一,也是保障分布式數據一致性的關鍵所在。我們以三臺機器為例,在服務器集群初始化階段,當有一臺服務器Server1啟動時候是無法完成選舉的,當第二臺機器 Server2 啟動后兩臺機器能互相通信,每臺機器都試圖找到一個leader,于是便進入了 leader 選舉流程.
每個 server 發出一個投票
投票的最基本元素是(SID-服務器id,ZXID-事物id)
接受來自各個服務器的投票
處理投票
優先檢查 ZXID(數據越新ZXID越大),ZXID比較大的作為leader,ZXID一樣的情況下比較SID
統計投票
這里有個過半的概念,大于集群機器數量的一半,即大于或等于(n/2+1),我們這里的由三臺,大于等于2即為達到“過半”的要求。
這里也有引申到為什么 Zookeeper 集群推薦是單數。
集群數量 | 至少正常運行數量 | 允許掛掉的數量 |
---|---|---|
2 | 2的半數為1,半數以上最少為2 | 0 |
3 | 3的半數為1.5,半數以上最少為2 | 1 |
4 | 4的半數為2,半數以上最少為3 | 1 |
5 | 5的半數為2.5,半數以上最少為3 | 2 |
6 | 6的半數為3,半數以上最少為4 | 2 |
通過以上可以發現,3臺服務器和4臺服務器都最多允許1臺服務器掛掉,5臺服務器和6臺服務器都最多允許2臺服務器掛掉,明顯4臺服務器成本高于3臺服務器成本,6臺服務器成本高于5服務器成本。這是由于半數以上投票通過決定的。
改變服務器狀態
一旦確定了 leader,服務器就會更改自己的狀態,且一半不會再發生變化,比如新機器加入集群、非 leader 掛掉一臺。
Follower?:是 Zookeeper 集群狀態的跟隨者。他的邏輯就比較簡單。除了響應本服務器上的讀請求外,follower 還要處理leader 的提議,并在 leader 提交該提議時在本地也進行提交。另外需要注意的是,leader 和 follower 構成ZooKeeper 集群的法定人數,也就是說,只有他們才參與新 leader的選舉、響應 leader 的提議。
Observer?:服務器充當一個觀察者的角色。如果 ZooKeeper 集群的讀取負載很高,或者客戶端多到跨機房,可以設置一些 observer 服務器,以提高讀取的吞吐量。Observer 和 Follower 比較相似,只有一些小區別:首先 observer 不屬于法定人數,即不參加選舉也不響應提議,也不參與寫操作的“過半寫成功”策略;其次是 observer 不需要將事務持久化到磁盤,一旦 observer 被重啟,需要從 leader 重新同步整個名字空間。
5.3會話(Session)Session 指的是 ZooKeeper 服務器與客戶端會話。在 ZooKeeper 中,一個客戶端連接是指客戶端和服務器之間的一個 TCP 長連接。客戶端啟動的時候,首先會與服務器建立一個 TCP 連接,從第一次連接建立開始,客戶端會話的生命周期也開始了。通過這個連接,客戶端能夠通過心跳檢測與服務器保持有效的會話,也能夠向Zookeeper 服務器發送請求并接受響應,同時還能夠通過該連接接收來自服務器的Watch事件通知。 Session 的 sessionTimeout 值用來設置一個客戶端會話的超時時間。當由于服務器壓力太大、網絡故障或是客戶端主動斷開連接等各種原因導致客戶端連接斷開時,只要在sessionTimeout規定的時間內能夠重新連接上集群中任意一臺服務器,那么之前創建的會話仍然有效。在為客戶端創建會話之前,服務端首先會為每個客戶端都分配一個sessionID。由于 sessionID 是 Zookeeper 會話的一個重要標識,許多與會話相關的運行機制都是基于這個 sessionID 的,因此,無論是哪臺服務器為客戶端分配的 sessionID,都務必保證全局唯一。
5.3.1 會話(Session)在Zookeeper客戶端與服務端成功完成連接創建后,就創建了一個會話,Zookeeper會話在整個運行期間的生命周期中,會在不同的會話狀態中之間進行切換,這些狀態可以分為CONNECTING、CONNECTED、RECONNECTING、RECONNECTED、CLOSE等。
一旦客戶端開始創建Zookeeper對象,那么客戶端狀態就會變成CONNECTING狀態,同時客戶端開始嘗試連接服務端,連接成功后,客戶端狀態變為CONNECTED,通常情況下,由于斷網或其他原因,客戶端與服務端之間會出現斷開情況,一旦碰到這種情況,Zookeeper客戶端會自動進行重連服務,同時客戶端狀態再次變成CONNCTING,直到重新連上服務端后,狀態又變為CONNECTED,在通常情況下,客戶端的狀態總是介于CONNECTING 和CONNECTED 之間。但是,如果出現諸如會話超時、權限檢查或是客戶端主動退出程序等情況,客戶端的狀態就會直接變更為CLOSE狀態。
5.3.2 會話創建Session是Zookeeper中的會話實體,代表了一個客戶端會話,其包含了如下四個屬性
sessionID。會話ID,唯一標識一個會話,每次客戶端創建新的會話時,Zookeeper都會為其分配一個全局唯一的sessionID。
TimeOut。會話超時時間,客戶端在構造Zookeeper實例時,會配置sessionTimeout參數用于指定會話的超時時間,Zookeeper客戶端向服務端發送這個超時時間后,服務端會根據自己的超時時間限制最終確定會話的超時時間。
TickTime。下次會話超時時間點,為了便于Zookeeper對會話實行”分桶策略”管理,同時為了高效低耗地實現會話的超時檢查與清理,Zookeeper會為每個會話標記一個下次會話超時時間點,其值大致等于當前時間加上TimeOut。
isClosing。標記一個會話是否已經被關閉,當服務端檢測到會話已經超時失效時,會將該會話的isClosing標記為”已關閉”,這樣就能確保不再處理來自該會話的心情求了。
Zookeeper為了保證請求會話的全局唯一性,在SessionTracker初始化時,調用initializeNextSession方法生成一個sessionID,之后在Zookeeper運行過程中,會在該sessionID的基礎上為每個會話進行分配,初始化算法如下
public static long initializeNextSession(long id) { long nextSid = 0; // 無符號右移8位使為了避免左移24后,再右移8位出現負數而無法通過高8位確定sid值 nextSid = (System.currentTimeMillis() << 24) >>> 8; nextSid = nextSid | (id << 56); return nextSid; }5.3.3 會話管理 Zookeeper的會話管理主要是通過SessionTracker來負責,其采用了分桶策略(將類似的會話放在同一區塊中進行管理)進行管理,以便Zookeeper對會話進行不同區塊的隔離處理以及同一區塊的統一處理。 5.4 數據節點 Znode
在Zookeeper中,“節點"分為兩類,第一類同樣是指構成集群的機器,我們稱之為機器節點;第二類則是指數據模型中的數據單元,我們稱之為數據節點一一ZNode。
Zookeeper將所有數據存儲在內存中,數據模型是一棵樹(Znode Tree),由斜杠(/)的進行分割的路徑,就是一個Znode,例如/foo/path1。每個上都會保存自己的數據內容,同時還會保存一系列屬性信息。
在Zookeeper中,node可以分為持久節點和臨時節點和順序節點三大類。
可以通過組合生成如下四種類型節點?
1. PERSISTENT
持久節點,節點創建后便一直存在于Zookeeper服務器上,直到有刪除操作來主動清楚該節點。
2. PERSISTENT_SEQUENTIAL
持久順序節點,相比持久節點,其新增了順序特性,每個父節點都會為它的第一級子節點維護一份順序,用于記錄每個子節點創建的先后順序。在創建節點時,會自動添加一個數字后綴,作為新的節點名,該數字后綴的上限是整形的最大值。
3.EPEMERAL
臨時節點,臨時節點的生命周期與客戶端會話綁定,客戶端失效,節點會被自動清理。同時,Zookeeper規定不能基于臨時節點來創建子節點,即臨時節點只能作為葉子節點。
4.EPEMERAL_SEQUENTIAL
臨時順序節點,在臨時節點的基礎添加了順序特性。
每個數據節點都具有三種類型的版本信息,對數據節點的任何更新操作都會引起版本號的變化。
version– 當前數據節點數據內容的版本號
cversion– 當前數據子節點的版本號
aversion– 當前數據節點ACL變更版本號
上述各版本號都是表示修改次數,如version為1表示對數據節點的內容變更了一次。即使前后兩次變更并沒有改變數據內容,version的值仍然會改變。version可以用于寫入驗證,類似于CAS。
5.6watcher事件監聽器ZooKeeper允許用戶在指定節點上注冊一些Watcher,當數據節點發生變化的時候,ZooKeeper服務器會把這個變化的通知發送給感興趣的客戶端
ACL是Access Control Lists 的簡寫, ZooKeeper采用ACL策略來進行權限控制,有以下權限:
CREATE:創建子節點的權限
READ:獲取節點數據和子節點列表的權限
WRITE:更新節點數據的權限
DELETE:刪除子節點的權限
ADMIN:設置節點ACL的權限
Paxos算法是基于消息傳遞且具有高度容錯特性的一致性算法,是目前公認的解決分布式一致性問題最有效的算法之一。(其他算法有二階段提交、三階段提交等)
六、ZooKeeper 可以做什么?分布式服務注冊與訂閱
在分布式環境中,為了保證高可用性,通常同一個應用或同一個服務的提供方都會部署多份,達到對等服務。而消費者就須要在這些對等的服務器中選擇一個來執行相關的業務邏輯,比較典型的服務注冊與訂閱,代表:dubbo。
分布式配置中心
發布與訂閱模型,即所謂的配置中心,顧名思義就是發布者將數據發布到ZK節點上,供訂閱者獲取數據,實現配置信息的集中式管理和動態更新。代表:百度的disconf。
github:https://github.com/knightliao/disconf
命名服務
在分布式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源或服務的地址,提供者等信息。被命名的實體通常可以是集群中的機器,提供的服務地址,進程對象等等——這些我們都可以統稱他們為名字(Name)。其中較為常見的就是一些分布式服務框架中的服務地址列表。通過調用ZK提供的創建節點的API,能夠很容易創建一個全局唯一的path,這個path就可以作為一個名稱。
分布式鎖
分布式鎖,這個主要得益于ZooKeeper為我們保證了數據的強一致性。鎖服務可以分為兩類,一個是保持獨占,另一個是控制時序。
所謂保持獨占,就是所有試圖來獲取這個鎖的客戶端,最終只有一個可以成功獲得這把鎖。通常的做法是把zk上的一個znode看作是一把鎖,通過create znode的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那個客戶端也即擁有了這把鎖。
控制時序,就是所有視圖來獲取這個鎖的客戶端,最終都是會被安排執行,只是有個全局時序了。做法和上面基本類似,只是這里 /distribute_lock 已絆預先存在,客戶端在它下面創建臨時有序節點(這個可以通過節點的屬性控制:CreateMode.EPHEMERAL_SEQUENTIAL來指定)。Zk的父節點(/distribute_lock)維持一份sequence,保證子節點創建的時序性,從而也形成了每個客戶端的全局時序
Master選舉
負載均衡
《從Paxos到Zookeeper 》
《ZooKeeper深入淺出 》
原文鏈接:https://www.jianshu.com/p/d5e...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/11922.html
摘要:作為整個集群的主節點,負責響應所有對狀態變更的請求。選舉是最重要的技術之一,也是保障分布式數據一致性的關鍵所在。這是由于半數以上投票通過決定的。另外需要注意的是,和構成集群的法定人數,也就是說,只有他們才參與新的選舉響應的提議。 showImg(https://segmentfault.com/img/remote/1460000016733126); 前言 提到ZooKeeper,相...
摘要:一般來說,阿里的面試會有兩輪的技術電面,分別交叉檢驗你的技術基礎。但從知識體系的角度來看,阿里面試對于知識的考核可以分為三個層次對于基礎知識的考核對于項目經驗的考核對于項目深度的考核。 最近去阿里的菜鳥國際做了一次面試交流,發現大公司對于面試者的知識結構考核非常嚴謹,可以作為我們日常工作學習的指導。雖然很多人說面試問到的東西在實際工作中很少用到,甚至有「面試造火箭,工作擰螺絲」的說法。...
摘要:導讀閱讀本文需要有足夠的時間,筆者會由淺到深帶你一步一步了解一個資深架構師所要掌握的各類知識點,你也可以按照文章中所列的知識體系對比自身,對自己進行查漏補缺,覺得本文對你有幫助的話,可以點贊關注一下。目錄一基礎篇二進階篇三高級篇四架構篇五擴 導讀:閱讀本文需要有足夠的時間,筆者會由淺到深帶你一步一步了解一個資深架構師所要掌握的各類知識點,你也可以按照文章中所列的知識體系對比自身,對自己...
摘要:正文本文是看到阿里巴巴系統架構師黃勇的采訪記錄有感而發,如有侵權,請聯系我。下面就一起來看看阿里架構師的十年架構路。抱著這樣的信心,我加入了易傳媒,擔任系統架構師職位。 showImg(https://segmentfault.com/img/remote/1460000016748965); 前言 做技術的,一定不能放棄技術。在精進技術的同時完善其他方面的能力,十年如一日。不忘初心,...
摘要:實戰高并發程序設計這本書是目前點評推薦比較多的書,其特色是案例小,好實踐代碼有場景,實用。想要學習多線程的朋友,這本書是我大力推薦的,我的個人博客里面二十多篇的多線程博文都是基于此書,并且在這本書的基礎上進行提煉和總結而寫出來的。 學習的最好途徑就是看書,這是我自己學習并且小有了一定的積累之后的第一體會。個人認為看書有兩點好處:showImg(/img/bVr5S5); 1.能出版出...
閱讀 1750·2021-09-28 09:43
閱讀 1111·2021-09-23 11:22
閱讀 2707·2021-09-14 18:05
閱讀 1822·2019-08-30 15:52
閱讀 2811·2019-08-30 10:55
閱讀 2007·2019-08-29 16:58
閱讀 1322·2019-08-29 16:37
閱讀 3030·2019-08-29 16:25