溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Kafka中的術語設計詳解

發(fā)布時間:2021-09-10 14:58:20 來源:億速云 閱讀:115 作者:chen 欄目:開發(fā)技術

本篇內容介紹了“Kafka中的術語設計詳解”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!


Kafka 中的術語

broker:中間的kafka cluster,存儲消息,是由多個server組成的集群。

topic:kafka給消息提供的分類方式。broker用來存儲不同topic的消息數(shù)據(jù)。

producer:往broker中某個topic里面生產(chǎn)數(shù)據(jù)。

consumer:從broker中某個topic獲取數(shù)據(jù)。

Kafka 中的術語設計:

1、Broker

中間的kafka cluster,存儲消息,是由多個server組成的集群。

Kafka中的術語設計詳解

2、topic與消息

kafka將所有消息組織成多個topic的形式存儲,而每個topic又可以拆分成多個partition,每個partition又由一個一個消息組成。每個消息都被標識了一個遞增序列號代表其進來的先后順序,并按順序存儲在partition中。

Kafka中的術語設計詳解

這樣,消息就以一個個id的方式,組織起來。

producer選擇一個topic,生產(chǎn)消息,消息會通過分配策略append到某個partition末尾。

consumer選擇一個topic,通過id指定從哪個位置開始消費消息。消費完成之后保留id,下次可以從這個位置開始繼續(xù)消費,也可以從其他任意位置開始消費。

上面的id在kafka中稱為offset,這種組織和處理策略提供了如下好處:

消費者可以根據(jù)需求,靈活指定offset消費。

保證了消息不變性,為并發(fā)消費提供了線程安全的保證。每個consumer都保留自己的offset,互相之間不干擾,不存在線程安全問題。

消息訪問的并行高效性。每個topic中的消息被組織成多個partition,partition均勻分配到集群server中。生產(chǎn)、消費消息的時候,會被路由到指定partition,減少競爭,增加了程序的并行能力。

增加消息系統(tǒng)的可伸縮性。每個topic中保留的消息可能非常龐大,通過partition將消息切分成多個子消息,并通過負責均衡策略將partition分配到不同server。這樣當機器負載滿的時候,通過擴容可以將消息重新均勻分配。

保證消息可靠性。消息消費完成之后不會刪除,可以通過重置offset重新消費,保證了消息不會丟失。

靈活的持久化策略??梢酝ㄟ^指定時間段(如最近一天)來保存消息,節(jié)省broker存儲空間。

備份高可用性。消息以partition為單位分配到多個server,并以partition為單位進行備份。備份策略為:1個leader和N個followers,leader接受讀寫請求,followers被動復制leader。leader和followers會在集群中打散,保證partition高可用。

3、Partitions

每個Topics劃分為一個或者多個Partition,并且Partition中的每條消息都被標記了一個sequential id  ,也就是offset,并且存儲的數(shù)據(jù)是可配置存儲時間的

Kafka中的術語設計詳解

4、producer

producer生產(chǎn)消息需要如下參數(shù):

topic:往哪個topic生產(chǎn)消息。

partition:往哪個partition生產(chǎn)消息。

key:根據(jù)該key將消息分區(qū)到不同partition。

message:消息。

Kafka中的術語設計詳解

5、consumer

傳統(tǒng)消息系統(tǒng)有兩種模式:

隊列

發(fā)布訂閱

kafka通過consumer group將兩種模式統(tǒng)一處理:每個consumer將自己標記consumer group名稱,之后系統(tǒng)會將consumer  group按名稱分組,將消息復制并分發(fā)給所有分組,每個分組只有一個consumer能消費這條消息。如下圖:

Kafka中的術語設計詳解

于是推理出兩個極端情況:

  • 當所有consumer的consumer group相同時,系統(tǒng)變成隊列模式

  • 當每個consumer的consumer group都不相同時,系統(tǒng)變成發(fā)布訂閱

注意:

1、Consumer Groups 提供了topics和partitions的隔離, 如上圖Consumer Group  A中的consumer-C2掛掉,consumer-C1會接收P1,P2,即一個consumer  Group中有其他consumer掛掉后能夠重新平衡。如下圖:

Kafka中的術語設計詳解

2、多consumer并發(fā)消費消息時,容易導致消息亂序,通過限制消費者為同步,可以保證消息有序,但是這大大降低了程序的并發(fā)性。

kafka通過partition的概念,保證了partition內消息有序性,緩解了上面的問題。partition內消息會復制分發(fā)給所有分組,每個分組只有一個consumer能消費這條消息。這個語義保證了某個分組消費某個分區(qū)的消息,是同步而非并發(fā)的。如果一個topic只有一個partition,那么這個topic并發(fā)消費有序,否則只是單個partition有序。

一般消息系統(tǒng),consumer存在兩種消費模型:

push:優(yōu)勢在于消息實時性高。劣勢在于沒有考慮consumer消費能力和飽和情況,容易導致producer壓垮consumer。

pull:優(yōu)勢在可以控制消費速度和消費數(shù)量,保證consumer不會出現(xiàn)飽和。劣勢在于當沒有數(shù)據(jù),會出現(xiàn)空輪詢,消耗cpu。

