什么是kafka

Kafka簡介

Kafka最初由Linkedin公司開發(fā),是一個分布式毡琉、支持分區(qū)的(partition)铁瞒、多副本的(replica),基于zookeeper協(xié)調的分布式消息系統(tǒng)桅滋,它的最大特性就是可以實時處理大量數(shù)據(jù)以滿足各種需求場景:比如基于hadoop的批處理系統(tǒng)慧耍、低時延的實時系統(tǒng)、storm/Spark流式處理引擎丐谋,web/nginx日志芍碧、訪問日志,消息服務等等号俐,用scala語言編寫泌豆,Linkedin于2010年貢獻給了Apache基金會并成為頂級開源項目。

1.前言

消息隊列的性能好壞吏饿,其文件存儲機制設計是衡量一個消息隊列服務水平和最關鍵指標之一踪危。

1.1Kafka的特性:

  • 高吞吐性、低延遲:kafka每秒可以處理幾十萬條消息猪落,它的延遲最低只有幾毫秒贞远,每個topic可以分多個partition,consumer group對partition進行consume操作

  • 可拓展性:kafka集群支持熱拓展

  • 持久性笨忌、可靠性:消息被持久化到本地磁盤蓝仲,并且支持數(shù)據(jù)備份防止數(shù)據(jù)丟失

  • 容錯性:允許集群中節(jié)點失敗(若副本數(shù)量為n官疲,則允許n-1個節(jié)點失斣忧)

  • 高并發(fā):支持數(shù)千個客戶端同時讀寫

1.2Kafka的使用場景:

  • 日志收集:一個公司可以用Kafka可以收集各種服務的log,通過kafka以統(tǒng)一接口服務的方式開放給各種consumer袁余,例如hadoop、Hbase咱揍、Solr等

  • 消息系統(tǒng):解耦和生產(chǎn)者和消費者颖榜、緩存消息等

  • 用戶活動跟蹤:Kafka經(jīng)常被用來記錄web用戶或者app用戶的各種活動,如瀏覽網(wǎng)頁、搜索掩完、點擊等活動噪漾,這些活動信息被各個服務器發(fā)布到kafka的topic中,然后訂閱者通過訂閱這些topic來做實時的監(jiān)控分析且蓬,或者裝載到hadoop欣硼、數(shù)據(jù)倉庫中做離線分析和挖掘

  • 運營指標:Kafka也經(jīng)常用來記錄運營監(jiān)控數(shù)據(jù)。包括收集各種分布式應用的數(shù)據(jù)恶阴,生產(chǎn)各種操作的集中反饋诈胜,比如報警和報告

  • 流式處理:比如spark streaming和storm

1.3基本術語及架構

img

基本工作流程如上圖所示,其中:

  • Producer:Producer即生產(chǎn)者冯事,消息的產(chǎn)生者焦匈,是消息的入口

  • Broker:Broker是kafka實例,每個服務器上有一個或多個kafka的實例昵仅,我們姑且認為每個broker對應一臺服務器缓熟。每個kafka集群內的broker都有一個不重復的編號,如圖中的broker-0摔笤、broker-1等……

  • Topic:消息的主題够滑,可以理解為消息的分類,kafka的數(shù)據(jù)就保存在topic吕世。在每個broker上都可以創(chuàng)建多個topic彰触。

  • Partition:Topic的分區(qū),每個topic可以有多個分區(qū)寞冯,分區(qū)的作用是做負載渴析,提高kafka的吞吐量。同一個topic在不同的分區(qū)的數(shù)據(jù)是不重復的吮龄,partition的表現(xiàn)形式就是一個一個的文件夾俭茧!

  • Replication:每一個分區(qū)都有多個副本,副本的作用是做備胎漓帚。當主分區(qū)(Leader)故障的時候會選擇一個備胎(Follower)上位母债,成為Leader。在kafka中默認副本的最大數(shù)量是10個尝抖,且副本的數(shù)量不能大于Broker的數(shù)量毡们,follower和leader絕對是在不同的機器,同一機器對同一個分區(qū)也只可能存放一個副本(包括自己)昧辽。

  • Message:每一條發(fā)送的消息主體衙熔。

  • Consumer:消費者,即消息的消費方搅荞,是消息的出口红氯。

  • Consumer Group:我們可以將多個消費組組成一個消費者組框咙,在kafka的設計中同一個分區(qū)的數(shù)據(jù)只能被消費者組中的某一個消費者消費。同一個消費者組的消費者可以消費同一個topic的不同分區(qū)的數(shù)據(jù)痢甘,這也是為了提高kafka的吞吐量喇嘱!

  • Zookeeper:kafka集群依賴zookeeper來保存集群的的元信息,來保證系統(tǒng)的可用性塞栅。

