我的學習分佈式專題(二)分佈式服務治理之分佈式協調技術Zookeeper

分佈式協調技術Zookeeper

 2.1 zookeeper集羣安裝部署(略)node

  2.2 zookeeper的基本原理,數據模型redis

  2.3 zookeeper Java api的使用算法

  2.4 zookeeper實際應用場景分析及實戰api

  2.5 zookeeper+dubbo的實戰練習(略)服務器


 

zookeeper的基本原理,數據模型:數據結構

dubbo的服務註冊中心就是基於zookeeper。zookeeper是一種分佈式協調服務(能夠在分佈式系統中共享配置,協調鎖資源,提供命名服務)。異步

zookeeper的目標:封裝好複雜易出錯的關鍵職務,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶;分佈式

zookeeper的特色:oop

  • 最終一致性:爲客戶端展現同一視圖,這是Zookeeper最重要的性能;
  • 可靠性:若是消息被一臺服務器接受,那麼它將被全部的服務器接受;
  • 原子性:更新只能成功或失敗,沒有中間狀態;

zookeeper的數據結構:zookeeper的數據存儲是基於節點,叫Znode;它的引用方式是路徑引用,相似於文件路徑;Znode包含數據,子節點引用,訪問權限等;性能

data:

Znode存儲的數據信息。

ACL:

記錄Znode的訪問權限,即哪些人或哪些IP能夠訪問本節點。

stat:

包含Znode的各類元數據,好比事務ID、版本號、時間戳、大小等等。

child:

當前節點的子節點引用,相似於二叉樹的左孩子右孩子。

  需注意:zookeeper是爲讀多寫少的場景所設計的,Znode並非用來存儲大規模業務數據的,而是用於存儲少許的狀態和配置信息的,每一個節點的數據最大不能超過1MB;

 Znode分爲四種類型:

  1.持久節點:默認的節點類型,建立節點的客戶端和zookeeper斷開鏈接後,該節點一直存在

  2.持久節點順序節點:建立節點時,zookeeper根據建立的時間順序給該節點名稱進行編號

  3.臨時節點:當建立節點的客戶端和zookeeper斷開鏈接後,臨時節點就會被刪除

  4.臨時順序節點:根據建立時間排序的臨時節點

如何實現分佈式一致性爲防止單機掛掉的狀況,Zookeeper維護了一個集羣,如圖所示:

 

zookeeper的集羣是一主多從的結構,在更新數據時,首先更新到主節點(主節點:服務器,不是Znode),再同步到從節點;在讀取數據時,直接讀取任意從節點

爲了保證主從節點的數據一致性,zookeeper採用了ZAB協議,這種協議很是相似於一致性算法Paxos和Raft

  ZAB(Zookeeper Atomic Broadcast):有效解決Zookeeper集羣崩潰恢復,以及主從同步數據的問題; 

ZAB協議是單調一致性,依靠事物ID和版本號,保證了數據的更新和讀取是有序的;

ZAB協議所定義的三種節點狀態:looking(選舉狀態),following(follower節點所處的狀態),leading(leader節點所處的狀態)

  ZXID:節點本地的最新事物編號,包含epoch和計數兩部分;epoch是紀元的意思,至關於Raft算法選主時的term  

  ------假如zookeeper當前的主節點掛掉了,集羣會進行崩潰恢復:

  階段一:

      leader election:選舉階段,此時集羣中的節點處於looking狀態,它們會各自向其餘節點發起投票,投票當中包含本身的服務器ID和最新事物ID(zxid)節點自身會與從其餘節點接收到的zxid作對比,對方大則對方數據更新,則從新發起投票,投票給目前已知最大的zxid所屬節點每次投票後,服務器都會統計投票數,判斷是否有某個節點獲得半數以上的投票,若是存在,該節點變爲leader,狀態變爲leading,其餘則爲following

  階段二:

      Discovery:發現階段,用於從節點中發現最新的zxid和事物日誌,爲防止某些意外狀況產生多個leader。若是出現兩個準leader,都會發出new epoch消息給各個Follower,必然有一個Leader的 epoch並非最新的。Follower發現接收的epoch沒有自身保存的epoch新,就會從新變爲Looking狀態,從新尋找真正的Leader。因此這一階段,leader接收全部來自follower發來的各自最新的epoch值,leader從中選出最大的epoch,基於此值加1,生成新的epoch分發給各個follower,各個follower接收到全新的epoch後,返回ACK給leader,帶上各自最大的zxid和歷史事物日誌。leader選出最大的zxid,並更新自身歷史日誌

  階段三:

      Synchronization:同步階段,把leader剛收集到的最新歷史事物日誌,同步給集羣中全部的follower,只有半數follower同步成功,這個準leader才能稱爲正式leader自此,故障恢復正式完成。

  ------ZAB實現寫入數據,涉及ZAB協議的Broadcast階段:Zookeeper常規狀況下更新數據的時候,由leader廣播到全部follower

    •  客戶端發出寫入數據請求給任意follower
    •  follower把寫入數據請求轉法給leader
    •  leader採用二階段提交方式,先發送propose廣播給follower
    •  follower接到propose消息,寫入日誌成功後,返回ACK消息給leader
    •  leader接到半數以上ACK消息,返回成功給客戶端,而且廣播commit請求給follower

