1. 程式人生 > >ZOOKEEPER和KAFKA簡介

ZOOKEEPER和KAFKA簡介

中心 概念 ras ice 規模 PE 傳遞 group 客戶端訪問

目錄

KAFKA

1. kafka的特性

2. Kafka的架構組件簡介

3. 重要組件或概念詳解

Topic、Partition、Offset

Producers

Consumers

4. Kafka的一些設計思想和基本概念

5. Kafka核心特性

壓縮

消息可靠性

備份機制

6. Kafka的應用場景

zookeeper

1 zookeeper簡介

2 zookeeper特性

3 Zookeeper的架構及原理

3.1 Zookeeper的基本概念

3.2 Zookeeper的數據模型

3.3 Zookeeper的數據同步

3.4 Zookeeper的leader選舉

4 zookeeper應用場景


KAFKA

Kafka是由LinkedIn開發的一個分布式的、可分區的、可復制的消息系統

1. kafka的特性

(1)高吞吐量、低延遲:kafka每秒可以處理幾十萬條消息,它的延遲最低只有幾毫秒

(2)可擴展性:kafka集群支持熱擴展,增減broker可以做到對消費者、生產者幾乎無感知

(3)持久性、可靠性:消息被持久化到本地磁盤,並且支持數據備份防止數據丟失

(4)容錯性:允許集群中節點失敗(若副本數量為n,則允許n-1個節點失敗)

(5)高並發:支持數千個客戶端同時讀寫

2. Kafka的架構組件簡介

a) Broker:Kafka的一個服務實例就是一個broker

b) Producer:生產消息到topic的一方

c) Consumer:訂閱topic消費消息的一方

d) Consumer group:消費組,一個消費者屬於一個特定的組

e) topic:消息存放的目錄即主題,可以理解為一個邏輯管理單元

f) partition:一個物理概念,一個partition可以理解為linux中的一個目錄,一個topic的消息可以包含一個或多個partition,每個partition可以設置多個副本,partition的多個副本中有一個是leader,負責響應生產者、消費者對partition的讀寫技術分享圖片


3. 重要組件或概念詳解

Topic、Partition、Offset

Kafka中的Message是以topic為基本單位組織的,不同的topic之間是相互獨立的。Topic以partition的形式存放,每個topic可以分成幾個不同的partition(每個topic有幾個partition是在創建topic時指定的)。Producer在生產數據時,會按照一定規則(這個規則是可以自定義的)把消息發布到topic的各個partition中。把消息日誌以Partition的形式存放有多重考慮,第一,方便在集群中擴展,每個Partition可以通過調整以適應它所在的機器,而一個topic又可以有多個Partition組成,因此整個集群就可以適應任意大小的數據了;第二就是可以提高並發,因為可以以Partition為單位讀寫了。

kafka中的數據是持久化的並且能夠容錯的。Kafka允許用戶為每個partition設置副本(Replications)數量,副本數量決定了有幾個broker來存放寫入的數據。如果你的副本數量設置為3,那麽一份數據就會被存放在3臺不同的機器上,那麽就允許有2個機器失敗。一般推薦副本數量至少為2,這樣就可以保證增減、重啟機器時不會影響到數據消費。如果對數據持久化有更高的要求,可以把副本數量設置為3或者更多。但只有一個partition的副本會被選舉成leader作為讀寫用。

關於如何設置partition值需要考慮的因素。一個partition只能被一個消費者消費(一個消費者可以同時消費多個partition),因此,如果設置的partition的數量小於consumer的數量,就會有消費者消費不到數據。所以,推薦partition的數量一定要大於同時運行的consumer的數量。另外一方面,建議partition的數量大於集群broker的數量,這樣leader partition就可以均勻的分布在各個broker中,最終使得集群負載均衡。需要註意的是,kafka需要為每個partition分配一些內存來緩存消息數據,如果partition數量越大,就要為kafka分配更大的heap space。

如下圖所示,創建1個topic包含4個Partition,2 Replication。每個partition放在不同的broker上,同屬一個partition的不同副本也在不同的broker上。