1.4 工作流程分析

1.4.1發(fā)送數(shù)據(jù)

我們看上面的架構圖中者铜,producer就是生產(chǎn)者,是數(shù)據(jù)的入口放椰。注意看圖中的紅色箭頭作烟,Producer在寫入數(shù)據(jù)的時候永遠的找leader,不會直接將數(shù)據(jù)寫入follower庄敛!那leader怎么找呢俗壹?寫入的流程又是什么樣的呢?我們看下圖:

img

發(fā)送的流程就在圖中已經(jīng)說明了藻烤,就不單獨在文字列出來了绷雏!需要注意的一點是,消息寫入leader后怖亭,follower是主動的去leader進行同步的涎显!producer采用push模式將數(shù)據(jù)發(fā)布到broker,每條消息追加到分區(qū)中兴猩,順序寫入磁盤期吓,所以保證同一分區(qū)內的數(shù)據(jù)是有序的!寫入示意圖如下:

img

上面說到數(shù)據(jù)會寫入到不同的分區(qū)倾芝,那kafka為什么要做分區(qū)呢讨勤?相信大家應該也能猜到,分區(qū)的主要目的是:

  • 方便擴展晨另。因為一個topic可以有多個partition潭千,所以我們可以通過擴展機器去輕松的應對日益增長的數(shù)據(jù)量。

  • 提高并發(fā)借尿。以partition為讀寫單位刨晴,可以多個消費者同時消費數(shù)據(jù),提高了消息的處理效率路翻。

熟悉負載均衡的朋友應該知道狈癞,當我們向某個服務器發(fā)送請求的時候,服務端可能會對請求做一個負載茂契,將流量分發(fā)到不同的服務器蝶桶,那在kafka中,如果某個topic有多個partition掉冶,producer又怎么知道該將數(shù)據(jù)發(fā)往哪個partition呢真竖?kafka中有幾個原則:

  1. partition在寫入的時候可以指定需要寫入的partition儡蔓,如果有指定,則寫入對應的partition疼邀。

  2. 如果沒有指定partition,但是設置了數(shù)據(jù)的key召锈,則會根據(jù)key的值hash出一個partition

  3. 如果既沒指定partition旁振,又沒有設置key,則會輪詢選出一個partition涨岁。

保證消息不丟失是一個消息隊列中間件的基本保證拐袜,那producer在向kafka寫入消息的時候,怎么保證消息不丟失呢梢薪?其實上面的寫入流程圖中有描述出來蹬铺,那就是通過ACK應答機制!在生產(chǎn)者向隊列寫入數(shù)據(jù)的時候可以設置參數(shù)來確定是否確認kafka接收到數(shù)據(jù)秉撇,這個參數(shù)可設置的值為0甜攀、1all琐馆。

  • 0代表producer往集群發(fā)送數(shù)據(jù)不需要等到集群的返回规阀,不確保消息發(fā)送成功。安全性最低但是效率最高瘦麸。

  • 1代表producer往集群發(fā)送數(shù)據(jù)只要leader應答就可以發(fā)送下一條谁撼,只確保leader發(fā)送成功。

  • all代表producer往集群發(fā)送數(shù)據(jù)需要所有的follower都完成從leader的同步才會發(fā)送下一條滋饲,確保leader發(fā)送成功和所有的副本都完成備份厉碟。安全性最高,但是效率最低屠缭。

最后要注意的是箍鼓,如果往不存在的topic寫數(shù)據(jù),能不能寫入成功呢勿她?kafka會自動創(chuàng)建topic袄秩,分區(qū)和副本的數(shù)量根據(jù)默認配置都是1。

