從外部數據源接入到kafka及kafka存儲數據的原理機制

1、外部數據是怎樣的接入到kafka的?

外部數據接入到kafka的流程示意圖:

在這裏插入圖片描述

(1)接入數據流程

(1)producer先從broker-list的節點中找到該partition的leader;

(2)然後producer將消息發送給作爲leader的partition;

(3)leader收到消息後,將消息寫入本地log;

(4)followers從leader中pull消息,實現replication的副本備份機制,同樣寫入本地log;

(5)replication寫入本地log後向leader發送ack(確認);

(6)leader收到所有的replication的ack之後,向producer發送ack;

(7)producer收到leader的ack,證明生產的數據已被kafka成功寫入。

(2)kafka的ack應答機制(request.requred.acks中修改ack值)

ack = 0:producer不等待broker中leader的ack;broker接收消息後如果還沒寫入本地log,broker就發生故障,可能會丟失數據;

ack = 1:producer等待leader的ack,但是不等待replication的ack;這樣partition的leader消息落盤成功後返回ack,但是在follwer備份成功之前若leader發生故障,也會丟失數據;延遲時間短但是可靠性低;

ack = -1:producer等待leader和replication的ack,這樣只有等leader中partition消息落盤成功,並且follower中replication消息備份落盤成功,纔會給producer返回ack,數據一般不會丟失,延遲時間長但是可靠性高。

2、kafka的數據存儲

(1)kafka的重要概念

  • Broker:消息中間件處理結點,一個Kafka節點就是一個broker,多個broker可以組成一個Kafka集羣;

  • Topic:一類消息,例如page

  • view日誌、click日誌等都可以以topic的形式存在,Kafka集羣能夠同時負責多個topic的分發;

  • Partition:topic物理上的分組,一個topic可以分爲多個partition,每個partition是一個有序的隊;

  • Segment:每個partition又由多個segment file組成;

  • offset:每個partition都由一系列有序的、不可變的消息組成,這些消息被連續的追加到partition中。partition中的每個消息都有一個連續的序列號叫做offset,用於partition唯一標識一條消息;

  • message:這個算是kafka文件中最小的存儲單位,即是 a commit log。
    kafka的message是以topic爲基本單位,不同topic之間是相互獨立的。每個topic又可分爲幾個不同的partition,每個partition存儲一部的分message。topic與partition的關係如下:
    在這裏插入圖片描述

其中,partition是以文件夾的形式存儲在具體Broker本機上。

(2)partition中的數據文件

(2-1) segment中的文件

對於一個partition(在Broker中以文件夾的形式存在),裏面又有很多大小相等的segment數據文件(這個文件的具體大小可以在config/server.properties中進行設置),這種特性可以方便old segment file的快速刪除。

下面先介紹一下partition中的segment file的組成:

segment file 組成:由2部分組成,分別爲index file和data file,這兩個文件是一一對應的,後綴”.index”和”.log”分別表示索引文件和數據文件;
segment file 命名規則:partition的第一個segment從0開始,後續每個segment文件名爲上一個segment文件最後一條消息的offset,ofsset的數值最大爲64位(long類型),20位數字字符長度,沒有數字用0填充。如下圖所示:
在這裏插入圖片描述
關於segment file中index與data file對應關係圖,這裏我們選用網上的一個圖片,如下所示:
在這裏插入圖片描述
segment的索引文件中存儲着大量的元數據,數據文件中存儲着大量消息,索引文件中的元數據指向對應數據文件中的message的物理偏移地址。以索引文件中的3,497爲例,在數據文件中表示第3個message(在全局partition表示第368772個message),以及該消息的物理偏移地址爲497。

注:Partition中的每條message由offset來表示它在這個partition中的偏移量,這個offset並不是該Message在partition中實際存儲位置,而是邏輯上的一個值(如上面的3),但它卻唯一確定了partition中的一條Message(可以認爲offset是partition中Message的id)。

(2-2) message文件

message中的物理結構爲:

在這裏插入圖片描述

(2-3) 數據文件的內部實現方法

Partition數據文件包含了若干上述格式的message,按照offset由小到大排列在一起,它實現的類是FileMessageSet,類圖如下:

在這裏插入圖片描述
它的主要方法如下:

  • append: 把給定的ByteBufferMessageSet中的Message寫入到這個數據文件中。
  • searchFor: 從指定的startingPosition開始搜索,找到第一個Message判斷其offset是大於或者等於指定的offset,並返回其在文件中的位置 - - Position。它的實現方式是從startingPosition開始讀取12個字節,分別是當前MessageSet的offset和size。如果當前offset小於指定的offset,那麼將position向後移動LogOverHead+MessageSize(其中 - LogOverHead爲offset+messagesize,爲12個字節)。
  • read:準確名字應該是slice,它截取其中一部分返回一個新的FileMessageSet。它不保證截取的位置數據的完整性。
  • sizeInBytes: 表示這個FileMessageSet佔有了多少字節的空間。
  • truncateTo: 把這個文件截斷,這個方法不保證截斷位置的Message的完整性。
  • readInto: 從指定的相對位置開始把文件的內容讀取到對應的ByteBuffer中。

3、參考資料

Kafka的數據生產——數據寫入流程 & 提高kafka的消費速率:
https://blog.csdn.net/wx1528159409/article/details/88663974

kafka接入學習:https://blog.csdn.net/u014001866/article/details/50971098

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章