kafka采用pull,并采用可配置化參數(shù)保證當存在數(shù)據(jù)并且數(shù)據(jù)量達到一定量的時候,consumer端才進行pull操作,否則一直處于block狀態(tài)。kakfa采用整數(shù)值consumer  position來記錄單個分區(qū)的消費狀態(tài),并且單個分區(qū)單個消息只能被consumer  group內的一個consumer消費,維護簡單開銷小。消費完成,broker收到確認,position指向下次消費的offset。由于消息不會刪除,在完成消費,position更新之后,consumer依然可以重置offset重新消費歷史消息。

消息發(fā)送語義

producer視角

消息最多發(fā)送一次:producer異步發(fā)送消息,或者同步發(fā)消息但重試次數(shù)為0。

消息至少發(fā)送一次:producer同步發(fā)送消息,失敗、超時都會重試。

消息發(fā)且僅發(fā)一次:后續(xù)版本支持。

consumer視角

消息最多消費一次:consumer先讀取消息,再確認position,***處理消息。

消息至少消費一次:consumer先讀取消息,再處理消息,***確認position。

消息消費且僅消費一次。

注意:

如果消息處理后的輸出端(如db)能保證消息更新冪等性,則多次消費也能保證exactly once語義。

如果輸出端能支持兩階段提交協(xié)議,則能保證確認position和處理輸出消息同時成功或者同時失敗。

在消息處理的輸出端存儲更新后的position,保證了確認position和處理輸出消息的原子性(簡單、通用)。

可用性

在kafka中,正常情況下所有node處于同步中狀態(tài),當某個node處于非同步中狀態(tài),也就意味著整個系統(tǒng)出問題,需要做容錯處理。

同步中代表了:

該node與zookeeper能連通。

該node如果是follower,那么consumer position與leader不能差距太大(差額可配置)。

某個分區(qū)內同步中的node組成一個集合,即該分區(qū)的ISR。

kafka通過兩個手段容錯:

數(shù)據(jù)備份:以partition為單位備份,副本數(shù)可設置。當副本數(shù)為N時,代表1個leader,N-1個followers,followers可以視為leader的consumer,拉取leader的消息,append到自己的系統(tǒng)中

failover:

1. 當leader處于非同步中時,系統(tǒng)從followers中選舉新leader

2. 當某個follower狀態(tài)變?yōu)榉峭街袝r,leader會將此follower剔除ISR,當此follower恢復并完成數(shù)據(jù)同步之后再次進入  ISR。

另外,kafka有個保障:當producer生產(chǎn)消息時,只有當消息被所有ISR確認時,才表示該消息提交成功。只有提交成功的消息,才能被consumer消費。

因此,當有N個副本時,N個副本都在ISR中,N-1個副本都出現(xiàn)異常時,系統(tǒng)依然能提供服務。

假設N副本全掛了,node恢復后會面臨同步數(shù)據(jù)的過程,這期間ISR中沒有node,會導致該分區(qū)服務不可用。kafka采用一種降級措施來處理:選舉***個恢復的node作為leader提供服務,以它的數(shù)據(jù)為基準,這個措施被稱為臟leader選舉。由于leader是主要提供服務的,kafka  broker將多個partition的leader均分在不同的server上以均攤風險。每個parition都有l(wèi)eader,如果在每個partition內運行選主進程,那么會導致產(chǎn)生非常多選主進程。kakfa采用一種輕量級的方式:從broker集群中選出一個作為controller,這個controller監(jiān)控掛掉的broker,為上面的分區(qū)批量選主。

一致性

上面的方案保證了數(shù)據(jù)高可用,有時高可用是體現(xiàn)在對一致性的犧牲上。如果希望達到強一致性,可以采取如下措施:

禁用臟leader選舉,ISR沒有node時,寧可不提供服務也不要未完全同步的node。

設置最小ISR數(shù)量min_isr,保證消息至少要被min_isr個node確認才能提交。

持久化

基于以下幾點事實,kafka重度依賴磁盤而非內存來存儲消息。

硬盤便宜,內存貴

順序讀+預讀取操作,能提高緩存***率

操作系統(tǒng)利用富余的內存作為pagecache,配合預讀取(read-ahead)+寫回(write-back)技術,從cache讀數(shù)據(jù),寫到cache就返回(操作系統(tǒng)后臺flush),提高用戶進程響應速度

java對象實際大小比理想大小要大,使得將消息存到內存成本很高

當堆內存占用不斷增加時,gc抖動較大

基于文件順序讀寫的設計思路,代碼編寫簡單

在持久化數(shù)據(jù)結構的選擇上,kafka采用了queue而不是Btree

kafka只有簡單的根據(jù)offset讀和append操作,所以基于queue操作的時間復雜度為O(1),而基于Btree操作的時間復雜度為O(logN)

在大量文件讀寫的時候,基于queue的read和append只需要一次磁盤尋址,而Btree則會涉及多次。磁盤尋址過程極大降低了讀寫性能

“Kafka中的術語設計詳解”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI