Kafka的原理介绍及实践
一.官方定義
?
根據(jù)官網(wǎng)的介紹,kafka是一個(gè)提供統(tǒng)一的、高吞吐、低延遲的,用來處理實(shí)時(shí)數(shù)據(jù)的流式平臺(tái),它具備以下三特性:
?
kafka一般用在兩大類應(yīng)用中:
?
在郵箱服務(wù)中,我們主要將kafka作為消息系統(tǒng),用于系統(tǒng)內(nèi)部消息的傳輸。為什么要采用kafka呢?讓我們先從kafka的設(shè)計(jì)原理說起。
?
概念與存儲(chǔ)機(jī)制
?
kafka中是以Topic機(jī)制來對(duì)消息進(jìn)行分類的,同一類消息屬于同一個(gè)Topic,你可以將每個(gè)Topic看成是一個(gè)消息隊(duì)列。生產(chǎn)者將消息發(fā)送到相應(yīng)的Topic,而消費(fèi)者通過從Topic拉取消息來消費(fèi),沒錯(cuò),在kafka中是要求消費(fèi)者主動(dòng)拉取消息消費(fèi)的,它并不會(huì)主動(dòng)推送消息,這是它的一個(gè)特點(diǎn),為什么會(huì)這樣設(shè)計(jì)呢?我們后面再說,先來看一下Topic的結(jié)構(gòu):
?
Partition分區(qū),每個(gè)topic可以有多個(gè)分區(qū),這是kafka為了提高并發(fā)量而設(shè)計(jì)的一種機(jī)制:一個(gè)topic下的多個(gè)分區(qū)可以并發(fā)接收消息,同樣的也能供消費(fèi)者并發(fā)拉取消息,即分區(qū)之間互不干擾,這樣的話,有多少個(gè)分區(qū)就可以有多大的并發(fā)量。所以,如果要更準(zhǔn)確的打比方,一個(gè)分區(qū)就是一個(gè)消息隊(duì)列,只不過這些消息隊(duì)列同屬于一種消息分類。
?
在kafka服務(wù)器,分區(qū)是以目錄形式存在的,每個(gè)分區(qū)目錄中,kafka會(huì)按配置大小或配置周期將分區(qū)拆分成多個(gè)段文件(LogSegment), 每個(gè)段由三部分組成:
其中*.log用于存儲(chǔ)消息本身的數(shù)據(jù)內(nèi)容,*.index存儲(chǔ)消息在文件中的位置(包括消息的邏輯offset和物理存儲(chǔ)offset),*.timeindex存儲(chǔ)消息創(chuàng)建時(shí)間和對(duì)應(yīng)邏輯地址的映射關(guān)系。
?
段文件結(jié)構(gòu)圖如下 :
將分區(qū)拆分成多個(gè)段是為了控制存儲(chǔ)的文件大小,如果整個(gè)分區(qū)只保存為一個(gè)文件,那隨著分區(qū)里消息的增多,文件也將越來越大,最后不可控制。而如果每個(gè)消息都保存為一個(gè)文件,那文件數(shù)量又將變得巨大,同樣容易失去控制。所以kafka采用段這種方式,控制了每個(gè)文件的大小,也方便控制所有文件的數(shù)量。同時(shí),這些文件因?yàn)榇笮∵m中,可以很方便地通過操作系統(tǒng)mmap機(jī)制映射到內(nèi)存中,提高寫入和讀取效率。這個(gè)設(shè)計(jì)的另一個(gè)好處是:當(dāng)系統(tǒng)要清除過期數(shù)據(jù)時(shí),可以直接將過期的段文件刪除,非常簡(jiǎn)潔。
?
但是這里也會(huì)有一個(gè)問題:如果每個(gè)消息都要在index文件中保存位置信息,那么index文件也很容易變得很大,這樣又會(huì)減弱上文所說的好處。所以在kafka中,index設(shè)計(jì)為稀疏索引來降低index的文件大小,這樣,index文件存儲(chǔ)的實(shí)際內(nèi)容為:該段消息在消息隊(duì)列中的相對(duì)offset和在log文件中的物理偏移量映射的稀疏記錄。
 ?
那么多少條消息會(huì)在index中保存一條記錄呢?這個(gè)可以通過系統(tǒng)配置來進(jìn)行設(shè)置。索引記錄固定為8個(gè)字節(jié)大小,分別為4個(gè)字節(jié)的相對(duì)offset(消息在partition中全局offset減去該segment的起始o(jì)ffset),4個(gè)字節(jié)的消息具體存儲(chǔ)文件的物理偏移量。
?
index文件結(jié)構(gòu)圖如下:
Kafka不會(huì)在消費(fèi)者拉取完消息后馬上就清理消息,而是會(huì)保存段文件一段時(shí)間,直到其過期再標(biāo)記為可清理,由后臺(tái)程序定期進(jìn)行清理。這種機(jī)制使得消費(fèi)者可以重復(fù)消費(fèi)消息,滿足更靈活的需求。
?
查詢機(jī)制
?
上面說過,kafka雖然作為消息系統(tǒng),但是消費(fèi)消息并不是通過推送而是通過拉取來消費(fèi)的,client需要通過offset和size參數(shù)主動(dòng)去查詢消息。
 ?