技術分享圖片

每個partition存儲一部分Message。每個Partition中的消息都是有序的,生產的消息被不斷追加到Partition上。如下圖所示

技術分享圖片

Partition中的每條Message由offset來表示它在這個partition中的偏移量,這個offset不是該Message在partition數據文件中的實際存儲位置,而是邏輯上一個值,它唯一確定了partition中的一條Message。因此,可以認為offset是partition中Message的id。partition中的每條Message包含了以下三個屬性:

· offset

· MessageSize

· Data

消費方是是根據offset來順序查找message,如果一個partition下的文件非常大,會影響查找效率。Kafka對partition下的文件進行了分段並建立了索引文件,索引文件和數據文件的名字是一樣的,只是擴展名不一樣,文件名是以數據文件裏面消息的最小offset來命名的如下圖所示。





技術分享圖片



index文件中並沒有為數據文件中的每條Message建立索引,而是采用了稀疏存儲的方式,每隔一定字節的數據建立一條索引。這樣避免了索引文件占用過多的空間,從而可以將索引文件保留在內存中。但缺點是沒有建立索引的Message也不能一次定位到其在數據文件的位置,從而需要做一次順序掃描,但是這次順序掃描的範圍就很小了

Kafka集群會保存所有的消息,不管消息有沒有被消費;我們可以設定消息的過期時間,只有過期的數據才會被自動清除以釋放磁盤空間。比如我們設置消息過期時間為2天,那麽這2天內的所有消息都會被保存到集群中,數據只有超過了兩天才會被清除。

Kafka需要維持的元數據只有一個–消費消息在Partition中的offset值,Consumer每消費一個消息,offset就會加1。其實消息的狀態完全是由Consumer控制的,Consumer可以跟蹤和重設這個offset值,這樣的話Consumer就可以讀取任意位置的消息。

Producers

Producers直接發送消息到broker上的leader partition,不需要經過任何中介一系列的路由轉發。為了實現這個特性,kafka集群中的每個broker都可以響應producer的請求,並返回topic的一些元信息,這些元信息包括哪些機器是存活的,topic的leader partition都在哪,現階段哪些leader partition是可以直接被訪問的。

Producer客戶端自己控制著消息被推送到哪些partition。實現的方式可以是隨機分配、實現一類隨機負載均衡算法,或者指定一些分區算法。Kafka提供了接口供用戶實現自定義的分區,用戶可以為每個消息指定一個partitionKey,通過這個key來實現一些hash分區算法。比如,把userid作為partitionkey的話,相同userid的消息將會被推送到同一個分區。

以Batch的方式推送數據可以極大的提高處理效率,kafka Producer 可以將消息在內存中累計到一定數量後作為一個batch發送請求。Batch的數量大小可以通過Producer的參數控制,參數值可以設置為累計的消息的數量(如500條)、累計的時間間隔(如100ms)或者累計的數據大小(64KB)。通過增加batch的大小,可以減少網絡請求和磁盤IO的次數,當然具體參數設置需要在效率和時效性方面做一個權衡。

Producers可以異步的並行的向kafka發送消息,但是通常producer在發送完消息之後會得到一個future響應,返回的是offset值或者發送過程中遇到的錯誤。這其中有個非常重要的參數“acks”,這個參數決定了producer要求leader partition 收到確認的副本個數,如果acks設置數量為0,表示producer不會等待broker的響應,所以,producer無法知道消息是否發送成功,這樣有可能會導致數據丟失,但同時,acks值為0會得到最大的系統吞吐量。

若acks設置為1,表示producer會在leader partition收到消息時得到broker的一個確認,這樣會有更好的可靠性,因為客戶端會等待直到broker確認收到消息。若設置為-1,producer會在所有備份的partition收到消息時得到broker的確認,這個設置可以得到最高的可靠性保證。

Kafka 消息有一個定長的header和變長的字節數組組成。因為kafka消息支持字節數組,也就使得kafka可以支持任何用戶自定義的序列號格式或者其它已有的格式如Apache Avro、protobuf等。Kafka沒有限定單個消息的大小,但我們推薦消息大小不要超過1MB,通常一般消息大小都在1~10kB之前。