1.4.2 保存數(shù)據(jù)

Producer將數(shù)據(jù)寫入kafka后逢并,集群就需要對數(shù)據(jù)進行保存了之剧!kafka將數(shù)據(jù)保存在磁盤,可能在我們的一般的認知里砍聊,寫入磁盤是比較耗時的操作背稼,不適合這種高并發(fā)的組件。Kafka初始會單獨開辟一塊磁盤空間玻蝌,順序寫入數(shù)據(jù)(效率比隨機寫入高)蟹肘。

1.4.3 Partition 結構

前面說過了每個topic都可以分為一個或多個partition词疼,如果你覺得topic比較抽象,那partition就是比較具體的東西了帘腹!Partition在服務器上的表現(xiàn)形式就是一個一個的文件夾贰盗,每個partition的文件夾下面會有多組segment文件,每組segment文件又包含.index文件阳欲、.log文件舵盈、.timeindex文件(早期版本中沒有)三個文件, log文件就實際是存儲message的地方球化,而index和timeindex文件為索引文件秽晚,用于檢索消息。

1.4.4 Message結構

上面說到log文件就實際是存儲message的地方筒愚,我們在producer往kafka寫入的也是一條一條的message赴蝇,那存儲在log中的message是什么樣子的呢?消息主要包含消息體巢掺、消息大小句伶、offset、壓縮類型……等等址遇!我們重點需要知道的是下面三個:

  1. offset:offset是一個占8byte的有序id號熄阻,它可以唯一確定每條消息在parition內的位置

  2. 消息大小:消息大小占用4byte倔约,用于描述消息的大小秃殉。

  3. 消息體:消息體存放的是實際的消息數(shù)據(jù)(被壓縮過),占用的空間根據(jù)具體的消息而不一樣浸剩。

1.4.5 存儲策略

無論消息是否被消費钾军,kafka都會保存所有的消息。那對于舊數(shù)據(jù)有什么刪除策略呢绢要?

  1. 基于時間吏恭,默認配置是168小時(7天)。

  2. 基于大小重罪,默認配置是1073741824樱哼。

需要注意的是,kafka讀取特定消息的時間復雜度是O(1)剿配,所以這里刪除過期的文件并不會提高kafka的性能搅幅!

1.4.6 消費數(shù)據(jù)

消息存儲在log文件后,消費者就可以進行消費了呼胚。在講消息隊列通信的兩種模式的時候講到過點對點模式和發(fā)布訂閱模式茄唐。Kafka采用的是點對點的模式,消費者主動的去kafka集群拉取消息蝇更,與producer相同的是沪编,消費者在拉取消息的時候也是找leader去拉取呼盆。

多個消費者可以組成一個消費者組(consumer group),每個消費者組都有一個組id蚁廓!同一個消費組者的消費者可以消費同一topic下不同分區(qū)的數(shù)據(jù)访圃,但是不會組內多個消費者消費同一分區(qū)的數(shù)據(jù)!O嗲丁挽荠!如下圖:

img

圖示是消費者組內的消費者小于partition數(shù)量的情況,所以會出現(xiàn)某個消費者消費多個partition數(shù)據(jù)的情況平绩,消費的速度也就不及只處理一個partition的消費者的處理速度!如果是消費者組的消費者多于partition的數(shù)量漠另,那會不會出現(xiàn)多個消費者消費同一個partition的數(shù)據(jù)呢捏雌?上面已經(jīng)提到過不會出現(xiàn)這種情況!多出來的消費者不消費任何partition的數(shù)據(jù)笆搓。所以在實際的應用中性湿,建議消費者組的consumer的數(shù)量與partition的數(shù)量一致

2.Kafka原理概念

2.1 持久化