都有哪些應用場景:

    •  分佈式鎖
    •  服務註冊和發現:利用Znode和Watcher,能夠實現分佈式服務的註冊和發現,如dubbo
    •  共享配置和狀態信息:redis的分佈式解決方案codis,利用了zookeeper來存放數據路由表和codis-proxy節點的元信息。同時codis-config發起的命令都會經過zookeeper同步到各個存活的codis-proxy

   此外kafka,hbase,hadoop,也都依靠zookeeper同步節點信息,實現高可用

 

zookeeper Java api的使用

create:建立節點 ;

delete:刪除節點;

exists:判斷節點是否存在;

getData:得到一個節點的數據;

setData:設置一個節點的數據;

getChildren:獲取節點下的全部子節點

這其中,exists,getData,getChildren屬於讀操做。Zookeeper客戶端在請求讀操做的時候,能夠選擇是否設置Watch。

Watch是什麼意思呢?

咱們能夠理解成是註冊在特定Znode上的觸發器。當這個Znode發生改變,也就是調用了create,delete,setData方法的時候,將會觸發Znode上註冊的對應事件,請求Watch的客戶端會接收到異步通知

具體交互過程以下:

1.客戶端調用getData方法,watch參數是true。服務端接到請求,返回節點數據,而且在對應的哈希表裏插入被Watch的Znode路徑,以及Watcher列表。

2.當被Watch的Znode已刪除,服務端會查找哈希表,找到該Znode對應的全部Watcher,異步通知客戶端,而且刪除哈希表中對應的Key-Value。

zookeeper實現分佈式鎖:    (轉自:https://mp.weixin.qq.com/s/u8QDlrDj3Rl1YjY4TyKMCA)

zookeeper分佈式鎖應用了臨時順序節點,支持可重入

獲取鎖首先在zookeeper中建立一個持久節點的ParentLock,當第一個客戶端想要得到鎖時,須要在ParentLock這個節點下建立一個臨時順序節點Lock1

以後,Client1查找ParentLock下面全部的臨時順序節點並排序,判斷本身所建立的節點Lock1是否是順序最靠前的一個。若是是第一個節點,則成功得到鎖。

這時候,若是再有一個客戶端 Client2 前來獲取鎖,則在ParentLock下載再建立一個臨時順序節點Lock2。

Client2查找ParentLock下面全部的臨時順序節點並排序,判斷本身所建立的節點Lock2是否是順序最靠前的一個,結果發現節點Lock2並非最小的。

因而,Client2向排序僅比它靠前的節點Lock1註冊Watcher,用於監聽Lock1節點是否存在。這意味着Client2搶鎖失敗,進入了等待狀態。

這時候,若是又有一個客戶端Client3前來獲取鎖,則在ParentLock下載再建立一個臨時順序節點Lock3。

Client3查找ParentLock下面全部的臨時順序節點並排序,判斷本身所建立的節點Lock3是否是順序最靠前的一個,結果一樣發現節點Lock3並非最小的。

因而,Client3向排序僅比它靠前的節點Lock2註冊Watcher,用於監聽Lock2節點是否存在。這意味着Client3一樣搶鎖失敗,進入了等待狀態。

這樣一來,Client1獲得了鎖,Client2監聽了Lock1,Client3監聽了Lock2。這偏偏造成了一個等待隊列,很像是Java當中ReentrantLock所依賴的AQS(AbstractQueuedSynchronizer)。

釋放鎖:

1.任務完成,客戶端顯示釋放:當任務完成時,Client1會顯示調用刪除節點Lock1的指令。

2.任務執行過程當中,客戶端崩潰:得到鎖的Client1在任務執行過程當中,若是Duang的一聲崩潰,則會斷開與Zookeeper服務端的連接。根據臨時節點的特性,相關聯的節點Lock1會隨之自動刪除。因爲Client2一直監聽着Lock1的存在狀態,當Lock1節點被刪除,Client2會馬上收到通知。這時候Client2會再次查詢ParentLock下面的全部節點,確認本身建立的節點Lock2是否是目前最小的節點。若是是最小,則Client2瓜熟蒂落得到了鎖。

相關文章
相關標籤/搜索