Consumers

Kafka提供了兩套consumer api,分為high-level api和sample-api。Sample-api 是一個底層的API,它維持了一個和單一broker的連接,並且這個API是完全無狀態的,每次請求都需要指定offset值,因此,這套API也是最靈活的。

在kafka中,當前讀到消息的offset值是由consumer來維護的,因此,consumer可以自己決定如何讀取kafka中的數據。比如,consumer可以通過重設offset值來重新消費已消費過的數據。不管有沒有被消費,kafka會保存數據一段時間,這個時間周期是可配置的,只有到了過期時間,kafka才會刪除這些數據。

High-level API封裝了對集群中一系列broker的訪問,可以透明的消費一個topic。它自己維持了已消費消息的狀態,即每次消費的都是下一個消息。

High-level API還支持以組的形式消費topic,如果consumers有同一個組名,那麽kafka就相當於一個隊列消息服務,而各個consumer均衡的消費相應partition中的數據。若consumers有不同的組名,那麽此時kafka就相當與一個發布/訂閱服務,會把topic中的所有消息廣播到每個consumer。

消息隊列服務:存在多個消費者,這些消費者同屬一個comsumer group,對於一個消息而言,只會被一個消費者消費

技術分享圖片

發布/訂閱服務:有不同的comsumer group,發布到topic的消息會被所有訂閱者消費

技術分享圖片

4. Kafka的一些設計思想和基本概念

kafka作為一個集群運行在一個或多個服務器上

kafka集群存儲的消息是以topic為類別記錄的。

每個消息(也叫記錄record,我習慣叫消息)是由一個key,一個value和時間戳構成。

Consumergroup:各個consumer可以組成一個組,每個消息只能被組中的一個consumer消費,如果一個消息可以被多個consumer消費的話,那麽這些consumer必須在不同的組。

消息狀態:在Kafka中,消息的狀態被保存在consumer中,broker不會關心哪個消息被消費了被誰消費了,只記錄一個offset值(指向partition中下一個要被消費的消息位置),這就意味著如果consumer處理不好的話,broker上的一個消息可能會被消費多次。

消息持久化:Kafka中會把消息持久化到本地文件系統中,並且保持極高的效率。

消息有效期:Kafka會長久保留其中的消息,以便consumer可以多次消費,當然其中很多細節是可配置的。

批量發送:Kafka支持以消息集合為單位進行批量發送,以提高push效率。

push-and-pull : Kafka中的Producer和consumer采用的是push-and-pull模式,即Producer只管向broker push消息,consumer只管從broker pull消息,兩者對消息的生產和消費是異步的。

Kafka集群中broker之間的關系:不是主從關系,各個broker在集群中地位一樣,我們可以隨意的增加或刪除任何一個broker節點。

負載均衡方面: Kafka提供了一個 metadata API來管理broker之間的負載(對Kafka0.8.x而言,對於0.7.x主要靠zookeeper來實現負載均衡)。

同步異步:Producer采用異步push方式,極大提高Kafka系統的吞吐率(可以通過參數控制是采用同步還是異步方式)。

分區機制partition:Kafka的broker端支持消息分區,Producer可以決定把消息發到哪個分區,在一個分區中消息的順序就是Producer發送消息的順序,一個主題中可以有多個分區,具體分區的數量是可配置的。

離線數據裝載:Kafka由於對可拓展的數據持久化的支持,它也非常適合向Hadoop或者數據倉庫中進行數據裝載。

插件支持:現在不少活躍的社區已經開發出不少插件來拓展Kafka的功能,如用來配合Storm、Hadoop、flume相關的插件。

5. Kafka核心特性

壓縮

我們上面已經知道了Kafka支持以集合(batch)為單位發送消息,在此基礎上,Kafka還支持對消息集合進行壓縮,Producer端可以通過GZIP或Snappy格式對消息集合進行壓縮。Producer端進行壓縮之後,在Consumer端需進行解壓。壓縮的好處就是減少傳輸的數據量,減輕對網絡傳輸的壓力,在對大數據處理上,瓶頸往往體現在網絡上而不是CPU(壓縮和解壓會耗掉部分CPU資源)。