kafka使用文件存儲消息(append only log),這就直接決定kafka在性能上嚴重依賴文件系統(tǒng)的本身特性.且無論任何OS下,對文件系統(tǒng)本身的優(yōu)化是非常艱難的.文件緩存/直接內存映射等是常用的手段.因為kafka是對日志文件進行append操作,因此磁盤檢索的開支是較小的;同時為了減少磁盤寫入的次數(shù),broker會將消息暫時buffer起來,當消息的個數(shù)(或尺寸)達到一定閥值時,再flush到磁盤,這樣減少了磁盤IO調用的次數(shù).對于kafka而言,較高性能的磁盤,將會帶來更加直接的性能提升.

2.2 性能

除磁盤IO之外,我們還需要考慮網(wǎng)絡IO,這直接關系到kafka的吞吐量問題.kafka并沒有提供太多高超的技巧;對于producer端,可以將消息buffer起來,當消息的條數(shù)達到一定閥值時,批量發(fā)送給broker;對于consumer端也是一樣,批量fetch多條消息.不過消息量的大小可以通過配置文件來指定.對于kafka broker端,似乎有個sendfile系統(tǒng)調用可以潛在的提升網(wǎng)絡IO的性能:將文件的數(shù)據(jù)映射到系統(tǒng)內存中,socket直接讀取相應的內存區(qū)域即可,而無需進程再次copy和交換(這里涉及到"磁盤IO數(shù)據(jù)"/"內核內存"/"進程內存"/"網(wǎng)絡緩沖區(qū)",多者之間的數(shù)據(jù)copy).

其實對于producer/consumer/broker三者而言,CPU的開支應該都不大,因此啟用消息壓縮機制是一個良好的策略;壓縮需要消耗少量的CPU資源,不過對于kafka而言,網(wǎng)絡IO更應該需要考慮.可以將任何在網(wǎng)絡上傳輸?shù)南⒍冀?jīng)過壓縮.kafka支持gzip/snappy等多種壓縮方式

2.3 負載均衡

kafka集群中的任何一個broker,都可以向producer提供metadata信息,這些metadata中包含"集群中存活的servers列表"/"partitions leader列表"等信息(請參看zookeeper中的節(jié)點信息). 當producer獲取到metadata信息之后, producer將會和Topic下所有partition leader保持socket連接;消息由producer直接通過socket發(fā)送到broker,中間不會經(jīng)過任何"路由層".

異步發(fā)送满败,將多條消息暫且在客戶端buffer起來,并將他們批量發(fā)送到broker;小數(shù)據(jù)IO太多,會拖慢整體的網(wǎng)絡延遲,批量延遲發(fā)送事實上提升了網(wǎng)絡效率;不過這也有一定的隱患,比如當producer失效時,那些尚未發(fā)送的消息將會丟失肤频。

2.4 Topic模型

其他JMS實現(xiàn),消息消費的位置是有prodiver保留,以便避免重復發(fā)送消息或者將沒有消費成功的消息重發(fā)等,同時還要控制消息的狀態(tài).這就要求JMS broker需要太多額外的工作.在kafka中,partition中的消息只有一個consumer在消費,且不存在消息狀態(tài)的控制,也沒有復雜的消息確認機制,可見kafka broker端是相當輕量級的.當消息被consumer接收之后,consumer可以在本地保存最后消息的offset,并間歇性的向zookeeper注冊offset.由此可見,consumer客戶端也很輕量級。

kafka中consumer負責維護消息的消費記錄,而broker則不關心這些,這種設計不僅提高了consumer端的靈活性,也適度的減輕了broker端設計的復雜度;這是和眾多JMS prodiver的區(qū)別.此外,kafka中消息ACK的設計也和JMS有很大不同,kafka中的消息是批量(通常以消息的條數(shù)或者chunk的尺寸為單位)發(fā)送給consumer,當消息消費成功后,向zookeeper提交消息的offset,而不會向broker交付ACK.或許你已經(jīng)意識到,這種"寬松"的設計,將會有"丟失"消息/"消息重發(fā)"的危險.

2.5 消息傳輸一致

Kafka提供3種消息傳輸一致性語義:最多1次算墨,最少1次宵荒,恰好1次。

最少1次:可能會重傳數(shù)據(jù)净嘀,有可能出現(xiàn)數(shù)據(jù)被重復處理的情況;

最多1次:可能會出現(xiàn)數(shù)據(jù)丟失情況;

