一文五分鐘讓你徹底理解Kafka架構(gòu)原理

對(duì)于kafka的架構(gòu)原理我們先提出幾個(gè)問(wèn)題?

1.Kafka的topic和分區(qū)內(nèi)部是如何存儲(chǔ)的壤蚜,有什么特點(diǎn)蘑拯?

2.與傳統(tǒng)的消息系統(tǒng)相比,Kafka的消費(fèi)模型有什么優(yōu)點(diǎn)?

3.Kafka如何實(shí)現(xiàn)分布式的數(shù)據(jù)存儲(chǔ)與數(shù)據(jù)讀取?

一枯怖、Kafka架構(gòu)圖

1.kafka名詞解釋

在一套kafka架構(gòu)中有多個(gè)Producer唐片,多個(gè)Broker,多個(gè)Consumer厚柳,每個(gè)Producer可以對(duì)應(yīng)多個(gè)Topic抛寝,每個(gè)Consumer只能對(duì)應(yīng)一個(gè)ConsumerGroup熊杨。

整個(gè)Kafka架構(gòu)對(duì)應(yīng)一個(gè)ZK集群,通過(guò)ZK管理集群配置盗舰,選舉Leader晶府,以及在consumer group發(fā)生變化時(shí)進(jìn)行rebalance。

名稱(chēng)

解釋

Broker

消息中間件處理節(jié)點(diǎn)岭皂,一個(gè)Kafka節(jié)點(diǎn)就是一個(gè)broker郊霎,一個(gè)或者多個(gè)Broker可以組成一個(gè)Kafka集群

Topic

主題,Kafka根據(jù)topic對(duì)消息進(jìn)行歸類(lèi)爷绘,發(fā)布到Kafka集群的每條消息都需要指定一個(gè)topic

Producer

消息生產(chǎn)者书劝,向Broker發(fā)送消息的客戶端

Consumer

消息消費(fèi)者进倍,從Broker讀取消息的客戶端

ConsumerGroup

每個(gè)Consumer屬于一個(gè)特定的Consumer Group,一條消息可以發(fā)送到多個(gè)不同的Consumer Group购对,但是一個(gè)Consumer Group中只能有一個(gè)Consumer能夠消費(fèi)該消息

Partition

物理上的概念猾昆,一個(gè)topic可以分為多個(gè)partition,每個(gè)partition內(nèi)部是有序的

2.Topic和Partition

在Kafka中的每一條消息都有一個(gè)topic骡苞。一般來(lái)說(shuō)在我們應(yīng)用中產(chǎn)生不同類(lèi)型的數(shù)據(jù)垂蜗,都可以設(shè)置不同的主題。一個(gè)主題一般會(huì)有多個(gè)消息的訂閱者解幽,當(dāng)生產(chǎn)者發(fā)布消息到某個(gè)主題時(shí)贴见,訂閱了這個(gè)主題的消費(fèi)者都可以接收到生產(chǎn)者寫(xiě)入的新消息。

kafka為每個(gè)主題維護(hù)了分布式的分區(qū)(partition)日志文件躲株,每個(gè)partition在kafka存儲(chǔ)層面是append log片部。任何發(fā)布到此partition的消息都會(huì)被追加到log文件的尾部,在分區(qū)中的每條消息都會(huì)按照時(shí)間順序分配到一個(gè)單調(diào)遞增的順序編號(hào)霜定,也就是我們的offset,offset是一個(gè)long型的數(shù)字档悠,我們通過(guò)這個(gè)offset可以確定一條在該partition下的唯一消息。在partition下面是保證了有序性望浩,但是在topic下面沒(méi)有保證有序性辖所。

在上圖中在我們的生產(chǎn)者會(huì)決定發(fā)送到哪個(gè)Partition。

1.如果沒(méi)有Key值則進(jìn)行輪詢發(fā)送磨德。

2.如果有Key值缘回,對(duì)Key值進(jìn)行Hash,然后對(duì)分區(qū)數(shù)量取余剖张,保證了同一個(gè)Key值的會(huì)被路由到同一個(gè)分區(qū)切诀,如果想隊(duì)列的強(qiáng)順序一致性,可以讓所有的消息都設(shè)置為同一個(gè)Key搔弄。