那麽如何區分消息是壓縮的還是未壓縮的呢,Kafka在消息頭部添加了一個描述壓縮屬性字節,這個字節的後兩位表示消息的壓縮采用的編碼,如果後兩位為0,則表示消息未被壓縮。

消息可靠性

在消息系統中,保證消息在生產和消費過程中的可靠性是十分重要的,在實際消息傳遞過程中,可能會出現如下三中情況:

一個消息發送失敗

一個消息被發送多次

最理想的情況:exactly-once ,一個消息發送成功且僅發送

有許多系統聲稱它們實現了exactly-once,但是它們其實忽略了生產者或消費者在生產和消費過程中有可能失敗的情況。比如雖然一個Producer成功發送一個消息,但是消息在發送途中丟失,或者成功發送到broker,也被consumer成功取走,但是這個consumer在處理取過來的消息時失敗了。

從Producer端看:Kafka是這麽處理的,當一個消息被發送後,Producer會等待broker成功接收到消息的反饋(可通過參數控制等待時間),如果消息在途中丟失或是其中一個broker掛掉,Producer會重新發送(我們知道Kafka有備份機制,可以通過參數控制是否等待所有備份節點都收到消息)。

從Consumer端看:前面講到過partition,broker端記錄了partition中的一個offset值,這個值指向Consumer下一個即將消費message。當Consumer收到了消息,但卻在處理過程中掛掉,此時Consumer可以通過這個offset值重新找到上一個消息再進行處理。Consumer還有權限控制這個offset值,對持久化到broker端的消息做任意處理。

備份機制

備份機制是Kafka0.8之後版本的特性,備份機制的出現大大提高了Kafka集群的可靠性、穩定性。有了備份機制後,Kafka允許集群中的節點掛掉後而不影響整個集群工作。一個備份數量為n的集群允許n-1個節點失敗。在所有備份節點中,有一個節點作為lead節點,這個節點保存了其它備份節點列表,並維持各個備份間的狀體同步。

6. Kafka的應用場景

1、消息隊列:應用程度使用Kafka作為傳統的消息系統實現標準的隊列和消息的發布—訂閱,比起大多數的消息系統來說,Kafka有更好的吞吐量,內置的分區,冗余及容錯性,這讓Kafka成為了一個很好的大規模消息處理應用的解決方案。消息系統 一般吞吐量相對較低,但是需要更小的端到端延時,並嘗嘗依賴於Kafka提供的強大的持久性保障。在這個領域,Kafka足以媲美傳統消息系統,如ActiveMR或RabbitMQ。據了解,目前平安的F項目有使用kafka的消息隊列實現與外部的通信

2、監控:主機通過Kafka發送與系統和應用程序健康相關的指標,然後這些信息會被收集和處理從而創建監控儀表盤並發送警告

3、用戶追蹤:為了更好地理解用戶行為,改善用戶體驗,將用戶查看了哪個頁面、點擊了哪些內容等信息發送到每個數據中心的Kafka集群上,並通過Hadoop進行分析、生成日常報告。據了解,平安互聯網產品在應用該場景

4、日誌聚合:使用Kafka代替日誌聚合(log aggregation)。日誌聚合一般來說是從服務器上收集日誌文件,然後放到一個集中的位置(文件服務器或HDFS)進行處理。然而Kafka忽略掉 文件的細節,將其更清晰地抽象成一個個日誌或事件的消息流。這就讓Kafka處理過程延遲更低,更容易支持多數據源和分布式數據處理。比起以日誌為中心的 系統比如Scribe或者Flume來說,Kafka提供同樣高效的性能和因為復制導致的更高的耐用性保證,以及更低的端到端延遲


zookeeper

1 zookeeper簡介

