从外部数据源接入到kafka及kafka存储数据的原理机制

1、外部数据是怎样的接入到kafka的?

外部数据接入到kafka的流程示意图:

从外部数据源接入到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的关系如下:
    从外部数据源接入到kafka及kafka存储数据的原理机制

其中,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填充。如下图所示:
从外部数据源接入到kafka及kafka存储数据的原理机制
关于segment file中index与data file对应关系图,这里我们选用网上的一个图片,如下所示:
从外部数据源接入到kafka及kafka存储数据的原理机制
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中的物理结构为:

从外部数据源接入到kafka及kafka存储数据的原理机制

(2-3) 数据文件的内部实现方法

Partition数据文件包含了若干上述格式的message,按照offset由小到大排列在一起,它实现的类是FileMessageSet,类图如下:

从外部数据源接入到kafka及kafka存储数据的原理机制
它的主要方法如下:

  • 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.****.net/wx1528159409/article/details/88663974

kafka接入学习:https://blog.****.net/u014001866/article/details/50971098