3.消費(fèi)模型

消息由生產(chǎn)者發(fā)送到kafka集群后幅虑,會(huì)被消費(fèi)者消費(fèi)。一般來(lái)說(shuō)我們的消費(fèi)模型有兩種:推送模型(psuh)和拉取模型(pull)

基于推送模型的消息系統(tǒng)顾犹,由消息代理記錄消費(fèi)狀態(tài)倒庵。消息代理將消息推送到消費(fèi)者后,標(biāo)記這條消息為已經(jīng)被消費(fèi)炫刷,但是這種方式無(wú)法很好地保證消費(fèi)的處理語(yǔ)義擎宝。比如當(dāng)我們把已經(jīng)把消息發(fā)送給消費(fèi)者之后,由于消費(fèi)進(jìn)程掛掉或者由于網(wǎng)絡(luò)原因沒(méi)有收到這條消息浑玛,如果我們?cè)谙M(fèi)代理將其標(biāo)記為已消費(fèi)绍申,這個(gè)消息就永久丟失了。如果我們利用生產(chǎn)者收到消息后回復(fù)這種方法,消息代理需要記錄消費(fèi)狀態(tài)极阅,這種不可取胃碾。如果采用push,消息消費(fèi)的速率就完全由消費(fèi)代理控制筋搏,一旦消費(fèi)者發(fā)生阻塞仆百,就會(huì)出現(xiàn)問(wèn)題。

Kafka采取拉取模型(poll)奔脐,由自己控制消費(fèi)速度俄周,以及消費(fèi)的進(jìn)度,消費(fèi)者可以按照任意的偏移量進(jìn)行消費(fèi)髓迎。比如消費(fèi)者可以消費(fèi)已經(jīng)消費(fèi)過(guò)的消息進(jìn)行重新處理峦朗,或者消費(fèi)最近的消息等等。

4.網(wǎng)絡(luò)模型

4.1 KafkaClient --單線程Selector

單線程模式適用于并發(fā)鏈接數(shù)小竖般,邏輯簡(jiǎn)單甚垦,數(shù)據(jù)量小茶鹃。

在kafka中涣雕,consumer和producer都是使用的上面的單線程模式。這種模式不適合kafka的服務(wù)端闭翩,在服務(wù)端中請(qǐng)求處理過(guò)程比較復(fù)雜挣郭,會(huì)造成線程阻塞,一旦出現(xiàn)后續(xù)請(qǐng)求就會(huì)無(wú)法處理疗韵,會(huì)造成大量請(qǐng)求超時(shí)兑障,引起雪崩。而在服務(wù)器中應(yīng)該充分利用多線程來(lái)處理執(zhí)行邏輯蕉汪。

4.2 Kafka--server -- 多線程Selector

在kafka服務(wù)端采用的是多線程的Selector模型流译,Acceptor運(yùn)行在一個(gè)單獨(dú)的線程中,對(duì)于讀取操作的線程池中的線程都會(huì)在selector注冊(cè)read事件者疤,負(fù)責(zé)服務(wù)端讀取請(qǐng)求的邏輯福澡。成功讀取后,將請(qǐng)求放入message queue共享隊(duì)列中驹马。然后在寫(xiě)線程池中革砸,取出這個(gè)請(qǐng)求,對(duì)其進(jìn)行邏輯處理糯累,即使某個(gè)請(qǐng)求線程阻塞了算利,還有后續(xù)的縣城從消息隊(duì)列中獲取請(qǐng)求并進(jìn)行處理,在寫(xiě)線程中處理完邏輯處理泳姐,由于注冊(cè)了OP_WIRTE事件效拭,所以還需要對(duì)其發(fā)送響應(yīng)。

5.高可靠分布式存儲(chǔ)模型

在Kafka中保證高可靠模型的依靠的是副本機(jī)制,有了副本機(jī)制之后缎患,就算機(jī)器宕機(jī)也不會(huì)發(fā)生數(shù)據(jù)丟失借笙。

5.1高性能的日志存儲(chǔ)

