ZooKeeper的工作原理

?ZooKeeper是一個分布式的應用程序協調服務

?

2 ZooKeeper的工作原理

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

?

?1ZooKeeper數據模型

類似于一個標準的文件系統具有層次關系的數據結構

每個子目錄項如NameService都被稱作為znode

ZNode根據其本身的特性,可以分為下面兩類

Regular ZNode: 常規型ZNode

Ephemeral ZNode: (?'fem(?)r(?)l)(臨時的)類型的目錄節點不能有子節點目錄。

Zookeeper的客戶端和服務器通信采用長連接方式,每個客戶 端和服務器通過心跳來保持連接,這個連接狀態稱為session,如果znode是臨時節點,這個session失效,znode也就刪除了。(3s/一次,200)

如果Client因為TimeoutZookeeper Server失去連接,client處在CONNECTING狀態,會自動嘗試再去連接Server,如果在session有效期內再次成功連接到某個Server,則回到CONNECTED狀態。

?

2ZooKeeper Watch

?

????Zookeeper從設計模式的角度來看,是一個基于觀察者設計模式設計的。簡單來說就是

?Client可以在某個ZNode上設置一個Watcher,來WatchZNode上的變化。如果該ZNode上有相應的變化,就會觸發這個Watcher,把相應的事件通知給設置WatcherClient。需要注意的是,ZooKeeper中的Watcher是一次性的,即觸發一次就會被取消,如果想繼續Watch的話,需要客戶端重新設置Watcher

?

3、?ZooKeeper特性?

?

???讀、寫(更新)模式

?

??ZooKeeper集群中,讀可以從任意一個ZooKeeper Server寫的請求會先ForwarderLeader,然后由Leader來通過ZooKeeper中的原子廣播協議,將請求廣播給所有的FollowerLeader收到一半以上的寫成功的消息后,就認為該寫成功了,就會將該寫進行持久化,并告訴客戶端寫成功了。

?

???FIFO
對于每一個ZooKeeper客戶端而言,所有的操作都是遵循FIFO順序的,這一特性是由下面兩個基本特性來保證的:一是ZooKeeper ClientServer之間的網絡通信是基于TCPTCP保證了Client/Server之間傳輸包的順序;二是ZooKeeper Server執行客戶端請求也是嚴格按照FIFO順序的。

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

?

?ZooKeeper典型應用場景

  1. 名字服務(NameService)?

每個ZNode都可以由其路徑唯一標識,路徑本身也比較簡潔直觀,另外ZNode上還可以存儲少量數據,這些都是實現統一的NameService的基礎。通過簡單的名字,訪問對應的服務器集群。

?

  1. 配置管理(Configuration Management)?

?

?

?

:分布式互斥鎖?

在傳統的應用程序中,線程、進程的同步,都可以通過操作系統提供的機制來完成。但是在分布式系統中,多個進程之間的同步,操作系統層面就無能為力了。

zookeeper中,并沒有JAVA里一樣有Synchronized或者是ReentrantLock機制來實現鎖機制,但是在zookeeper中,實現起來更簡單:我們可以講將zk的一個數據節點代表一個鎖,當多個客戶端同時調用create()節點創建節點的時候,zookeeper會保證只會有一個客戶端創建成功,那么我們就可以讓這個創建成功的客戶端讓其持有鎖,而其它的客戶端則注冊Watcher監聽當持有鎖的客戶端釋放鎖后,監聽的客戶端就會收到Watcher通知,然后再去試圖獲取鎖,這樣反復即可。

Zookeeper的三種角色:

1.leaderfollower?

?

? ? ? ZooKeeper需要在所有的服務(可以理解為服務器)中選舉出一個Leader,然后讓這個Leader來負責管理集群。此時,集群中的其它服務器則 成為此LeaderFollower。并且,當Leader故障的時候,需要ZooKeeper能夠快速地在Follower中選舉出下一個 Leader。這就是ZooKeeperLeader機制,下面我們將簡單介紹在ZooKeeper中,Leader選舉(Leader Election)是如何實現的。?

此操作實現的核心思想是:首先創建一個EPHEMERAL目錄節點,例如“/election”。然后。每一個ZooKeeper服務器在此目錄 下創建一個SEQUENCE|EPHEMERAL類型的節點,例如“/election/n_”。在SEQUENCE標志下,ZooKeeper將自動地 為每一個ZooKeeper服務器分配一個比前一個分配的序號要大的序號。此時創建節點的ZooKeeper服務器中擁有最小序號編號的服務器將成為 Leader

在實際的操作中,還需要保障:當Leader服務器發生故障的時候,系統能夠快速地選出下一個ZooKeeper服務器作為Leader。一個簡 單的解決方案是,讓所有的follower監視leader所對應的節點。當Leader發生故障時,Leader所對應的臨時節點將會自動地被刪除,此 操作將會觸發所有監視Leader的服務器的watch。這樣這些服務器將會收到Leader故障的消息,并進而進行下一次的Leader選舉操作。但 是,這種操作將會導致從眾效應的發生,尤其當集群中服務器眾多并且帶寬延遲比較大的時候,此種情況更為明顯。

Zookeeper中,為了避免從眾效應的發生,它是這樣來實現的:每一個followerfollower集群中對應的比自己節點序號小一 號的節點(也就是所有序號比自己小的節點中的序號最大的節點)設置一個watch。只有當follower所設置的watch被觸發的時候,它才進行 Leader選舉操作,一般情況下它將成為集群中的下一個Leader。很明顯,此Leader選舉操作的速度是很快的。因為,每一次Leader選舉幾 乎只涉及單個follower的操作

2.Observer

? ? ? observer的行為在大多數情況下與follower完全一致, 但是他們不參加選舉和投票, 而僅僅接受(observing)選舉和投票的結果.

Zookeeper集群,選舉機制

?

?

zookeeper選舉機制

FastLeaderElection算法通過異步的通信方式來收集其它節點的選票,同時在分析選票時又根據投票者的當前狀態來作不同的處理,以加快Leader的選舉進程。????
??? 每個在zookeeper服務器啟動先讀取當前保存在磁盤的數據,zookeeper中的每份數據都有一個對應的id值,這個值是依次遞增的;換言之,越新的數據,對應的ID值就越大。?
??? 在讀取數據完畢之后,每個zookeeper服務器發送自己選舉的leader,這個協議中包含了以下幾部分的數據:?
1)、所選舉leader的id(就是配置文件中寫好的每個服務器的id) ,在初始階段,每臺服務器的這個值都是自己服務器的id,也就是它們都選舉自己為leader。?
2)、服務器最大數據的id,這個值大的服務器,說明存放了更新的數據。?
3)、邏輯時鐘的值,這個值從0開始遞增,每次選舉對應一個值,也就是說:如果在同一次選舉中,那么這個值應該是一致的,邏輯時鐘值越大,說明這一次選舉leader的進程更新。?
4)、本機在當前選舉過程中的狀態,有以下幾種:LOOKING,FOLLOWING,OBSERVING,LEADING?