恰好1次:并不是指真正只傳輸1次报咳,只不過有一個機制。確保不會出現(xiàn)“數(shù)據(jù)被重復處理”和“數(shù)據(jù)丟失”的情況挖藏。

at most once: 消費者fetch消息,然后保存offset,然后處理消息;當client保存offset之后,但是在消息處理過程中consumer進程失效(crash),導致部分消息未能繼續(xù)處理.那么此后可能其他consumer會接管,但是因為offset已經(jīng)提前保存,那么新的consumer將不能fetch到offset之前的消息(盡管它們尚沒有被處理),這就是"at most once".

at least once: 消費者fetch消息,然后處理消息,然后保存offset.如果消息處理成功之后,但是在保存offset階段zookeeper異呈钊校或者consumer失效,導致保存offset操作未能執(zhí)行成功,這就導致接下來再次fetch時可能獲得上次已經(jīng)處理過的消息,這就是"at least once".

"Kafka Cluster"到消費者的場景中可以采取以下方案來得到“恰好1次”的一致性語義:

最少1次+消費者的輸出中額外增加已處理消息最大編號:由于已處理消息最大編號的存在,不會出現(xiàn)重復處理消息的情況膜眠。

2.6 副本

kafka中,replication策略是基于partition,而不是topic;kafka將每個partition數(shù)據(jù)復制到多個server上,任何一個partition有一個leader和多個follower(可以沒有);備份的個數(shù)可以通過broker配置文件來設定岩臣。leader處理所有的read-write請求,follower需要和leader保持同步.Follower就像一個"consumer",消費消息并保存在本地日志中;leader負責跟蹤所有的follower狀態(tài),如果follower"落后"太多或者失效,leader將會把它從replicas同步列表中刪除.當所有的follower都將一條消息保存成功,此消息才被認為是"committed",那么此時consumer才能消費它,這種同步策略,就要求follower和leader之間必須具有良好的網(wǎng)絡環(huán)境.即使只有一個replicas實例存活,仍然可以保證消息的正常發(fā)送和接收,只要zookeeper集群存活即可.

選擇follower時需要兼顧一個問題,就是新leader server上所已經(jīng)承載的partition leader的個數(shù),如果一個server上有過多的partition leader,意味著此server將承受著更多的IO壓力.在選舉新leader,需要考慮到"負載均衡",partition leader較少的broker將會更有可能成為新的leader.

2.7 log

每個log entry格式為"4個字節(jié)的數(shù)字N表示消息的長度" + "N個字節(jié)的消息內容";每個日志都有一個offset來唯一的標記一條消息,offset的值為8個字節(jié)的數(shù)字,表示此消息在此partition中所處的起始位置..每個partition在物理存儲層面,有多個log file組成(稱為segment).segment file的命名為"最小offset".kafka.例如"00000000000.kafka";其中"最小offset"表示此segment中起始消息的offset.

獲取消息時,需要指定offset和最大chunk尺寸,offset用來表示消息的起始位置,chunk size用來表示最大獲取消息的總長度(間接的表示消息的條數(shù)).根據(jù)offset,可以找到此消息所在segment文件,然后根據(jù)segment的最小offset取差值,得到它在file中的相對位置,直接讀取輸出即可.

2.8 分布式

kafka使用zookeeper來存儲一些meta信息,并使用了zookeeper watch機制來發(fā)現(xiàn)meta信息的變更并作出相應的動作(比如consumer失效,觸發(fā)負載均衡等)

Broker node registry: 當一個kafka broker啟動后,首先會向zookeeper注冊自己的節(jié)點信息(臨時znode),同時當broker和zookeeper斷開連接時,此znode也會被刪除.

Broker Topic Registry: 當一個broker啟動時,會向zookeeper注冊自己持有的topic和partitions信息,仍然是一個臨時znode.

Consumer and Consumer group: 每個consumer客戶端被創(chuàng)建時,會向zookeeper注冊自己的信息;此作用主要是為了"負載均衡".一個group中的多個consumer可以交錯的消費一個topic的所有partitions;簡而言之,保證此topic的所有partitions都能被此group所消費,且消費時為了性能考慮,讓partition相對均衡的分散到每個consumer上.

