kafka原理學(xué)習(xí)筆記

一横堡、kafka簡(jiǎn)介

kafka是分布式消息隊(duì)列,具有高性能冠桃、持久化命贴、多副本備份、橫向擴(kuò)展能力食听,其最大的特性是高吞吐量胸蛛、低延遲,可以幾乎實(shí)時(shí)的處理大量數(shù)據(jù)樱报。這和其文件存儲(chǔ)機(jī)制的設(shè)計(jì)有關(guān)葬项,簡(jiǎn)單來說寫入時(shí)為順序?qū)懭耄矣蠱MFile的機(jī)制迹蛤,而在檢索時(shí)玷室,也做了分段和稀疏索引。同時(shí)笤受,在整體架構(gòu)上穷缤,對(duì)于同一個(gè)topic中的消息會(huì)均勻的分布在不同的partition上,也使得分布式消費(fèi)成為可能箩兽。

二津肛、鳥瞰kafka

kafka overview.jpg

總體來講,kafka的數(shù)據(jù)流向如上圖所示汗贫,簡(jiǎn)單描述流程大概是:
2.1 producer往topic上寫消息身坐,此時(shí)kafka會(huì)均勻的把message分布在不同的partition上(發(fā)送時(shí)不需要指定partition,kafka會(huì)自動(dòng)的loan balance)落包,同時(shí)寫入時(shí)只寫入到了leader上
2.2 leader發(fā)送給其他的follower
2.3 各個(gè)consumer線程可以組成一個(gè)consumer group部蛇,每個(gè)consumer group 均可以從頭開始消費(fèi)一個(gè)topic下的各個(gè)partition,即同一個(gè)topic的message咐蝇,允許多個(gè)consumer group進(jìn)行消費(fèi)
2.4 在某一個(gè)consumer group 進(jìn)行消費(fèi)時(shí)涯鲁,partition中每一條message只能被其中的一個(gè)consumer線程消費(fèi)
2.5 消費(fèi)時(shí)可是從leader進(jìn)行的消費(fèi)
2.6 Consumer處理partition里面的message的時(shí)候是順序讀取的。所以必須維護(hù)著上一次讀到哪里的offsite信息
2.7 broker有序、topics抹腿、partitions的一些元信息用zk來存,監(jiān)控和路由啥的也都會(huì)用到zk

好了旭寿,到這里一定會(huì)產(chǎn)生一些疑問警绩,比如:
1.partition是干嘛的?
2.為什么不同的consumer group 可以同時(shí)消費(fèi)同一個(gè)topic盅称?如何確保消費(fèi)順序肩祥?
3.leader 和 follower的設(shè)計(jì)是有什么用后室?
4.消息的可靠性?
5.為什么說kafka的性能很好混狠,讀寫很快岸霹?

一個(gè)個(gè)來看。

三檀蹋、Topic & partition

Topic相當(dāng)于傳統(tǒng)消息系統(tǒng)MQ中的一個(gè)隊(duì)列queue,producer端發(fā)送的message必須指定是發(fā)送到哪個(gè)topic云芦,但是不需要指定topic下的哪個(gè)partition俯逾,因?yàn)閗afka會(huì)把收到的message進(jìn)行l(wèi)oad balance,均勻的分布在這個(gè)topic下的不同的partition上( hash(message) % [broker數(shù)量] )舅逸。物理上存儲(chǔ)上桌肴,這個(gè)topic會(huì)分成一個(gè)或多個(gè)partition,每個(gè)partiton相當(dāng)于是一個(gè)子queue琉历。在物理結(jié)構(gòu)上坠七,每個(gè)partition對(duì)應(yīng)一個(gè)物理的目錄(文件夾),文件夾命名是[topicname][partition][序號(hào)]旗笔,一個(gè)topic可以有無數(shù)多的partition彪置,根據(jù)業(yè)務(wù)需求和數(shù)據(jù)量來設(shè)置。在kafka配置文件中可隨時(shí)更高num.partitions參數(shù)來配置更改topic的partition數(shù)量蝇恶,在創(chuàng)建Topic時(shí)通過參數(shù)指定parittion數(shù)量拳魁。Topic創(chuàng)建之后通過Kafka提供的工具也可以修改partiton數(shù)量。