kafka一個(gè)topic下面的所有消息都是以partition的方式分布式的存儲(chǔ)在多個(gè)節(jié)點(diǎn)上。同時(shí)在kafka的機(jī)器上较锡,每個(gè)Partition其實(shí)都會(huì)對(duì)應(yīng)一個(gè)日志目錄业稼,在目錄下面會(huì)對(duì)應(yīng)多個(gè)日志分段(LogSegment)。LogSegment文件由兩部分組成蚂蕴,分別為“.index”文件和“.log”文件低散,分別表示為segment索引文件和數(shù)據(jù)文件。這兩個(gè)文件的命令規(guī)則為:partition全局的第一個(gè)segment從0開(kāi)始骡楼,后續(xù)每個(gè)segment文件名為上一個(gè)segment文件最后一條消息的offset值熔号,數(shù)值大小為64位,20位數(shù)字字符長(zhǎng)度鸟整,沒(méi)有數(shù)字用0填充引镊,如下,假設(shè)有1000條消息篮条,每個(gè)LogSegment大小為100弟头,下面展現(xiàn)了900-1000的索引和Log:

由于kafka消息數(shù)據(jù)太大,如果全部建立索引涉茧,即占了空間又增加了耗時(shí)赴恨,所以kafka選擇了稀疏索引的方式,這樣的話索引可以直接進(jìn)入內(nèi)存伴栓,加快偏查詢速度伦连。

簡(jiǎn)單介紹一下如何讀取數(shù)據(jù),如果我們要讀取第911條數(shù)據(jù)首先第一步钳垮,找到他是屬于哪一段的惑淳,根據(jù)二分法查找到他屬于的文件,找到0000900.index和00000900.log之后饺窿,然后去index中去查找 (911-900) =11這個(gè)索引或者小于11最近的索引,在這里通過(guò)二分法我們找到了索引是[10,1367]然后我們通過(guò)這條索引的物理位置1367歧焦,開(kāi)始往后找,直到找到911條數(shù)據(jù)短荐。

上面講的是如果要找某個(gè)offset的流程倚舀,但是我們大多數(shù)時(shí)候并不需要查找某個(gè)offset,只需要按照順序讀即可,而在順序讀中忍宋,操作系統(tǒng)會(huì)對(duì)內(nèi)存和磁盤(pán)之間添加page cahe痕貌,也就是我們平常見(jiàn)到的預(yù)讀操作,所以我們的順序讀操作時(shí)速度很快糠排。但是kafka有個(gè)問(wèn)題舵稠,如果分區(qū)過(guò)多,那么日志分段也會(huì)很多,寫(xiě)的時(shí)候由于是批量寫(xiě)哺徊,其實(shí)就會(huì)變成隨機(jī)寫(xiě)了室琢,隨機(jī)I/O這個(gè)時(shí)候?qū)π阅苡绊懞艽蟆K砸话銇?lái)說(shuō)Kafka不能有太多的partition落追。針對(duì)這一點(diǎn)盈滴,RocketMQ把所有的日志都寫(xiě)在一個(gè)文件里面,就能變成順序?qū)懡文疲ㄟ^(guò)一定優(yōu)化巢钓,讀也能接近于順序讀。

可以思考一下:1.為什么需要分區(qū)疗垛,也就是說(shuō)主題只有一個(gè)分區(qū)症汹,難道不行嗎?2.日志為什么需要分段

5.2副本機(jī)制

Kafka的副本機(jī)制是多個(gè)服務(wù)端節(jié)點(diǎn)對(duì)其他節(jié)點(diǎn)的主題分區(qū)的日志進(jìn)行復(fù)制贷腕。當(dāng)集群中的某個(gè)節(jié)點(diǎn)出現(xiàn)故障背镇,訪問(wèn)故障節(jié)點(diǎn)的請(qǐng)求會(huì)被轉(zhuǎn)移到其他正常節(jié)點(diǎn)(這一過(guò)程通常叫Reblance),kafka每個(gè)主題的每個(gè)分區(qū)都有一個(gè)主副本以及0個(gè)或者多個(gè)副本,副本保持和主副本的數(shù)據(jù)同步泽裳,當(dāng)主副本出故障時(shí)就會(huì)被替代瞒斩。

在Kafka中并不是所有的副本都能被拿來(lái)替代主副本,所以在kafka的leader節(jié)點(diǎn)中維護(hù)著一個(gè)ISR(In sync Replicas)集合诡壁,翻譯過(guò)來(lái)也叫正在同步中集合济瓢,在這個(gè)集合中的需要滿足兩個(gè)條件:

