真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Kafka的Log存儲(chǔ)解析是怎樣的

Kafka的Log存儲(chǔ)解析是怎樣的,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

目前成都創(chuàng)新互聯(lián)已為數(shù)千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站改版維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、清澗網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

引言

Kafka中的Message是以topic為基本單位組織的,不同的 topic之間是相互獨(dú)立的。每個(gè)topic又可以分成幾個(gè)不同的partition(每個(gè)topic有幾個(gè)partition是在創(chuàng)建topic時(shí)指定 的),每個(gè)partition存儲(chǔ)一部分Message。借用官方的一張圖,可以直觀地看到topic和partition的關(guān)系。
Kafka的Log存儲(chǔ)解析是怎樣的

partition是以文件的形式存儲(chǔ)在文件系統(tǒng)中,比如,創(chuàng)建了一個(gè)名 為page_visits的topic,其有5個(gè)partition,那么在Kafka的數(shù)據(jù)目錄中(由配置文件中的log.dirs指定的)中就有這樣 5個(gè)目錄: page_visits-0, page_visits-1,page_visits-2,page_visits-3,page_visits-4,其命名規(guī)則 為-,里面存儲(chǔ)的分別就是這5個(gè)partition的數(shù)據(jù)。

接下來(lái),本文將分析partition目錄中的文件的存儲(chǔ)格式和相關(guān)的代碼所在的位置。

Partition的數(shù)據(jù)文件

Partition中的每條Message由offset來(lái)表示它在這個(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)容。它的格式和Kafka通訊協(xié)議中介紹的MessageSet格式是一致。

Partition的數(shù)據(jù)文件則包含了若干條上述格式的Message,按offset由小到大排列在一起。它的實(shí)現(xiàn)類為FileMessageSet,類圖如下:
Kafka的Log存儲(chǔ)解析是怎樣的
它的主要方法如下:

  • append: 把給定的ByteBufferMessageSet中的Message寫(xiě)入到這個(gè)數(shù)據(jù)文件中。

  • searchFor: 從指定的startingPosition開(kāi)始搜索找到第一個(gè)Message其offset是大于或者等于指定的offset,并返回其在文件中的位置 Position。它的實(shí)現(xiàn)方式是從startingPosition開(kāi)始讀取12個(gè)字節(jié),分別是當(dāng)前MessageSet的offset和size。如 果當(dāng)前offset小于指定的offset,那么將position向后移動(dòng)LogOverHead+MessageSize(其中 LogOverHead為offset+messagesize,為12個(gè)字節(jié))。

  • read:準(zhǔn)確名字應(yīng)該是slice,它截取其中一部分返回一個(gè)新的FileMessageSet。它不保證截取的位置數(shù)據(jù)的完整性。

  • sizeInBytes: 表示這個(gè)FileMessageSet占有了多少字節(jié)的空間。

  • truncateTo: 把這個(gè)文件截?cái)?,這個(gè)方法不保證截?cái)辔恢玫腗essage的完整性。

  • readInto: 從指定的相對(duì)位置開(kāi)始把文件的內(nèi)容讀取到對(duì)應(yīng)的ByteBuffer中。

我們來(lái)思考一下,如果一個(gè)partition只有一個(gè)數(shù)據(jù)文件會(huì)怎么樣?

  1. 新數(shù)據(jù)是添加在文件末尾(調(diào)用FileMessageSet的append方法),不論文件數(shù)據(jù)文件有多大,這個(gè)操作永遠(yuǎn)都是O(1)的。

  2. 查找某個(gè)offset的Message(調(diào)用FileMessageSet的searchFor方法)是順序查找的。因此,如果數(shù)據(jù)文件很大的話,查找的效率就低。

那Kafka是如何解決查找效率的的問(wèn)題呢?有兩大法寶:1) 分段 2) 索引。

數(shù)據(jù)文件的分段

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è)段 中。

為數(shù)據(jù)文件建索引

數(shù)據(jù)文件分段使得可以在一個(gè)較小的數(shù)據(jù)文件中查找對(duì)應(yīng)offset的 Message了,但是這依然需要順序掃描才能找到對(duì)應(yīng)offset的Message。為了進(jìn)一步提高查找的效率,Kafka為每個(gè)分段后的數(shù)據(jù)文件建立 了索引文件,文件名與數(shù)據(jù)文件的名字是一樣的,只是文件擴(kuò)展名為.index。
索引文件中包含若干個(gè)索引條目,每個(gè)條目表示數(shù)據(jù)文件中一條Message的索引。索引包含兩個(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開(kāi)始,那么 offset為25的Message在index文件中的相對(duì)offset就是25-20 = 5。存儲(chǔ)相對(duì)offset可以減小索引文件占用的空間。

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

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

在Kafka中,索引文件的實(shí)現(xiàn)類為OffsetIndex,它的類圖如下:
Kafka的Log存儲(chǔ)解析是怎樣的

主要的方法有:

  • append方法,添加一對(duì)offset和position到index文件中,這里的offset將會(huì)被轉(zhuǎn)成相對(duì)的offset。

  • lookup, 用二分查找的方式去查找小于或等于給定offset的最大的那個(gè)offset

小結(jié)

我們以幾張圖來(lái)總結(jié)一下Message是如何在Kafka中存儲(chǔ)的,以及如何查找指定offset的Message的。

Message是按照topic來(lái)組織,每個(gè)topic可以分成多個(gè)的partition,比如:有5個(gè)partition的名為為page_visits的topic的目錄結(jié)構(gòu)為:
Kafka的Log存儲(chǔ)解析是怎樣的

partition是分段的,每個(gè)段叫LogSegment,包括了一個(gè)數(shù)據(jù)文件和一個(gè)索引文件,下圖是某個(gè)partition目錄下的文件:
Kafka的Log存儲(chǔ)解析是怎樣的
可以看到,這個(gè)partition有4個(gè)LogSegment。

借用博主@lizhitao 博客上的一張圖來(lái)展示是如何查找Message的。
Kafka的Log存儲(chǔ)解析是怎樣的
比如:要查找絕對(duì)offset為7的Message:

  1. 首先是用二分查找確定它是在哪個(gè)LogSegment中,自然是在第一個(gè)Segment中。

  2. 打 開(kāi)這個(gè)Segment的index文件,也是用二分查找找到offset小于或者等于指定offset的索引條目中最大的那個(gè)offset。自然 offset為6的那個(gè)索引是我們要找的,通過(guò)索引文件我們知道offset為6的Message在數(shù)據(jù)文件中的位置為9807。

  3. 打開(kāi)數(shù)據(jù)文件,從位置為9807的那個(gè)地方開(kāi)始順序掃描直到找到offset為7的那條Message。

這套機(jī)制是建立在offset是有序的。索引文件被映射到內(nèi)存中,所以查找的速度還是很快的。

一句話,Kafka的Message存儲(chǔ)采用了分區(qū)(partition),分段(LogSegment)和稀疏索引這幾個(gè)手段來(lái)達(dá)到了高效性。

關(guān)于Kafka的Log存儲(chǔ)解析是怎樣的問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。


網(wǎng)頁(yè)名稱:Kafka的Log存儲(chǔ)解析是怎樣的
鏈接分享:http://weahome.cn/article/gsjcgj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部