Consumer id Registry: 每個consumer都有一個唯一的ID(host:uuid,可以通過配置文件指定,也可以由系統(tǒng)生成),此id用來標記消費者信息.

Consumer offset Tracking: 用來跟蹤每個consumer目前所消費的partition中最大的offset.此znode為持久節(jié)點,可以看出offset跟group_id有關,以表明當group中一個消費者失效,其他consumer可以繼續(xù)消費.

Partition Owner registry: 用來標記partition正在被哪個consumer消費.臨時znode档押。此節(jié)點表達了"一個partition"只能被group下一個consumer消費,同時當group下某個consumer失效,那么將會觸發(fā)負載均衡(即:讓partitions在多個consumer間均衡消費,接管那些"游離"的partitions)

當consumer啟動時,所觸發(fā)的操作:

A) 首先進行"Consumer id Registry";

B) 然后在"Consumer id Registry"節(jié)點下注冊一個watch用來監(jiān)聽當前group中其他consumer的"leave"和"join";只要此znode path下節(jié)點列表變更,都會觸發(fā)此group下consumer的負載均衡.(比如一個consumer失效,那么其他consumer接管partitions).

C) 在"Broker id registry"節(jié)點下,注冊一個watch用來監(jiān)聽broker的存活情況;如果broker列表變更,將會觸發(fā)所有的groups下的consumer重新balance.

總結:

  1. Producer端使用zookeeper用來"發(fā)現(xiàn)"broker列表,以及和Topic下每個partition leader建立socket連接并發(fā)送消息.
  2. Broker端使用zookeeper用來注冊broker信息,已經(jīng)監(jiān)測partition leader存活性.
  3. Consumer端使用zookeeper用來注冊consumer信息,其中包括consumer消費的partition列表等,同時也用來發(fā)現(xiàn)broker列表,并和partition leader建立socket連接,并獲取消息兴枯。

2.9 Leader的選擇

Kafka的核心是日志文件累盗,日志文件在集群中的同步是分布式數(shù)據(jù)系統(tǒng)最基礎的要素屎勘。

如果leaders永遠不會down的話我們就不需要followers了爽撒!一旦leader down掉了县习,需要在followers中選擇一個新的leader.但是followers本身有可能延時太久或者crash沟启,所以必須選擇高質量的follower作為leader.必須保證三娩,一旦一個消息被提交了鸿脓,但是leader down掉了抑钟,新選出的leader必須可以提供這條消息涯曲。大部分的分布式系統(tǒng)采用了多數(shù)投票法則選擇新的leader,對于多數(shù)投票法則,就是根據(jù)所有副本節(jié)點的狀況動態(tài)的選擇最適合的作為leader.Kafka并不是使用這種方法在塔。

Kafka動態(tài)維護了一個同步狀態(tài)的副本的集合(a set of in-sync replicas)幻件,簡稱ISR,在這個集合中的節(jié)點都是和leader保持高度一致的蛔溃,任何一條消息必須被這個集合中的每個節(jié)點讀取并追加到日志中了绰沥,才回通知外部這個消息已經(jīng)被提交了。因此這個集合中的任何一個節(jié)點隨時都可以被選為leader.ISR在ZooKeeper中維護贺待。ISR中有f+1個節(jié)點徽曲,就可以允許在f個節(jié)點down掉的情況下不會丟失消息并正常提供服。ISR的成員是動態(tài)的麸塞,如果一個節(jié)點被淘汰了秃臣,當它重新達到“同步中”的狀態(tài)時,他可以重新加入ISR.這種leader的選擇方式是非衬墓ぃ快速的奥此,適合kafka的應用場景。

一個邪惡的想法:如果所有節(jié)點都down掉了怎么辦雁比?Kafka對于數(shù)據(jù)不會丟失的保證稚虎,是基于至少一個節(jié)點是存活的,一旦所有節(jié)點都down了偎捎,這個就不能保證了蠢终。

實際應用中,當所有的副本都down掉時茴她,必須及時作出反應蜕径。可以有以下兩種選擇:

  1. 等待ISR中的任何一個節(jié)點恢復并擔任leader败京。

  2. 選擇所有節(jié)點中(不只是ISR)第一個恢復的節(jié)點作為leader.