節(jié)點(diǎn)必須和ZK保持連接

在同步的過(guò)程中這個(gè)副本不能落后主副本太多

另外還有個(gè)AR(Assigned Replicas)用來(lái)標(biāo)識(shí)副本的全集,OSR用來(lái)表示由于落后被剔除的副本集合,所以公式如下:ISR = leader + 沒(méi)有落后太多的副本; AR = OSR+ ISR;

這里先要說(shuō)下兩個(gè)名詞:HW(高水位)是consumer能夠看到的此partition的位置妹卿,LEO是每個(gè)partition的log最后一條Message的位置。HW能保證leader所在的broker失效蔑鹦,該消息仍然可以從新選舉的leader中獲取夺克,不會(huì)造成消息丟失。

當(dāng)producer向leader發(fā)送數(shù)據(jù)時(shí)嚎朽,可以通過(guò)request.required.acks參數(shù)來(lái)設(shè)置數(shù)據(jù)可靠性的級(jí)別:

1(默認(rèn)):這意味著producer在ISR中的leader已成功收到的數(shù)據(jù)并得到確認(rèn)后發(fā)送下一條message铺纽。如果leader宕機(jī)了,則會(huì)丟失數(shù)據(jù)哟忍。

0:這意味著producer無(wú)需等待來(lái)自broker的確認(rèn)而繼續(xù)發(fā)送下一批消息狡门。這種情況下數(shù)據(jù)傳輸效率最高,但是數(shù)據(jù)可靠性確是最低的锅很。

-1:producer需要等待ISR中的所有follower都確認(rèn)接收到數(shù)據(jù)后才算一次發(fā)送完成其馏,可靠性最高。但是這樣也不能保證數(shù)據(jù)不丟失爆安,比如當(dāng)ISR中只有l(wèi)eader時(shí)(其他節(jié)點(diǎn)都和zk斷開(kāi)連接叛复,或者都沒(méi)追上),這樣就變成了acks=1的情況。

以上就是我的分享褐奥,看完的朋友記得點(diǎn)贊噢咖耘!想學(xué)習(xí)更多的Java技術(shù)方面的知識(shí)的朋友們,可以進(jìn)我的Java高級(jí)架構(gòu)師交流群撬码,里面有高可用儿倒、高并發(fā)、高性能及分布式呜笑、Jvm性能調(diào)優(yōu)义桂、Spring源碼,MyBatis蹈垢,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個(gè)知識(shí)點(diǎn)的架構(gòu)資料慷吊,群號(hào):680075317,也可以進(jìn)群一起交流曹抬,比如遇到技術(shù)瓶頸溉瓶、面試不過(guò)的,大家一些交流學(xué)習(xí)谤民!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末堰酿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子张足,更是在濱河造成了極大的恐慌触创,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件为牍,死亡現(xiàn)場(chǎng)離奇詭異哼绑,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)碉咆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)抖韩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人疫铜,你說(shuō)我怎么就攤上這事茂浮。” “怎么了壳咕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵席揽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我谓厘,道長(zhǎng)幌羞,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任庞呕,我火速辦了婚禮新翎,結(jié)果婚禮上程帕,老公的妹妹穿的比我還像新娘。我一直安慰自己地啰,他們只是感情好愁拭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著亏吝,像睡著了一般岭埠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔚鸥,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天惜论,我揣著相機(jī)與錄音,去河邊找鬼止喷。 笑死馆类,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弹谁。 我是一名探鬼主播乾巧,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼预愤!你這毒婦竟也來(lái)了沟于?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤植康,失蹤者是張志新(化名)和其女友劉穎旷太,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體销睁,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡供璧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了榄攀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗜傅。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖檩赢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情违寞,我是刑警寧澤贞瞒,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站趁曼,受9級(jí)特大地震影響军浆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜挡闰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一乒融、第九天 我趴在偏房一處隱蔽的房頂上張望掰盘。 院中可真熱鬧,春花似錦赞季、人聲如沸愧捕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)次绘。三九已至,卻和暖如春撒遣,著一層夾襖步出監(jiān)牢的瞬間邮偎,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卿樱。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓阻逮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親膳凝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容