Zookeeper是一個工具,可以實現集群中的分布式協調服務。所謂的分布式協調服務,就是在集群的節點中進行可靠的消息傳遞,來協調集群的工作。Zookeeper之所以能夠實現分布式協調服務,靠的就是它能夠保證分布式數據一致性。所謂的分布式數據一致性,指的就是可以在集群中保證數據傳遞的一致性。Zookeeper能夠提供的分布式協調服務包括:數據發布訂閱、負載均衡、命名服務、分布式協調/通知、集群管理、分布式鎖、分布式隊列等功能。

2 zookeeper特性

A. 最終一致性:client不論連接到哪個Server,展示給它都是同一個視圖,即zookeeper集群各個節點的數據都是一樣的,這是zookeeper最重要的性能。

B. 可靠性:具有簡單、健壯、良好的性能,如果消息被到一臺服務器接受,那麽它將被所有的服務器接受,簡單來說就是更新操作會確保在所有服務器都成功。

C. 原子性:讀寫會操作節點的所有數據,要麽讀或寫了完整的數據,要麽就失敗,不會出現只讀或寫了部分數據

D. 實時性:Zookeeper保證客戶端將在一個時間間隔範圍內獲得服務器的更新信息,或者服務器失效的信息。但由於網絡延時等原因,Zookeeper不能保證兩個客戶端能同時得到剛更新的數據,如果需要最新數據,應該在讀數據之前調用sync()接口。

E. 等待無關(wait-free):慢的或者失效的client不得幹預快速的client的請求,使得每個client都能有效的等待。

F. 順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務器上消息a在消息

b前發布,則在所有Server上消息a都將在消息b前被發布;偏序是指如果一個消息b在消息a後被同一個發送者發布,a必將排在b前面。

3 Zookeeper的架構及原理

3.1 Zookeeper的基本概念

Zookeeper包括以下幾個角色:

Leader:領導者負責進行投票的發起和決議,更新系統狀態

Follower:跟隨者用於接收客戶請求並返回結果(寫操作需發給leader進行廣播),在選主過程中參與投票

Observer:觀察者可以接收客戶端的請求,將寫請求發給leader,但observer不參與投票過程,只同步leader的狀態。

Client:請求發起方

技術分享圖片

Znode:ZooKeeper目錄樹中每一個節點對應一個Znode。每個Znode維護著一個屬性結構,它包含著版本號(dataVersion),時間戳(ctime,mtime)等狀態信息。ZooKeeper正是使用節點的這些特性來實現它的某些特定功能。每當Znode的數據改變時,他相應的版本號將會增加。每當客戶端檢索數據時,它將同時檢索數據的版本號。並且如果一個客戶端執行了某個節點的更新或刪除操作,他也必須提供要被操作的數據版本號。如果所提供的數據版本號與實際不匹配,那麽這個操作將會失敗。

  Znode是客戶端訪問ZooKeeper的主要實體,它包含以下幾個特征:

  (1)Watches

  客戶端可以在節點上設置watch(我們稱之為監視器)。當節點狀態發生改變時(數據的增、刪、改)將會觸發watch所對應的操作。當watch被觸發時,ZooKeeper將會向客戶端發送且僅發送一條通知,因為watch只能被觸發一次。

  (2)數據訪問

  ZooKeeper中的每個節點存儲的數據要被原子性的操作。也就是說讀操作將獲取與節點相關的所有數據,寫操作也將替換掉節點的所有數據。另外,每一個節點都擁有自己的ACL(訪問控制列表),這個列表規定了用戶的權限,即限定了特定用戶對目標節點可以執行的操作。

  (3)節點類型

ZooKeeper中的節點有兩種,分別為臨時節點和永久節點。節點的類型在創建時即被確定,並且不能改變。
  ZooKeeper的臨時節點:該節點的生命周期依賴於創建它們的會話。一旦會話結束,臨時節點將被自動刪除,當然可以也可以手動刪除。另外,需要註意是, ZooKeeper的臨時節點不允許擁有子節點。
  ZooKeeper的永久節點:該節點的生命周期不依賴於會話,並且只有在客戶端顯示執行刪除操作的時候,他們才能被刪除。

  (4)順序節點(唯一性的保證)

   當創建Znode的時候,用戶可以請求在ZooKeeper的路徑結尾添加一個遞增的計數。這個計數對於此節點的父節點來說是唯一的,它的格式為"%10d"(10位數字,沒有數值的數位用0補充,例如"0000000001")。當計數值大於232-1時,計數器將溢出。