一般來說撮弧,(1)一個(gè)Topic的Partition數(shù)量大于等于Broker的數(shù)量潘懊,可以提高吞吐率。(2)同一個(gè)Partition的Replica盡量分散到不同的機(jī)器贿衍,高可用授舟。

當(dāng)add a new partition的時(shí)候,partition里面的message不會(huì)重新進(jìn)行分配贸辈,原來的partition里面的message數(shù)據(jù)不會(huì)變释树,新加的這個(gè)partition剛開始是空的,隨后進(jìn)入這個(gè)topic的message就會(huì)重新參與所有partition的load balance擎淤。

四躏哩、消息寫入及順序消費(fèi)

kafka中的Message是以topic為基本單位組織的,不同的topic之間是相互獨(dú)立的揉燃。每個(gè)topic又可以分成幾個(gè)不同的partition(每個(gè)topic有幾個(gè)partition是在創(chuàng)建topic時(shí)指定的)扫尺,每個(gè)partition存儲(chǔ)一部分Message。

另外炊汤,因?yàn)橛脖P是機(jī)械結(jié)構(gòu)正驻,每次讀寫都會(huì)尋址->寫入弊攘,其中尋址是一個(gè)“機(jī)械動(dòng)作”,它是最耗時(shí)的姑曙。所以硬盤最討厭隨機(jī)I/O襟交,最喜歡順序I/O。為了提高讀寫硬盤的速度伤靠,kafka就是使用順序I/O捣域。

也就是說,當(dāng)有消息寫入時(shí)宴合,實(shí)際的寫入會(huì)類似下圖所示

kafka數(shù)據(jù)寫入圖.jpg

可以看到焕梅,message在partition中是順序存儲(chǔ)的,這種方式有一個(gè)很明顯的缺陷——沒有辦法刪除數(shù)據(jù)卦洽,所以kafka是不會(huì)刪除數(shù)據(jù)的贞言,它會(huì)把所有的數(shù)據(jù)都保留下來。所以消費(fèi)時(shí)需要consumer通過offset來標(biāo)記消費(fèi)到了那一條數(shù)據(jù)阀蒂,通過的consumer group中的consumer消費(fèi)的offset可能不一樣该窗,如下圖所示


kafka消費(fèi).png

五、leader選舉機(jī)制

從前文的鳥瞰圖我們可以知道蚤霞,kafka的每個(gè)partition可以在其他的kafka broker節(jié)點(diǎn)上存副本酗失,即對(duì)于同一個(gè)partition可以有一個(gè)leader多個(gè)follower,這是為了確保當(dāng)某個(gè)broker宕機(jī)的時(shí)候不會(huì)影響這個(gè)kafka集群昧绣,如果是leader所在的broker宕機(jī)了级零,也會(huì)有新的follower站出來成為leader,也就是leader的重新選舉機(jī)制滞乙。那kafka是如何進(jìn)行l(wèi)eader的重新選舉的呢奏纪?

1.kafka會(huì)在所有的broker中選出一個(gè)controller,所有partition的leader選舉都由controller決定斩启,controller在zk注冊(cè)Watch序调,一旦有broker宕機(jī),其在zk對(duì)應(yīng)的znode會(huì)自動(dòng)被刪除兔簇,zk會(huì)fire controller注冊(cè)的watch

2.此時(shí)controller會(huì)去重新讀取一遍最新的幸存的broker发绢,并決定partition集合(set_p),這個(gè)集合包含了宕機(jī)的broker上所有的partition

3.對(duì)于集合中的每個(gè)partition垄琐,controller會(huì)去讀取該partition的ISR(副本同步隊(duì)列)边酒,如果當(dāng)前ISR中有至少一個(gè)replica(副本)還幸存,則選擇其中一個(gè)作為新leader狸窘,新的ISR則包含當(dāng)前ISR中所有幸存的replica(選舉算法的實(shí)現(xiàn)類似于微軟的PacificA)墩朦。如果該partition的所有replica都宕機(jī)了,則將新的leader設(shè)置為-1翻擒。

4.將新的leader氓涣,ISR和新的leader_epoch及controller_epoch寫入/brokers/topics/[topic]/partitions/[partition]/state牛哺。

