您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)如何深入分析Kafka架構(gòu)的工作流程、存儲機制、分區(qū)策略,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
在開始之前首先要明確一點,kafka是一個分布式流平臺,本質(zhì)上是一個消息隊列。談到消息隊列,就會聯(lián)想到消息隊列的三大作用:異步、消峰、解耦。kafka主要應(yīng)用在大數(shù)據(jù)的實時處理領(lǐng)域,使用起來比較簡單,本文主要分析kafka的工作流程、存儲機制,分區(qū)策略,并圍繞多個角度展開總結(jié)。
但是要注意的是,隨著時代的巨輪駛向2020,目前kafka已經(jīng)不是一家獨大了,Pulsar作為一個天生支持多租戶、跨地域復(fù)制、統(tǒng)一消息模型的消息平臺,已經(jīng)在不少企業(yè)成功的替代了Kafka。關(guān)于Apache Pulsar的更多知識,感興趣的可以關(guān)注我,后面會對它進(jìn)行總結(jié)和深入。
kafka將消息按照topic進(jìn)行分類,每條message由三個屬性組成。
offset:表示 message 在當(dāng)前 Partition 中的偏移量,是一個邏輯上的值,唯一確定了 Partition 中的一條 message,可以簡單的認(rèn)為是一個 id;
MessageSize:表示 message 內(nèi)容 data 的大??;
data:message 的具體內(nèi)容
在整個kafka架構(gòu)中,生產(chǎn)者和消費者采用發(fā)布和訂閱的模式,生產(chǎn)者生產(chǎn)消息,消費者消費消息,它倆各司其職,并且都是面向topic的。(需要注意:topic是邏輯上的概念,而partition是物理上的概念,每個partition對應(yīng)于一個log文件,該log文件中存儲的就是producer生產(chǎn)的數(shù)據(jù)。)
Producer生產(chǎn)的數(shù)據(jù)會被不斷追加到該log文件末端,且每條數(shù)據(jù)都有自己的offset。
消費者組中的每個消費者,都會實時記錄自己消費到了哪個offset,這樣當(dāng)出現(xiàn)故障并恢復(fù)后,可以從這個offset位置繼續(xù)進(jìn)行消費,避免漏掉數(shù)據(jù)或者重復(fù)消費。
在kafka的設(shè)計之初,考慮到了生產(chǎn)者生產(chǎn)的消息不斷追加到log文件末尾后導(dǎo)致log文件過大的情況,所以采用了分片和索引機制,具體來說就是將每個partition分為多個segment。每個segment對應(yīng)三個文件:.index 文件、.log 文件、.timeindex 文件(早期版本中沒有)。其中.log和.index文件位于一個文件夾下,該文件夾的命名規(guī)則為:topic名稱+分區(qū)序號。例如,csdn這個topic有2個分區(qū),則其對應(yīng)的文件夾為csdn-0,csdn-1;
如果我們打開csdn-0這個文件夾,會看到里面的文件如下:
00000000000000000000.index 00000000000000000000.log 00000000000000150320.index 00000000000000150320.log
通過這個文件夾下有兩個log,我們可以得出結(jié)論,這個partition有2個segment。
文件命名規(guī)則:partition全局的第一個segment從0開始,后續(xù)每個segment文件名為上一個segment文件最后一條消息的offset值,數(shù)值大小為64位,20位數(shù)字字符長度,沒有數(shù)字用0填充。
注意:index 文件并不是從0開始,也不是每次遞增1的,這是因為 Kafka 采取稀疏索引存儲的方式,每隔一定字節(jié)的數(shù)據(jù)建立一條索引,它減少了索引文件大小,使得能夠把 index 映射到內(nèi)存,降低了查詢時的磁盤 IO 開銷,同時也并沒有給查詢帶來太多的時間消耗。
下面引用一張舊的kafka存儲機制圖,不帶.timeindex 文件:
index文件和log文件的關(guān)系:“.index”文件存儲大量的索引信息,“.log”文件存儲大量的數(shù)據(jù),索引文件中的元數(shù)據(jù)指向?qū)?yīng)數(shù)據(jù)文件中message的物理偏移地址。
因為每一個segment文件名為上一個 Segment 最后一條消息的 offset ,所以當(dāng)需要查找一個指定 offset 的 message 時,通過在所有 segment 的文件名中進(jìn)行二分查找就能找到它歸屬的 segment ,再在其 index 文件中找到其對應(yīng)到文件上的物理位置,就能拿出該 message 。
舉例:這里我們以查找offset為6的message為例,查找流程如下:
首先要確定這個offset信息在哪個segment文件(由于是順序讀寫,這里使用二分查找法),第一個文件名為00000000000000000000,第二個為00000000000000150320,所以6這個offset的數(shù)據(jù)肯定在第一個文件里面;
找到文件后就好辦了,在這個文件的 00000000000000000000.index文件中的[6,9807]定位到00000000000000000000.log文件中9807這個位置來進(jìn)行數(shù)據(jù)讀取即可。
在了解分區(qū)策略之前需要先了解為什么要分區(qū),可以從兩方面來解釋這個問題:
方便在集群中擴展,每個Partition可以通過調(diào)整以適應(yīng)它所在的機器,而一個topic又可以有多個Partition組成,因此整個集群就可以適應(yīng)任意大小的數(shù)據(jù);
可以提高并發(fā),分區(qū)后以Partition為單位讀寫。
首先要知道producer發(fā)送的數(shù)據(jù)其實需要封裝成一個ProducerRecord對象才可以,我們看ProducerRecord提供的方法如下:
通過這個構(gòu)造方法,我們知道kafka分區(qū)策略有如下3種:
指明 partition 的情況下,直接將指明的值直接作為 partiton 值;
沒有指明 partition 值但有 key 的情況下,將 key 的 hash 值與 topic 的 partition 數(shù)進(jìn)行取余得到 partition 值;
既沒有 partition 值又沒有 key 值的情況下,第一次調(diào)用時隨機生成一個整數(shù)(后面每次調(diào)用在這個整數(shù)上自增),將這個值與 topic 可用的 partition 總數(shù)取余得到 partition 值,也就是常說的 round-robin 算法。
上述就是小編為大家分享的如何深入分析Kafka架構(gòu)的工作流程、存儲機制、分區(qū)策略了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。