這是一個在可用性和連續(xù)性之間的權衡兜喻。如果等待ISR中的節(jié)點恢復,一旦ISR中的節(jié)點起不起來或者數(shù)據(jù)都是了赡麦,那集群就永遠恢復不了了朴皆。如果等待ISR意外的節(jié)點恢復,這個節(jié)點的數(shù)據(jù)就會被作為線上數(shù)據(jù)泛粹,有可能和真實的數(shù)據(jù)有所出入遂铡,因為有些數(shù)據(jù)它可能還沒同步到。Kafka目前選擇了第二種策略晶姊,在未來的版本中將使這個策略的選擇可配置扒接,可以根據(jù)場景靈活的選擇。

這種窘境不只Kafka會遇到,幾乎所有的分布式數(shù)據(jù)系統(tǒng)都會遇到钾怔。

2.10 副本管理

以上僅僅以一個topic一個分區(qū)為例子進行了討論碱呼,但實際上一個Kafka將會管理成千上萬的topic分區(qū).Kafka盡量的使所有分區(qū)均勻的分布到集群所有的節(jié)點上而不是集中在某些節(jié)點上,另外主從關系也盡量均衡這樣每個幾點都會擔任一定比例的分區(qū)的leader.

優(yōu)化leader的選擇過程也是很重要的宗侦,它決定了系統(tǒng)發(fā)生故障時的空窗期有多久愚臀。Kafka選擇一個節(jié)點作為“controller”,當發(fā)現(xiàn)有節(jié)點down掉的時候它負責在游泳分區(qū)的所有節(jié)點中選擇新的leader,這使得Kafka可以批量的高效的管理所有分區(qū)節(jié)點的主從關系。如果controller down掉了矾利,活著的節(jié)點中的一個會備切換為新的controller.

2.11 Leader與副本同步

對于某個分區(qū)來說姑裂,保存正分區(qū)的"broker"為該分區(qū)的"leader",保存?zhèn)浞莘謪^(qū)的"broker"為該分區(qū)的"follower"男旗。備份分區(qū)會完全復制正分區(qū)的消息舶斧,包括消息的編號等附加屬性值。為了保持正分區(qū)和備份分區(qū)的內容一致察皇,Kafka采取的方案是在保存?zhèn)浞莘謪^(qū)的"broker"上開啟一個消費者進程進行消費捧毛,從而使得正分區(qū)的內容與備份分區(qū)的內容保持一致。一般情況下让网,一個分區(qū)有一個“正分區(qū)”和零到多個“備份分區(qū)”∈郏可以配置“正分區(qū)+備份分區(qū)”的總數(shù)量溃睹,關于這個配置,不同主題可以有不同的配置值胰坟。注意因篇,生產(chǎn)者,消費者只與保存正分區(qū)的"leader"進行通信笔横。

Kafka允許topic的分區(qū)擁有若干副本竞滓,這個數(shù)量是可以配置的,你可以為每個topic配置副本的數(shù)量吹缔。Kafka會自動在每個副本上備份數(shù)據(jù)商佑,所以當一個節(jié)點down掉時數(shù)據(jù)依然是可用的。

Kafka的副本功能不是必須的厢塘,你可以配置只有一個副本茶没,這樣其實就相當于只有一份數(shù)據(jù)。

創(chuàng)建副本的單位是topic的分區(qū)晚碾,每個分區(qū)都有一個leader和零或多個followers.所有的讀寫操作都由leader處理抓半,一般分區(qū)的數(shù)量都比broker的數(shù)量多的多,各分區(qū)的leader均勻的分布在brokers中格嘁。所有的followers都復制leader的日志笛求,日志中的消息和順序都和leader中的一致。followers向普通的consumer那樣從leader那里拉取消息并保存在自己的日志文件中。

許多分布式的消息系統(tǒng)自動的處理失敗的請求探入,它們對一個節(jié)點是否著(alive)”有著清晰的定義狡孔。Kafka判斷一個節(jié)點是否活著有兩個條件:

  1. 節(jié)點必須可以維護和ZooKeeper的連接,Zookeeper通過心跳機制檢查每個節(jié)點的連接新症。

  2. 如果節(jié)點是個follower,他必須能及時的同步leader的寫操作步氏,延時不能太久。