org.apache.zookeeper.CreateMode中定義了四種節點類型,分別對應:
PERSISTENT:永久節點
EPHEMERAL:臨時節點
PERSISTENT_SEQUENTIAL:永久節點、序列化
EPHEMERAL_SEQUENTIAL:臨時節點、序列化

3.2 Zookeeper的數據模型

Zookeeper會維護一個具有層次關系的數據結構,它類似於一個標準的文件系統,如下圖所示

技術分享圖片

這種數據結構有如下特點:

每個子目錄項如 NameService 都被稱作為 znode,這個 znode 是被它所在的路徑唯一標識,如 Server1 這個 znode 的標識為 /NameService/Server1

znode 可以有子節點目錄,並且每個 znode 可以存儲數據,註意 EPHEMERAL 類型的目錄節點不能有子節點目錄

znode 是有版本的,每個 znode 中存儲的數據可以有多個版本,也就是一個訪問路徑中可以存儲多份數據

znode 可以是臨時節點,一旦創建這個 znode 的客戶端與服務器失去聯系,這個 znode 也將自動刪除,Zookeeper 的客戶端和服務器通信采用長連接方式,每個客戶端和服務器通過心跳來保持連接,這個連接狀態稱為 session,如果 znode 是臨時節點,這個 session 失效,znode 也就刪除了

znode 的目錄名可以自動編號,如 App1 已經存在,再創建的話,將會自動命名為 App2

znode 可以被監控,包括這個目錄節點中存儲的數據的修改,子節點目錄的變化等,一旦變化可以通知設置監控的客戶端,這個是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基於這個特性實現的

3.3 Zookeeper的數據同步

不管訪問zookeeper的那個server,數據都是一樣的,所有各server間肯定存在數據同步,同步過程圖如下:

查詢請求只涉及1、6兩個步驟,client端連接到其中一個server,server直接查詢本地,把結果返回給client端

更新修改操作請求則需要經過以下所有步驟,follower收到client端的寫請求,會把請求轉發給leader,由leader廣播給所有follower,follower數據寫成功後,給leader以確認,leader收到半數以上的follower確認後,返回commit給接收請求的follower,follower再返回結果給client,寫請求完成,

技術分享圖片

3.4 Zookeeper的leader選舉

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

一旦leader已經和多數的follower進行了狀態同步後,他就可以開始廣播消息了,即進入廣播狀態。這時候當一個server加入zookeeper服務中,它會在恢復模式下啟動,發現leader,並和leader進行狀態同步。待到同步結束,它也參與消息廣播。Zookeeper服務一直維持在Broadcast狀態,直到leader崩潰了或者leader失去了大部分的followers支持。

Broadcast模式極其類似於分布式事務中的2pc(two-phrase commit 兩階段提交):即leader提起一個決議,由followers進行投票,leader對投票結果進行計算決定是否通過該決議,如果通過執行該決議(事務),否則什麽也不做。

廣播模式需要保證proposal被按順序處理,因此zk采用了遞增的事務id號(zxid)來保證。所有的提議(proposal)都在被提出的時候加上了zxid。實現中zxid是一個64為的數字,它高32位是epoch用來標識leader關系是否改變,每次一個leader被選出來,它都會有一個新的epoch。低32位是個遞增計數。

當leader崩潰或者leader失去大多數的follower,這時候zk進入恢復模式,恢復模式需要重新選舉出一個新的leader,讓所有的server都恢復到一個正確的狀態。

首先看一下選舉的過程,zk的實現中用了基於paxos算法(主要是fastpaxos)的實現。具體如下:

1.每個Server啟動以後都詢問其它的Server它要投票給誰。

2.對於其他server的詢問,server每次根據自己的狀態都回復自己推薦的leader的id和上一次處理事務的zxid(系統啟動時每個server都會推薦自己)

