【Kafka系列】4.1 消費(fèi)者Consumer

1.消費(fèi)者和消費(fèi)者組的關(guān)系

Kafka并不刪除已消費(fèi)的消息,為了實(shí)現(xiàn)傳統(tǒng)Message Queue消息只被消費(fèi)一次的語義张咳,Kafka保證每條消息在同一個Consumer Group里只會被某一個Consumer消費(fèi)。與傳統(tǒng)Message Queue不同的是矢洲,Kafka還允許不同Consumer Group同時消費(fèi)同一條消息炊甲,這一特性可以為消息的多元化處理提供支持。

消費(fèi)者組

測試:創(chuàng)建一個Topic (名為topic1)琴拧,再創(chuàng)建一個屬于group1的Consumer實(shí)例,并創(chuàng)建三個屬于group2的Consumer實(shí)例嘱支,然后通過Producer向topic1發(fā)送Key分別為1蚓胸,2,3的消息除师。結(jié)果發(fā)現(xiàn)屬于group1的Consumer收到了所有的這三條消息沛膳,同時group2中的3個Consumer分別收到了Key為1,2汛聚,3的消息锹安,如下圖所示。

消費(fèi)者組測試

2.kafka消費(fèi)者Consumer Rebalance

(1)Kafka的Rebalance(再均衡:在同一個消費(fèi)者組當(dāng)中,分區(qū)的所有權(quán)從一個消費(fèi)者轉(zhuǎn)移到另外一個消費(fèi)者)機(jī)制叹哭,Rebalance顧名思義就是重新均衡消費(fèi)者消費(fèi)忍宋。Rebalance的過程如下:

漸進(jìn)式rebalance

第一步:所有成員都向coordinator發(fā)送請求,請求入組风罩。一旦所有成員都發(fā)送了請求糠排,coordinator會從中選擇一個consumer擔(dān)任leader的角色,并把組成員信息以及訂閱信息發(fā)給leader超升。

第二步:leader開始分配消費(fèi)方案入宦,指明具體哪個consumer負(fù)責(zé)消費(fèi)哪些topic的哪些partition。一旦完成分配室琢,leader會將這個方案發(fā)給coordinator乾闰。coordinator接收到分配方案之后會把方案發(fā)給各個consumer,這樣組內(nèi)的所有成員就都知道自己應(yīng)該消費(fèi)哪些分區(qū)了盈滴。

(2)以下的場景會觸發(fā)Consumer Rebalance操作:

①新的消費(fèi)者加入Consumer Group涯肩;②有消費(fèi)者主動退出Consumer Group;③Consumer Group訂閱的任何一個Topic出現(xiàn)分區(qū)數(shù)量的變化雹熬。

(3)默認(rèn)情況下宽菜,Kafka提供了兩種分配策略:RangeRoundRobin

Range策略:①對一個topic中的partition進(jìn)行排序竿报;②對消費(fèi)者按字典進(jìn)行排序铅乡;③遍歷排序后的partition的方式分配給消費(fèi)者。

例子:有兩個消費(fèi)者C0和C1烈菌,兩個topic(t0,t1)阵幸,每個topic有三個分區(qū)p(0-2),那么采用Range策略芽世,分配出的結(jié)果為:

C0: [t0-p0, t0-p1, t1-p0, t1-p1]

C1: [t0-p2, t1-p2]

RoundRobin策略:RoundRobin策略和Range策略類型挚赊,唯一的區(qū)別就是Range策略分配partition時,是按照topic逐次劃分的济瓢。RoundRobin策略則是將所有topic的所有分區(qū)一起排序荠割,然后遍歷partition分配給消費(fèi)者

例子:有兩個消費(fèi)者C0和C1旺矾,兩個topic(t0,t1)蔑鹦,每個topic有三個分區(qū)p(0-2),那么采用RoundRobin策略箕宙,分配出的結(jié)果為:

C0: [t0-p0, t0-p2, t1-p1]

C1: [t0-p1, t1-p0, t1-p2]

(4)Kafka對消息的分配是以Partition為單位分配的嚎朽,而非以每一條消息作為分配單元。這樣設(shè)計的劣勢:無法保證同一個Consumer Group里的Consumer均勻消費(fèi)數(shù)據(jù)柬帕。優(yōu)勢:①每個Consumer不用都跟大量的Broker通信哟忍,減少通信開銷狡门;②降低了分配難度,實(shí)現(xiàn)也更簡單锅很;③因?yàn)橥粋€Partition里的數(shù)據(jù)是有序的其馏,這種設(shè)計可以保證每個Partition里的數(shù)據(jù)可以被有序消費(fèi)。

如果某Consumer Group中Consumer實(shí)例數(shù)量少于Partition數(shù)量粗蔚,則至少有一個Consumer會消費(fèi)多個Partition的數(shù)據(jù)尝偎,如果Consumer的數(shù)量與Partition數(shù)量相同,則正好一個Consumer消費(fèi)一個Partition的數(shù)據(jù)鹏控。而如果Consumer的數(shù)量多于Partition的數(shù)量時,會有部分Consumer無法消費(fèi)該Topic下任何一條消息肤寝。

3.非線程安全的Kafka Consumer實(shí)現(xiàn)多線程消費(fèi)

(1)線程封閉当辐,即為每個線程實(shí)例化一個Consumer對象。說明:一個線程對應(yīng)一個Consumer 實(shí)例鲤看,稱之為消費(fèi)線程缘揪。一個消費(fèi)線程可以消費(fèi)一個或多個分區(qū)中的消息,所有的消費(fèi)線程都隸屬于同一個消費(fèi)組义桂。