??? 每臺服務器將自己服務器的以上數據發送到集群中的其他服務器之后,同樣的也需要接收來自其他服務器的數據,它將做以下的處理:?
A、如果所接收數據服務器的狀態還是在選舉階段(LOOKING 狀態),那么首先判斷邏輯時鐘值,又分為以下三種情況:?
a) 如果發送過來的邏輯時鐘大于目前的邏輯時鐘,那么說明這是更新的一次選舉,此時需要更新一下本機的邏輯時鐘值,代碼如下:?

if (n.epoch > logicalclock) { logicalclock = n.epoch; recvset.clear(); if(totalOrderPredicate(n.leader, n.zxid,getInitId(), getInitLastLoggedZxid())) updateProposal(n.leader, n.zxid); else updateProposal(getInitId(),getInitLastLoggedZxid()); sendNotifications();


其中的totalOrderPredicate函數就是根據發送過來的封包中的leader id,數據id來與本機保存的相應數據進行判斷的函數(首先看數據id,數據id大者勝出;其次再判斷leader id,leader id大者勝出),返回true則調用updateProposal函數更新數據。?
b) 發送過來數據的邏輯時鐘小于本機的邏輯時鐘?
說明對方在一個相對較早的選舉進程中,這里只需要將本機的數據廣播出去?
c)?兩邊的邏輯時鐘相同,此時也只是調用totalOrderPredicate函數判斷是否需要更新本機的數據,將最新的選舉結果廣播出去?


