大数据之路Week08_day06 (Zookeeper初识)
讓我們來回顧一下我們在學習Hadoop中的HDFS的時候,肯定見過下面這樣的兩幅圖:
這副圖代表著什么呢?它介紹的是Hadoop集群的高可靠,也就是前面提過的HA,仔細觀察一下這副圖,我們發現有兩個NameNode,只不過一個是活躍的狀態 ,一個是熱備狀態,什么是熱備狀態?比如說在之前的Hadoop集群中,什么可以掛掉(宕機),DataNode可以掛掉一個,因為它有備份,但是我們這里的問題是,假如我們的namenode掛掉了呢??這該怎么辦?
所以,Hadoop的高可靠,就是在這里,它擁有兩個NameNode節點。但是同時只能是一個NameNode節點,一個是正在運行活躍的狀態,一個是熱備狀態的,當一個namenode節點掛掉后,這個熱備的namenode就立刻頂替,完成容災,那這里就有幾個問題了,這個熱備的namenode怎么知道我另一個namenode節點掛掉了呢?又怎么保證熱備的namenode切換過來后,數據保持同步呢?
在這篇博客先介紹Zookeeper并搭建Zookeeper.
先來看一副圖
zookeeper在我的理解中是對namenode進行切換管理的,它通過投票機制來進行確定的是否是需要進行切換。
那什么是Zookeeper呢?它的主要思想又是什么呢?
Zookeeper簡介
Zookeeper是一個高效的分布式協調服務,可以提供配置信息管理、命名、分布式同步、集群管理、數據庫切換等服務。它不適合用來存儲大量信息,可以用來存儲一些配置、發布與訂閱等少量信息。Hadoop、Storm、消息中間件、RPC服務框架、分布式數據庫同步系統,這些都是Zookeeper的應用場景。
Zookeeper集群中節點個數一般為奇數個(>=3),若集群中Master掛掉,剩余節點個數在半數以上時,就可以推舉新的主節點,繼續對外提供服務。
關于ZooKeeper集群服務器數
ZooKeeper 官方確實給出了關于奇數的建議,但絕大部分 ZooKeeper 用戶對于這個建議認識有偏差。一個 ZooKeeper 集群如果要對外提供可用的服務,那么集群中必須要有過半的機器正常工作并且彼此之間能夠正常通信。基于這個特性,如果想搭建一個能夠允許 N 臺機器 down 掉的集群,那么就要部署一個由 2*N+1 臺服務器構成的 ZooKeeper 集群。因此,一個由 3 臺機器構成的 ZooKeeper 集群,能夠在掛掉 1 臺機器后依然正常工作,而對于一個由 5 臺服務器構成的 ZooKeeper 集群,能夠對 2 臺機器掛掉的情況進行容災。注意,如果是一個由6臺服務器構成的 ZooKeeper 集群,同樣只能夠掛掉 2 臺機器,因為如果掛掉 3 臺,剩下的機器就無法實現過半了。
zookeeper有這樣一個特性:
【集群中只要有超過過半的機器是正常工作的,那么整個集群對外就是可用的】
也就是說如果有2個zookeeper,那么只要有1個死了zookeeper就不能用了,因為1沒有過半,所以2個zookeeper的死亡容忍度為0;
同理,要是有3個zookeeper,一個死了,還剩下2個正常的,過半了,所以3個zookeeper的容忍度為1;
同理你多列舉幾個:2->0;3->1;4->1;5->2;6->2會發現一個規律,2n和2n-1的容忍度是一樣的,
都是n-1,所以為了更加高效,何必增加那一個不必要的zookeeper呢。
在官網上是這樣說的:
ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services.
這大概描述了Zookeeper主要可以干哪些事情:配置管理,名字服務,提供分布式同步以及集群管理。那這些服務又到底是什么呢?我們為什么需要這樣的服務?我們又為什么要使用Zookeeper來實現呢,使用Zookeeper有什么優勢?接下來我會挨個介紹這些到底是什么,以及有哪些開源系統中使用了。
客戶端發起事務請求,事務請求的結果在整個Zookeeper集群中所有機器上的應用情況是一致的。不會出現集群中部分機器應用了該事務,而存在另外一部分集群中機器沒有應用該事務的情況。在Zookeeper集群中的任何一臺機器,其看到的服務器的數據模型是一致的。Zookeeper能夠保證客戶端請求的順序,每個請求分配一個全局唯一的遞增編號,用來反映事務操作的先后順序。Zookeeper將全量數據保存在內存中,并直接服務于所有的非事務請求,在以讀操作為主的場景中性能非常突出。
Zookeeper使用的數據結構為樹形結構,根節點為"/"。Zookeeper集群中的節點,根據其身份特性分為leader、follower、observer。leader負責客戶端writer類型的請求;follower負責客戶端reader類型的請求,并參與leader選舉;observer是特殊的follower,可以接收客戶端reader請求,但是不會參與選舉,可以用來擴容系統支撐能力,提高讀取速度。
Zookeeper是一個基于觀察者模式設計的分布式服務管理框架,負責存儲和管理相關數據,接收觀察者的注冊。一旦這些數據的狀態發生變化,zookeeper就負責通知那些已經在zookeeper集群進行注冊并關心這些狀態發生變化的觀察者,以便觀察者執行相關操作。
Zookeeper使用的是ZAB原子消息廣播協議,節點之間的一致性算法為Paxos,能夠保障分布式環境中數據的一致性。分布式場景下高可用是Zookeeper的特性,可以采用第三方客戶端的實現,即Curator框架。
Paxos 算法解決的問題是一個分布式系統如何就某個值(決議)達成一致。一個典型的場景是,在一個分布式數據庫系統中,如果各節點的初始狀態一致,每個節點執行相同的操作序列,那么他們最后能得到一個一致的狀態。為保證每個節點執行相同的命令序列,需要在每一條指令上執行一個“一致性算法”以保證每個節點看到的指令一致。一個通用的一致性算法可以應用在許多場景中,是分布式計算中的重要問題。因此從20世紀80年代起對于一致性算法的研究就沒有停止過。節點通信存在兩種模型:共享內存(Shared memory)和消息傳遞(Messages passing)。Paxos 算法就是一種基于消息傳遞模型的一致性算法。
不僅僅是分布式系統中,凡是多個過程需要達成某種一致的場合都可以使用Paxos 算法。一致性算法可以通過共享內存(需要鎖)或者消息傳遞實現,Paxos 算法采用的是后者。Paxos 算法適用的幾種情況:一臺機器中多個進程/線程達成數據一致;分布式文件系統或者分布式數據庫中多客戶端并發讀寫數據;分布式存儲中多個副本響應讀寫請求的一致性。
Zookeeper——Paxos作為靈魂
那么ZK Server最基礎的東西是什么呢?我想應該是Paxos了。所以本文會介紹Paxos以及它在ZK Server中對應的實現。
先說Paxos,它是一個基于消息傳遞的一致性算法,Leslie Lamport萊斯利·蘭伯特在1990年提出,近幾年被廣泛應用于分布式計算中,Google的Chubby,Apache的Zookeeper都是基于它的理論來實現的,Paxos還被認為是到目前為止唯一的分布式一致性算法,其它的算法都是Paxos的改進或簡化。有個問題要提一下,Paxos有一個前提:沒有拜占庭將軍問題。就是說Paxos只有在一個可信的計算環境中才能成立,這個環境是不會被入侵所破壞的。
Paxos描述了這樣一個場景,有一個叫做Paxos的小島(Island)上面住了一批居民,島上面所有的事情由一些特殊的人決定,他們叫做議員(Senator)。議員的總數(Senator Count)是確定的,不能更改。島上每次環境事務的變更都需要通過一個提議(Proposal),每個提議都有一個編號(PID),這個編號是一直增長的,不能倒退。每個提議都需要超過半數((Senator Count)/2 +1)的議員同意才能生效。每個議員只會同意大于當前編號的提議,包括已生效的和未生效的。如果議員收到小于等于當前編號的提議,他會拒絕,并告知對方:你的提議已經有人提過了。這里的當前編號是每個議員在自己記事本上面記錄的編號,他不斷更新這個編號。整個議會不能保證所有議員記事本上的編號總是相同的。現在議會有一個目標:保證所有的議員對于提議都能達成一致的看法。
好,現在議會開始運作,所有議員一開始記事本上面記錄的編號都是0。有一個議員發了一個提議:將電費設定為1元/度。他首先看了一下記事本,嗯,當前提議編號是0,那么我的這個提議的編號就是1,于是他給所有議員發消息:1號提議,設定電費1元/度。其他議員收到消息以后查了一下記事本,哦,當前提議編號是0,這個提議可接受,于是他記錄下這個提議并回復:我接受你的1號提議,同時他在記事本上記錄:當前提議編號為1。發起提議的議員收到了超過半數的回復,立即給所有人發通知:1號提議生效!收到的議員會修改他的記事本,將1好提議由記錄改成正式的法令,當有人問他電費為多少時,他會查看法令并告訴對方:1元/度。
現在看沖突的解決:假設總共有三個議員S1-S3,S1和S2同時發起了一個提議:1號提議,設定電費。S1想設為1元/度, S2想設為2元/度。結果S3先收到了S1的提議,于是他做了和前面同樣的操作。緊接著他又收到了S2的提議,結果他一查記事本,咦,這個提議的編號小于等于我的當前編號1,于是他拒絕了這個提議:對不起,這個提議先前提過了。于是S2的提議被拒絕,S1正式發布了提議: 1號提議生效。S2向S1或者S3打聽并更新了1號法令的內容,然后他可以選擇繼續發起2號提議。
好,我覺得Paxos的精華就這么多內容。現在讓我們來對號入座,看看在ZK Server里面Paxos是如何得以貫徹實施的。
小島(Island)——ZK Server Cluster
議員(Senator)——ZK Server
提議(Proposal)——ZNode Change(Create/Delete/SetData…)
提議編號(PID)——Zxid(ZooKeeper Transaction Id)
正式法令——所有ZNode及其數據
貌似關鍵的概念都能一一對應上,但是等一下,Paxos島上的議員應該是人人平等的吧,而ZK Server好像有一個Leader的概念。沒錯,其實Leader的概念也應該屬于Paxos范疇的。如果議員人人平等,在某種情況下會由于提議的沖突而產生一個“活鎖”(所謂活鎖我的理解是大家都沒有死,都在動,但是一直解決不了沖突問題)。Paxos的作者Lamport在他的文章”The Part-Time Parliament“中闡述了這個問題并給出了解決方案——在所有議員中設立一個總統,只有總統有權發出提議,如果議員有自己的提議,必須發給總統并由總統來提出。好,我們又多了一個角色:總統。
總統——ZK Server Leader
又一個問題產生了,總統怎么選出來的?oh, my god! It’s a long story. 在淘寶核心系統團隊的Blog上面有一篇文章是介紹如何選出總統的,有興趣的可以去看看:http://rdc.taobao.com/blog/cs/?p=162(親測發現我打不開這個網頁,不知道你們行不行,我發現的一篇博客,寫的還不錯 https://www.cnblogs.com/yuyijq/p/4116365.html 可以去看看)
現在我們假設總統已經選好了,下面看看ZK Server是怎么實施的。
情況一:
屁民甲(Client)到某個議員(ZK Server)那里詢問(Get)某條法令的情況(ZNode的數據),議員毫不猶豫的拿出他的記事本(local storage),查閱法令并告訴他結果,同時聲明:我的數據不一定是最新的。你想要最新的數據?沒問題,等著,等我找總統Sync一下再告訴你。
情況二:
屁民乙(Client)到某個議員(ZK Server)那里要求政府歸還欠他的一萬元錢,議員讓他在辦公室等著,自己將問題反映給了總統,總統詢問所有議員的意見,多數議員表示欠屁民的錢一定要還,于是總統發表聲明,從國庫中拿出一萬元還債,國庫總資產由100萬變成99萬。屁民乙拿到錢回去了(Client函數返回)。
情況三:
總統突然掛了,議員接二連三的發現聯系不上總統,于是各自發表聲明,推選新的總統,總統大選期間政府停業,拒絕屁民的請求。
Zookeeper工作流程-Leader
1 .恢復數據;
2 .維持與Learner的心跳,接收Learner請求并判斷Learner的請求消息類型;
3 .Learner的消息類型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根據不同的消息類型,進行不同的處理。
PING 消息是指Learner的心跳信息;
REQUEST消息是Follower發送的提議信息,包括寫請求及同步請求;
ACK消息是 Follower的對提議的回復,超過半數的Follower通過,則commit該提議;
REVALIDATE消息是用來延長SESSION有效時間。
Zookeeper工作流程-Follower
Follower主要有四個功能:
1.向Leader發送請求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
2.接收Leader消息并進行處理;
3.接收Client的請求,如果為寫請求,發送給Leader進行投票;
4.返回Client結果。
Follower的消息循環處理如下幾種來自Leader的消息:
1 .PING消息: 心跳消息;
2 .PROPOSAL消息:Leader發起的提案,要求Follower投票;
3 .COMMIT消息:服務器端最新一次提案的信息;
4 .UPTODATE消息:表明同步完成;
5 .REVALIDATE消息:根據Leader的REVALIDATE結果,關閉待revalidate的session還是允許其接受消息;
6 .SYNC消息:返回SYNC結果到客戶端,這個消息最初由客戶端發起,用來強制得到最新的更新。
Zookeeper節點數據操作流程
注:
1.在Client向Follwer發出一個寫的請求
2.Follwer把請求發送給Leader
3.Leader接收到以后開始發起投票并通知Follwer進行投票
4.Follwer把投票結果發送給Leader
5.Leader將結果匯總后如果需要寫入,則開始寫入同時把寫入操作通知給Leader,然后commit;
6.Follwer把請求結果返回給Client
Zookeeper設計目的
1.最終一致性:client不論連接到哪個Server,展示給它都是同一個視圖,這是zookeeper最重要的性能。
2.可靠性:具有簡單、健壯、良好的性能,如果消息被到一臺服務器接受,那么它將被所有的服務器接受。
3.實時性:Zookeeper保證客戶端將在一個時間間隔范圍內獲得服務器的更新信息,或者服務器失效的信息。但由于網絡延時等原因,Zookeeper不能保證兩個客戶端能同時得到剛更新的數據,如果需要最新數據,應該在讀數據之前調用sync()接口。
4.等待無關(wait-free):慢的或者失效的client不得干預快速的client的請求,使得每個client都能有效的等待。
5.原子性:更新只能成功或者失敗,沒有中間狀態。
6.順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務器上消息a在消息b前發布,則在所有Server上消息a都將在消息b前被發布;偏序是指如果一個消息b在消息a后被同一個發送者發布,a必將排在b前面。
總結
以上是生活随笔為你收集整理的大数据之路Week08_day06 (Zookeeper初识)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一周学习总结PPT-学会VLOOKUP函
- 下一篇: elk之elasticsearch(二)