封閉線程消費(fèi)

(2)消費(fèi)者程序使用單或多線程獲取消息找筝,同時創(chuàng)建多個消費(fèi)線程執(zhí)行消息處理邏輯。獲取消息的線程可以是一個慷吊,也可以是多個袖裕,每個線程維護(hù)專屬的Consumer實(shí)例,處理消息則交由特定的線程池來做溉瓶,從而實(shí)現(xiàn)消息獲取與消息處理的真正解耦急鳄。

線程池消費(fèi)

4.指定offset或者timestamp消費(fèi)數(shù)據(jù)

指定offset:Kafka是通過seek() 方法來指定消費(fèi)的,在執(zhí)行seek() 方法之前要去執(zhí)行一次poll()方法堰酿,等到分配到分區(qū)之后會去對應(yīng)partition的指定offset開始消費(fèi)疾宏。

指定timestamp:Kafka的offsetsForTimes() 方法,通過timestamp 來查詢與此對應(yīng)的分區(qū)位置触创。offsetsForTimes() 方法的參數(shù) timestampsToSearch 是一個Map類型坎藐,key為待查詢的partition,而 value為待查詢的時間戳哼绑,該方法會返回時間戳大于等于待查詢時間的第一條消息對應(yīng)的位置和時間戳岩馍。

5.消費(fèi)者提交消費(fèi)位移時提交的是當(dāng)前消費(fèi)到的最新消息的offset還是offset+1

在舊消費(fèi)者客戶端中,消費(fèi)位移是存儲在 ZooKeeper 中的凌那。而在新消費(fèi)者客戶端中兼雄,消費(fèi)位移存儲在 Kafka 內(nèi)部的主題__consumer_offsets 中。

當(dāng)前消費(fèi)者需要提交的消費(fèi)位移是offset+1帽蝶。

6.造成重復(fù)消費(fèi)的場景

(1)Rebalance:一個consumer正在消費(fèi)一個partition的消息A赦肋,還沒有消費(fèi)完块攒,發(fā)生了rebalance(加入了一個consumer),從而導(dǎo)致消息A沒有消費(fèi)成功佃乘,rebalance后囱井,另一個consumer又把這條消息消費(fèi)一遍。

(2)消費(fèi)者端手動提交:如果先消費(fèi)消息趣避,再更新offset位置庞呕,導(dǎo)致消息重復(fù)消費(fèi)。

(3)消費(fèi)者端自動提交:設(shè)置offset為自動提交程帕,關(guān)閉kafka時住练,如果在close之前,調(diào)用 consumer.unsubscribe() 則有可能部分offset沒提交愁拭,下次重啟會重復(fù)消費(fèi)讲逛。

(4)生產(chǎn)者端:生產(chǎn)者因?yàn)闃I(yè)務(wù)問題導(dǎo)致的宕機(jī),在重啟之后可能數(shù)據(jù)會重發(fā)岭埠。

7.造成消息漏消費(fèi)的場景

(1)自動提交:設(shè)置offset為自動定時提交盏混,當(dāng)offset被自動定時提交時,數(shù)據(jù)還在內(nèi)存中未處理惜论,此時剛好把線程kill掉许赃,那么offset已經(jīng)提交,但是數(shù)據(jù)未處理馆类,導(dǎo)致這部分內(nèi)存中的數(shù)據(jù)丟失混聊。

(2)生產(chǎn)者端:發(fā)送消息設(shè)置的是fire-and-forget(發(fā)后即忘),它只管往 Kafka 中發(fā)送消息而并不關(guān)心消息是否正確到達(dá)蹦掐。不過在某些時候(比如發(fā)生不可重試異常時)會造成消息的丟失技羔。這種發(fā)送方式的性能最高,可靠性也最差卧抗。

(3)消費(fèi)者端:先提交位移藤滥,但是消息還沒消費(fèi)完就宕機(jī)了,造成了消息沒有被消費(fèi)社裆。自動位移提交同理acks沒有設(shè)置為all拙绊。如果在broker還沒把消息同步到其他broker的時候宕機(jī)了,那么消息將會丟失泳秀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末标沪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嗜傅,更是在濱河造成了極大的恐慌金句,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吕嘀,死亡現(xiàn)場離奇詭異违寞,居然都是意外死亡贞瞒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門趁曼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來军浆,“玉大人,你說我怎么就攤上這事挡闰∑谷冢” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵摄悯,是天一觀的道長。 經(jīng)常有香客問我射众,道長碟摆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任叨橱,我火速辦了婚禮,結(jié)果婚禮上断盛,老公的妹妹穿的比我還像新娘罗洗。我一直安慰自己,他們只是感情好钢猛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布伙菜。 她就那樣靜靜地躺著,像睡著了一般命迈。 火紅的嫁衣襯著肌膚如雪贩绕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天壶愤,我揣著相機(jī)與錄音淑倾,去河邊找鬼。 笑死征椒,一個胖子當(dāng)著我的面吹牛娇哆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播勃救,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼碍讨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蒙秒?” 一聲冷哼從身側(cè)響起勃黍,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晕讲,沒想到半個月后覆获,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體马澈,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年锻梳,在試婚紗的時候發(fā)現(xiàn)自己被綠了箭券。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡疑枯,死狀恐怖辩块,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荆永,我是刑警寧澤废亭,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站具钥,受9級特大地震影響豆村,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骂删,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一掌动、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宁玫,春花似錦粗恢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至佛掖,卻和暖如春妖碉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芥被。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工欧宜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人撕彤。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓鱼鸠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親羹铅。 傳聞我的和親對象是個殘疾皇子蚀狰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355