5.直接通過RPC向set_p相關(guān)的broker發(fā)送LeaderAndISRRequest命令。

如下圖所示


kafka leader選舉機(jī)制.jpg

從前文的鳥瞰圖我們可以知道劳吠,producer發(fā)送消息時(shí)是先寫到leader上引润,再由leader同步到follower,如果寫到leader后還沒同步時(shí)正好broker宕機(jī)了痒玩,此時(shí)重新選舉后follower充當(dāng)新的leader淳附,則剛剛那條消息的數(shù)據(jù)就丟失了,也就是說kafka在一些少量場(chǎng)景下存在丟失數(shù)據(jù)的可能(消息隊(duì)列消費(fèi)時(shí)也同樣存在丟失數(shù)據(jù)或者重復(fù)消費(fèi)的場(chǎng)景)蠢古,接下來就來看下kafka在消息可靠性上的設(shè)置

六奴曙、消息的可靠性

6.1生產(chǎn)者生產(chǎn)消息的可靠性

消息投遞可靠性.jpg

6.2消費(fèi)者消費(fèi)時(shí)可能存在的異常場(chǎng)景

6.2.1 consumer的delivery gurarantee,默認(rèn)是讀完message先commmit再處理message便瑟,autocommit默認(rèn)是true缆毁,這時(shí)候先commit就會(huì)更新offsite+1番川,一旦處理失敗到涂,offsite已經(jīng)+1,這個(gè)時(shí)候就會(huì)丟message

6.2.2 如前文所述颁督,同一個(gè)topic支持被不同的consumer group消費(fèi)践啄,如果同樣的業(yè)務(wù)存在兩個(gè)consumer group(一般不會(huì)這樣),在消息消費(fèi)時(shí)就需要考慮重復(fù)消費(fèi)的場(chǎng)景

6.3由于MMFile導(dǎo)致的消息丟失

kafka為了像操作內(nèi)存一樣寫入數(shù)據(jù)沉御,在寫入數(shù)據(jù)時(shí)屿讽,除了前文提到的順序?qū)懭胪猓矔?huì)有內(nèi)存映射文件(Memory Mapped Files ,MMFile)這樣的機(jī)制吠裆,它的工作原理是直接利用操作系統(tǒng)的Page來實(shí)現(xiàn)文件到物理內(nèi)存的直接映射伐谈。完成映射之后你對(duì)物理內(nèi)存的操作會(huì)被同步到硬盤上,如果在完成同步之前试疙,服務(wù)器宕機(jī)了诵棵,則也會(huì)丟失一部分?jǐn)?shù)據(jù)。

七祝旷、kafka如何做到快速寫入和讀取的

7.1 快速寫入

關(guān)于寫入的部分前文已經(jīng)提到履澳,主要是依靠順序?qū)懭氡苊饬俗詈臅r(shí)的機(jī)械動(dòng)作——尋址,以及上面剛剛提到的MMFile機(jī)制可以使kafka如同操作內(nèi)存一樣的寫入怀跛。

7.2 快速讀取

7.2.1 parition數(shù)據(jù)文件

為了弄明白kafka如何做到快速讀取某一條消息的距贷,首先要看一下partition文件的結(jié)構(gòu)。

kafka文件存儲(chǔ)方式.jpg

partition是以文件的形式存儲(chǔ)在文件系統(tǒng)中吻谋。

Partition中的每條Message由offset來表示它在這個(gè)partition中的偏移量忠蝗,這個(gè)offset不是該Message在partition數(shù)據(jù)文件中的實(shí)際存儲(chǔ)位置,而是邏輯上一個(gè)值漓拾,它唯一確定了partition中的一條Message什湘。因此长赞,可以認(rèn)為offset是partition中Message的id。partition中的每條Message包含了以下三個(gè)屬性:

offset
MessageSize
data

其中offset為long型闽撤,MessageSize為int32得哆,表示data有多大,data為message的具體內(nèi)容

7.2.2 分段

由于consumer消費(fèi)消息時(shí)一定是根據(jù)偏移量(offset)順序消費(fèi)的哟旗,弄清楚了partition文件的結(jié)構(gòu)后贩据,所以很容易想到kafka解決查詢效率的手段之一是將數(shù)據(jù)文件分段。