B、如果所接收服務器不在選舉狀態,也就是在FOLLOWING或者LEADING狀態?
a) 如果邏輯時鐘相同,將該數據保存到recvset,如果所接收服務器宣稱自己是leader,那么將判斷是不是有半數以上的服務器選舉它,如果是則設置選舉狀態退出選舉過程?
如果邏輯時鐘不相同,那么說明在另一個選舉過程中已經有了選舉結果,于是將該選舉結果加入到outofelection集合中,再根 據outofelection來判斷是否可以結束選舉,如果可以也是保存邏輯時鐘,設置選舉狀態,退出選舉過程?

以一個簡單的例子來說明整個選舉的過程.?
假設有五臺服務器組成的zookeeper集群,它們的id從1-5,同時它們都是最新啟動的,也就是沒有歷史數據,在存放數據量這一點上,都是一樣的.假設這些服務器依序啟動,來看看會發生什么?

1) 服務器1啟動,此時只有它一臺服務器啟動了,它發出去的報沒有任何響應,所以它的選舉狀態一直是LOOKING狀態??
2) 服務器2啟動,它與最開始啟動的服務器1進行通信,互相交換自己的選舉結果,由于兩者都沒有歷史數據,所以id值較大的服務器2勝出,但是由于沒有達到超 過半數以上的服務器都同意選舉它(這個例子中的半數以上是3),所以服務器1,2還是繼續保持LOOKING狀態.??
3) 服務器3啟動,根據前面的理論分析,服務器3成為服務器1,2,3中的老大,而與上面不同的是,此時有三臺服務器選舉了它,所以它成為了這次選舉的leader.??
4) 服務器4啟動,根據前面的分析,理論上服務器4應該是服務器1,2,3,4中最大的,但是由于前面已經有半數以上的服務器選舉了服務器3,所以它只能接收當小弟的命了.??
5) 服務器5啟動,同4一樣,當小弟

?

轉載于:https://www.cnblogs.com/JimBo-Wang/p/6627133.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284135.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284135.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284135.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

memcache的學習路線圖

memcache學習材料//memcache自帶的github 上的 wiki//席劍飛 Memcache(MC)系列 1~8系列評注: memcache系統寫的最深的一博客,建議一讀。http://blog.csdn.net/xifeijian/article/details/21994941//mysql與memcache的使用https://…

[轉]錢嶺:別擔心“35歲危機”,要成為“老專家”

從清華大學到貝爾實驗室,再到中國移動,作為“IT老人”,錢嶺的技術人生幾乎覆蓋了20世紀90年代至今的信息產業革命。2007年開始,錢嶺在中國移動經歷了基礎科研到產品落地,再到團隊孵化;也經歷了云計算從無到…

【GIS前沿】周成虎院士:GIS的大數據時代展望(PPT分享)

本文源自微信公眾號:宋關福GIS筆記。版權歸原作者及刊載媒體所有,如有侵權請立即與我們聯系,我們將及時處理。更多GIS前言技術,請關注《GIS前言》專欄。 GIS的大數據時代展望

DataV:可視化大屏展示神器實戰分享

由于公司年即將發布新的產品,傳統意義上的PPT顯得不太生動化,所以想采用具體化,可視化的數據大屏進行業務數據的事實展示,第一時間想到了來自于阿里云旗下的DataV,廢話不多說,老司機開始發牌照!…

數據庫性能系列之索引(中)

GOOD NIGHT前言上一篇中,我們已經了解到了索引的基本概念和一些用法。那索引為什么會提升查詢的速度,以及索引究竟是怎么工作的呢?也許大家心里還是有一些迷茫,這一切,還要從索引背后的算法說起。GOOD NIGHT概述大家知…

微服務架構的設計原則和核心話題

目錄 一、前言 二、微服務架構的設計原則 1.拆分足夠微 2.輕量級通信 3.單一職責原則 4.領域驅動原則 三、微服務架構的核心話題 1.服務拆分 2.服務注冊與發現 3.負載均衡 4.API網關 5.服務部署與發布 四、總結 一、前言 毫無疑問,微服務架構的設計原…

4.3.2 基于集合的操作

在SQL Server處理select命令時,會在內存中建立一個結構,以返回結果集。這個結構實質上是一個有行和列的二維數組,稱為“游標(cursor)”。“游標”這個詞是“CURrent set of Records(當前記錄集)”的縮寫。它表示從表或…

Golang GOPATH 包

2019獨角獸企業重金招聘Python工程師標準>>> Golang GOPATH & 包的定義 & 包的導入 GOPATH 設置 go 命令依賴一個重要的環境變量:$GOPATH 可以在 .zshrc 配置文件中加上一行這樣的配置, export GOPATH/Users/flyme/mygo Go從1.1版本到…