kafka收到客戶端請(qǐng)求后,對(duì)消息的尋址會(huì)經(jīng)過下面幾個(gè)步驟:
?
kafka讀取示意圖:
?
二、RabbitMQ vs kafka
?
介紹了kafka的實(shí)現(xiàn)原理,我們?cè)賮韺?duì)比一下同樣作為消息隊(duì)列服務(wù)的RabbitMQ。MQ的應(yīng)用也很廣泛,功能多而全,那么和MQ相比,kafka有哪些優(yōu)勢(shì)呢?為什么我們會(huì)使用kafka而拋棄了RabbitMQ呢?
?
RabbitMQ流程圖:
RabbitMQ消費(fèi)者只能從隊(duì)列頭部按序進(jìn)行消費(fèi),消息一旦被消費(fèi),就會(huì)被打上刪除標(biāo)記,緊接著消費(fèi)下一條消息,沒辦法進(jìn)行回溯操作,這樣的話一個(gè)消費(fèi)者消費(fèi)完消息,另一個(gè)消費(fèi)者就別想再消費(fèi)了。而Kafka提供動(dòng)態(tài)指定消費(fèi)位點(diǎn),能夠靈活地進(jìn)行回溯消費(fèi)操作,只要該消息還在生命周期內(nèi)可以重復(fù)拉取,并且不同消費(fèi)者可以互不干擾的消費(fèi)同一個(gè)消息隊(duì)列,這就比RabbitMQ靈活多了。
?
kafka消費(fèi)位點(diǎn)示意圖:
RabbitMQ如果要滿足多個(gè)消費(fèi)者消費(fèi)同一個(gè)消息隊(duì)列,也可以借助exchange路由能力,但是這樣會(huì)將消息復(fù)制到多個(gè)隊(duì)列,每個(gè)消費(fèi)者需要綁定一個(gè)自己的隊(duì)列進(jìn)行消費(fèi)。如果有幾百個(gè)消費(fèi)者,那么隊(duì)列復(fù)制幾百倍,引起mq的消息水位猛漲,容易失控。而kafka就沒這個(gè)問題,不管多少個(gè)消費(fèi)者都只需要一個(gè)隊(duì)列就能滿足,每個(gè)消費(fèi)者都可以完整地不相互干擾地消費(fèi)隊(duì)列中的所有消息。
?
當(dāng)然,RabbitMQ也有其優(yōu)點(diǎn),它提供的exchange,binding, queue等抽象實(shí)體,提供強(qiáng)大的路由關(guān)系(rounte key and bindkey)和消息過濾能力。作為傳統(tǒng)消息系統(tǒng)提供了細(xì)粒度的消息控制能力。而Kafka主要是面向高流量,大吞吐的批處理系統(tǒng),在路由抽象方面化繁為簡(jiǎn),重點(diǎn)關(guān)注系統(tǒng)的高吞吐,所以使用上更為簡(jiǎn)潔。
?
kafka還有傳統(tǒng)解決方案無法滿足的高伸縮能力等優(yōu)勢(shì),這里就不一一介紹了。
?
三、Kafka在郵件系統(tǒng)data bus中的運(yùn)用
?
正因?yàn)閗afka有著以上介紹的能力和優(yōu)勢(shì),我們的郵箱服務(wù)中采用了它作為消息系統(tǒng),其中一個(gè)應(yīng)用就是郵件系統(tǒng)的data bus。
?
?data bus介紹?
郵件系統(tǒng)用戶收發(fā)信流程伴隨著大量的業(yè)務(wù)邏輯和子系統(tǒng)調(diào)用,如果將這些流程都強(qiáng)依附在主干枝上,將會(huì)對(duì)系統(tǒng)造成較大的壓力,整個(gè)業(yè)務(wù)流程也將變得復(fù)雜而緩慢。所以通過數(shù)據(jù)總線將主次流程進(jìn)行解耦,減輕收發(fā)信主流程的復(fù)雜度,使其可以以更快的速度完成,加快系統(tǒng)響應(yīng)時(shí)間。主流程產(chǎn)生事件源,通過kafka的傳輸,觸發(fā)多個(gè)次要流程,次要流程可以并發(fā)在系統(tǒng)后臺(tái)完成,并且可以輕易的擴(kuò)展多種多樣的次要流程。
?
下圖以簡(jiǎn)化后的信流程為例:
?Kafka在data bus中的運(yùn)用?
郵件系統(tǒng)在完成收發(fā)信流程后,會(huì)生成當(dāng)次流程相關(guān)的系統(tǒng)事件,比如新郵件事件。data bus將這些事件寫入到kafka集群的相應(yīng)topic中,下游的一系列子系統(tǒng)對(duì)topic進(jìn)行消費(fèi)。
?
?
如下圖所示,應(yīng)用消費(fèi)能力能借助Kafka集群實(shí)現(xiàn)彈性擴(kuò)容
?
總? ? 結(jié)
?
kafka在郵件系統(tǒng)中的應(yīng)用給我們帶來的好處:
- 時(shí)延敏感型業(yè)務(wù):通過提高業(yè)務(wù)Topic的Partition數(shù)量,一來留下了較好的機(jī)器擴(kuò)容的空間,另一方面也可以通過提高消費(fèi)者并發(fā)線程數(shù)來提升應(yīng)用整體消費(fèi)速度,減少時(shí)延。
?
- 慢速型業(yè)務(wù):有些不關(guān)心時(shí)效性的下游業(yè)務(wù),在考慮消息生命周期等因素,可以很好地利用Kafka的消息堆積能力,磁盤存儲(chǔ)能力,削峰填谷,讓消費(fèi)流速適應(yīng)自己的處理能力,不至于因?yàn)橥蝗婚g的大量消息沖擊而崩潰。
?
總結(jié)
以上是生活随笔為你收集整理的Kafka的原理介绍及实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 链路追踪技术的应用及实践
- 下一篇: 技术系列课|音视频测试实战——记音视频测