比如有100條Message闸餐,它們的offset是從0到99饱亮。假設(shè)將數(shù)據(jù)文件分成5段,第一段為0-19舍沙,第二段為20-39近上,以此類推,每段放在一個(gè)單獨(dú)的數(shù)據(jù)文件里面拂铡,數(shù)據(jù)文件以該段中最小的offset命名壹无。這樣在查找指定offset的Message的時(shí)候,用二分查找就可以定位到該Message在哪個(gè)段中感帅。

7.2.3 索引

數(shù)據(jù)文件分段使得可以在一個(gè)較小的數(shù)據(jù)文件中查找對(duì)應(yīng)offset的message了斗锭,但是這依然需要順序掃描才能找到對(duì)應(yīng)offset的message。為了進(jìn)一步提高查找的效率失球,kafka為每個(gè)分段后的數(shù)據(jù)文件建立了索引文件殷绍。

索引包含兩個(gè)部分(均為4個(gè)字節(jié)的數(shù)字)胶征,分別為相對(duì)offset和position。

相對(duì)offset:因?yàn)閿?shù)據(jù)文件分段以后,每個(gè)數(shù)據(jù)文件的起始o(jì)ffset不為0看锉,相對(duì)offset表示這條message相對(duì)于其所屬分段的數(shù)據(jù)文件中最小的offset的大小该互。舉例斗蒋,分段后的一個(gè)數(shù)據(jù)文件的offset是從20開始临梗,那么offset為25的message在index文件中的相對(duì)offset就是25-20 = 5。

position:表示該條message在數(shù)據(jù)文件中的絕對(duì)位置荧止。只要打開文件并移動(dòng)文件指針到這個(gè)position就可以讀取對(duì)應(yīng)的message了屹电。

值得一提的是,index文件中并沒有為數(shù)據(jù)文件中的每條message建立索引跃巡,而是采用了稀疏存儲(chǔ)的方式危号,每隔一定字節(jié)的數(shù)據(jù)建立一條索引。這樣避免了索引文件占用過多的空間素邪,從而可以將索引文件保留在內(nèi)存中外莲。但缺點(diǎn)是沒有建立索引的message也不能一次定位到其在數(shù)據(jù)文件的位置,從而需要做一次順序掃描,但是這次順序掃描的范圍就很小了偷线。

八磨确、參考及引用的資料

8.1 Kafka史上最詳細(xì)原理總結(jié) ----看完絕對(duì)不后悔 https://blog.csdn.net/lingbo229/article/details/80761778

8.2 震驚了!原來這才是kafka声邦! http://www.reibang.com/p/d3e963ff8b70

8.3 kafka leader選舉機(jī)制原理 http://www.reibang.com/p/1f02328a4f2e

8.4 http://kafka.apache.org/documentation/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乏奥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子亥曹,更是在濱河造成了極大的恐慌邓了,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件媳瞪,死亡現(xiàn)場(chǎng)離奇詭異骗炉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蛇受,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門句葵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兢仰,你說我怎么就攤上這事乍丈。” “怎么了旨别?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵诗赌,是天一觀的道長(zhǎng)汗茄。 經(jīng)常有香客問我秸弛,道長(zhǎng),這世上最難降的妖魔是什么洪碳? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任递览,我火速辦了婚禮,結(jié)果婚禮上瞳腌,老公的妹妹穿的比我還像新娘绞铃。我一直安慰自己,他們只是感情好嫂侍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布儿捧。 她就那樣靜靜地躺著,像睡著了一般挑宠。 火紅的嫁衣襯著肌膚如雪菲盾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天各淀,我揣著相機(jī)與錄音懒鉴,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛临谱,可吹牛的內(nèi)容都是我干的璃俗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼悉默,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼城豁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抄课,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤钮蛛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后剖膳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魏颓,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年吱晒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了甸饱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡仑濒,死狀恐怖叹话,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情墩瞳,我是刑警寧澤驼壶,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站喉酌,受9級(jí)特大地震影響热凹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泪电,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一般妙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧相速,春花似錦碟渺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至旺隙,卻和暖如春绒极,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背催束。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工集峦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓塔淤,卻偏偏與公主長(zhǎng)得像摘昌,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子高蜂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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