符合以上條件的節(jié)點準確的說應該是“同步中的(in sync)”徒爹,而不是模糊的說是“活著的”或是“失敗的”荚醒。Leader會追蹤所有“同步中”的節(jié)點,一旦一個down掉了隆嗅,或是卡住了界阁,或是延時太久,leader就會把它移除胖喳。至于延時多久算是“太久”泡躯,是由參數(shù)replica.lag.max.messages決定的,怎樣算是卡住了丽焊,怎是由參數(shù)replica.lag.time.max.ms決定的较剃。

只有當消息被所有的副本加入到日志中時,才算是“committed”技健,只有committed的消息才會發(fā)送給consumer写穴,這樣就不用擔心一旦leader down掉了消息會丟失。Producer也可以選擇是否等待消息被提交的通知雌贱,這個是由參數(shù)acks決定的啊送。

Kafka保證只要有一個“同步中”的節(jié)點,“committed”的消息就不會丟失欣孤。

3.Kafka與Zookeeper

3.1 Zookeeper協(xié)調控制

  1. 管理broker與consumer的動態(tài)加入與離開馋没。(Producer不需要管理,隨便一臺計算機都可以作為Producer向Kakfa Broker發(fā)消息)
  2. 觸發(fā)負載均衡降传,當broker或consumer加入或離開時會觸發(fā)負載均衡算法篷朵,使得一個consumer group內的多個consumer的消費負載平衡。(因為一個comsumer消費一個或多個partition婆排,一個partition只能被一個consumer消費)
  3. 維護消費關系及每個partition的消費信息款票。

3.2 Zookeeper上的細節(jié)

  1. 每個broker啟動后會在zookeeper上注冊一個臨時的broker registry,包含broker的ip地址和端口號泽论,所存儲的topics和partitions信息艾少。
  2. 每個consumer啟動后會在zookeeper上注冊一個臨時的consumer registry:包含consumer所屬的consumer group以及訂閱的topics。
  3. 每個consumer group關聯(lián)一個臨時的owner registry和一個持久的offset registry翼悴。對于被訂閱的每個partition包含一個owner registry缚够,內容為訂閱這個partition的consumer id幔妨;同時包含一個offset registry,內容為上一次訂閱的offset谍椅。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末误堡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子雏吭,更是在濱河造成了極大的恐慌锁施,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杖们,死亡現(xiàn)場離奇詭異悉抵,居然都是意外死亡,警方通過查閱死者的電腦和手機摘完,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門姥饰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人孝治,你說我怎么就攤上這事列粪。” “怎么了谈飒?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵岂座,是天一觀的道長。 經(jīng)常有香客問我杭措,道長费什,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任瓤介,我火速辦了婚禮,結果婚禮上赘那,老公的妹妹穿的比我還像新娘刑桑。我一直安慰自己,他們只是感情好募舟,可當我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布祠斧。 她就那樣靜靜地躺著,像睡著了一般拱礁。 火紅的嫁衣襯著肌膚如雪琢锋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天呢灶,我揣著相機與錄音吴超,去河邊找鬼。 笑死鸯乃,一個胖子當著我的面吹牛鲸阻,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鸟悴,長吁一口氣:“原來是場噩夢啊……” “哼陈辱!你這毒婦竟也來了?” 一聲冷哼從身側響起细诸,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤沛贪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后震贵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體利赋,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年屏歹,在試婚紗的時候發(fā)現(xiàn)自己被綠了隐砸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蝙眶,死狀恐怖季希,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情幽纷,我是刑警寧澤式塌,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站友浸,受9級特大地震影響峰尝,放射性物質發(fā)生泄漏。R本人自食惡果不足惜收恢,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一武学、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伦意,春花似錦火窒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至离钝,卻和暖如春票编,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卵渴。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工慧域, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浪读。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓吊趾,卻偏偏與公主長得像宛裕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子论泛,可洞房花燭夜當晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內容