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