PPK大疆無人機應用教程

文章目錄 一、新建項目二、導入數據三、解算過程四、結果導出一、新建項目 新建工程,設置項目名稱,保存位置,控制等級,坐標系統(坐標系統選擇高斯克呂格,中央子午線根據實際數據所在位置進行選擇) 二、導入數據 選擇大疆數據,找到對應的文件夾 數據有:圖片,EVENT.b…

Eclipse Add generated serial version ID報錯解決方案

為什么80%的碼農都做不了架構師?>>> 問題: The following problem occurred:Could not find class file.Make sure the file is compilable 解決方案: 1、右鍵項目 -> Java Build Path -> Source 在Sourcd folders on bui…

開啟線程的方式

1、實現Runnable接口 1 package test;2 3 4 5 public class ThreadTest implements Runnable{6 public void tt(){7 Thread t new Thread(this);8 t.start();9 } 10 11 Override 12 public void run() { 13 while(true){ 14 …

C# WPF設備監控軟件(經典)-上篇

01—前言應老東家也是老同學的需求,開發了此設備監控軟件。主要是為了應對測試設備長時間不上傳測試數據未能及時發現的問題,測試數據一般在每臺設備都有個固定的臨時存放目錄,測試數據不更新時,此文件夾便不再更新。需求相對比較…

[轉]微服務的4個設計原則和19個解決方案

目錄 一、微服務架構演進過程 二、微服務架構的好處 三、微服務應用4個設計原則 1.AKF拆分原則 2.前后端分離 3.無狀態服務 4.Restful通信風格 四、微服務架構帶來的問題 五、微服務平臺的19個落地實踐 1.企業IT建設的三大基礎環境 2.微服務應用平臺總體架構 3.微服…

時間處理總結(二)oracle

不斷總結中................. 1.等于land.djsjto_date(2016/7/26,yyyy-MM-dd)2.大于等于land.djsj>to_date(2016/7/26,yyyy-MM-dd)3.小于等于land.djsj<to_date(2016/7/26,yyyy-MM-dd)4.區間land.djsj>to_date(2016/7/26,yyyy-MM-dd) and land.djsj<to_date(2016/7…

【GlobalMapper精品教程】033:影像地圖羽化方式詳解

在Globalmapper中,可以很方便的對影響進行多種羽化值設置。 文章目錄 1. 不要羽化此圖層2. 沿一個或多個邊緣羽化3. 羽化到有效數據的多邊形覆蓋4. 在當前選定的多邊形內羽化5. 裁剪到選定的邊界,而不是羽化6. 在多邊形外部羽化,而不是內部加載配套案例數據包中的data033.ra…

基于WPF重復造輪子,寫一款數據庫文檔管理工具(一)

項目背景公司業務歷史悠久且復雜&#xff0c;數據庫的表更是多而繁雜&#xff0c;每次基于老業務做功能開發都需要去翻以前的表和業務代碼。需要理解舊的表的用途以及包含的字段的含義&#xff0c;表少還好說&#xff0c;但是表一多這就很浪費時間&#xff0c;而且留下來的文檔…

[轉]GitBook使用教程收藏

GitBook使用教程 最簡單的方式就是使用GitBook編輯器&#xff0c;沒有什么難度&#xff0c;后面的教程主要針對命令行的方式 PS&#xff1a;GitBook的book頁面默認沒有download按鈕的 需要到設置中打開&#xff0c;打開后再次publish生效 同步GitHub 更新失敗&#xff0c;無法…

二 面向對象三大特性

一 繼承與派生 一、繼承定義 二、繼承與抽象的關系 三、繼承與重用性 四、派生 五、組合與重用性 六、接口與歸一化設計 七、抽象類 八、繼承實現的原理 九、子類中調用父類的方法 二 多態與多態性 一、多態 二、多態性 三 封裝 一、封裝定義 二、特性(property) 三、封裝與擴展…

CSS3新屬性

邊框&#xff1a; border-radius 用于創建圓角 div { border:2px solid; border-radius:25px; -moz-border-radius:25px; /* Old Firefox */ } box-shadow 用于向方框添加陰影 div { box-shadow: 10px 10px 5px #888888; } border-image 使用圖片來創建邊框 div { border-image…

Android實用筆記——使用Spinner實現下拉列表

2019獨角獸企業重金招聘Python工程師標準>>> 1、編輯activity_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"mat…