3.收到所有Server回復以後,就計算出zxid最大的哪個Server,並將這個Server相關信息設置成下一次要投票的Server。

4.計算這過程中獲得票數最多的的sever為獲勝者,如果獲勝者的票數超過半數,則改server被選為leader。否則,繼續這個過程,直到leader被選舉出來。

此外恢復模式下,如果是重新剛從崩潰狀態恢復的或者剛啟動的的server還會從磁盤快照中恢復數據和會話信息。(zk會記錄事務日誌並定期進行快照,方便在恢復時進行狀態恢復)

選完leader以後,zk就進入狀態同步過程。

1.leader就會開始等待server連接

2.Follower連接leader,將最大的zxid發送給leader

3.Leader根據follower的zxid確定同步點

4.完成同步後通知follower 已經成為uptodate狀態

5.Follower收到uptodate消息後,又可以重新接受client的請求進行服務了。

4 zookeeper應用場景

統一命名服務

分布式環境下,經常需要對應用/服務進行統一命名,便於識別不同服務。類似於域名與ip之間對應關系,域名容易記住。通過名稱來獲取資源或服務的地址,提供者等信息按照層次結構組織服務/應用名稱可將服務名稱以及地址信息寫到Zookeeper上,客戶端通過Zookeeper獲取可用服務列表類。例子:平安的ESG平臺,服務方發布接口,會事先在zookeeper上創建一個服務編碼的znode,然後服務方每一個服務器啟動的時候都會把要發布的接口和ip端口信息作為子znode寫入服務編碼的znode下,供消費方訂閱。

配置管理

分布式環境下,配置文件管理和同步是一個常見問題。一個集群中,所有節點的配置信息是一致的,比如Hadoop。對配置文件修改後,希望能夠快速同步到各個節點上配置管理可交由Zookeeper實現。可將配置信息寫入Zookeeper的一個znode上。各個節點監聽這個znode。一旦znode中的數據被修改,zookeeper將通知各個節點。

集群管理

分布式環境中,實時掌握每個節點的狀態是必要的。可根據節點實時狀態作出一些調整。Zookeeper可將節點信息寫入Zookeeper的一個znode上。監聽這個znode可獲取它的實時狀態變化,如kafka的broker狀態管理。

分布式通知/協調

分布式環境中,經常存在一個服務需要知道它所管理的子服務的狀態。例如,NameNode須知道各DataNode的狀態,JobTracker須知道各TaskTracker的狀態。心跳檢測機制和信息推送也是可通過Zookeeper實現。例子:ESG的消費方訂閱:消費者事先在zookeeper上創建一個消費編碼的znode,並在管理平臺申請調用服務方的權限,管理平臺對消費編碼的znode設置了監聽,當消費者服務器啟動時,會把自己的ip信息作為子znode寫入消費編碼的znode下,會觸發管理平臺的監聽,管理平臺會把消費方所訂閱的服務方ip、端口、接口等信息推送給消費方。

分布式鎖

Zookeeper是強一致的。多個客戶端同時在Zookeeper上創建相同znode,只有一個創建成功。Zookeeper實現鎖的獨占性。多個客戶端同時在Zookeeper上創建相同znode ,創建成功的那個客戶端得到鎖,其他客戶端等待。Zookeeper 控制鎖的時序。各個客戶端在某個znode下創建臨時znode (類型為CreateMode. EPHEMERAL _SEQUENTIAL),這樣,該znode可掌握全局訪問時序。例如多個客戶端要修改一個文件的時候,可以采用zookeeper的分布式鎖控制

分布式隊列

兩種隊列。當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達,這種是同步隊列。隊列按照 FIFO 方式進行入隊和出隊操作,例如實現生產者和消費者模型。(可通過分布式鎖實現)
同步隊列。一個job由多個task組成,只有所有任務完成後,job才運行完成。可為job創建一個/job目錄,然後在該目錄下,為每個完成的task創建一個臨時znode,一旦臨時節點數目達到task總數,則job運行完成。


ZOOKEEPER和KAFKA簡介