Kafka设计解析(十六)Kafka 0.11消息设计

2023-07-10,,

转载自 huxihx,原文链接 【原创】Kafka 0.11消息设计

目录

一、Kafka消息层次设计

1. v1格式

2. v2格式

二、v1消息格式

三、v2消息格式

四、测试对比

Kafka 0.11版本增加了很多新功能,包括支持事务、精确一次处理语义和幂等producer等,而实现这些新功能的前提就是要提供支持这些功能的新版本消息格式,同时也要维护与老版本的兼容性。本文将详细探讨Kafka 0.11新版本消息格式的设计,其中会着重比较新旧两版本消息格式在设计上的异同。毕竟只有深入理解了Kafka的消息设计,我们才能更好地学习Kafka所提供的各种功能。    

一、Kafka消息层次设计

不管是0.11版本还是之前的版本,Kafka的消息层次都是分为两层:消息集合(message set)以及消息(message)。一个消息集合中包含若干多条日志项,而每个日志项封装了消息以及其他一些元数据。Kafka底层的消息日志则由一系列消息集合日志项组成的。Kafka不会在消息这个层面上直接操作,它总是在消息集合这个层面上进行写入操作。

新旧两个版本对这两个层次的设计都有很大区别,我们下面分开来说。不过在深入到具体版本之前,我们先要明确一些基本术语。

首先,我会遵循Kafka社区的规范,称老版本消息格式为v1,新版本格式为v2。另外这里所指的老版本是指包含了时间戳(timestamp)字段的消息格式,更早之前的消息格式不在本文讨论的范围。其次,消息集合和消息在新旧版本对应的类名也有些许区别:

1. v1格式

在0.11版本之前,消息集合对应的类是org.apache.kafka.common.record.Records,消息是o.a.k.common.record.Record。消息集合中的每一项被称为日志项(log entry),你可以理解每个日志项都是一个batch。

2. v2格式

0.11版本中消息集合对应的类是o.a.k.common.record.RecordBatch,消息依然是o.a.k.common.record.Record。特别注意这里的RecordBatch,如果你在之前的Kafka版本中搜寻RecordBatch类,你会发现在老版本中它指代的是Java producer端的消息batch——java producer将待发送消息收集起来,然后根据topic分区执行分组操作,其分组结果就保存在多个RecordBatch中。但是在新版本中,RecordBatch指的是普通的消息集合,producer端的分组batch由类o.a.k.clients.producer.internals.ProducerBatch来负责。各位千万不要混淆!

okay,了解了基本的术语,我们分别讨论下老版本、新版本的消息格式。

二、v1消息格式

在0.11版本之前,Kafka的消息格式如下图所示:

图中各个字段的含义很清晰,这里不再赘述。从上图中我们可以计算出来一条普通的Kafka消息的头部开销——这里姑且称为头部,header,但不要和新版本的header混淆!下面会讨论新版本的header。此版本的消息头部开销等于4 + 1 + 1 + 8 + 4 + 4 = 22字节,也就是说一条Kafka消息长度再小,也不可以小于22字节,否则会被Kafka视为corrupted。另外根据这张图展示出来的格式,我们能够很容易地计算每条Kafka消息的总长度。注意,这里我们讨论的未压缩消息。已压缩消息的计算会复杂一些,故本文暂且不讨论。

下面我们来做一些计算。假设有一条Kafka消息,key是“key”,value是“hello”,那么key的长度就是3,value的长度就是5,因此这条Kafka消息需要占用22 + 3 + 5 = 30字节;倘若另一条Kafka消息未指定key,而value依然是“hello”,那么Kafka会往key长度字段中写入-1表明key是空,因而不再需要保存key信息,故总的消息长度= 22 + 5 = 27字节。当然value字段也可能是null——Kafka的log cleaner会定期地写入这种被称为tombstone消息,不过计算方法与key为空时是相同的。总之单条Kafka消息长度的计算是很简单的,下面我们来说说消息集合日志项的计算。

老版本消息集合中的每一项的格式如下图所示:

aaarticlea/png;base64,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" alt="" />

如图所示,每个消息集合中的日志项由日志项头部+一条“浅层”消息构成。

浅层(shallow)消息:如果是未压缩消息,shallow消息就是消息本身;如果是压缩消息,Kafka会将多条消息压缩再一起封装进这条浅层消息的value字段。这条浅层消息也被称为wrapper消息,里面包含的消息被称为内部消息,即inner message。由此可见,老版本的message batch中通常都只包含一条消息,即使是对于已压缩消息而言,它也只是包含一条shallow消息。
日志项头部(log entry header):8字节的offset字段 + 4个字节的size字段,共计12个字节。其中offset保存的是这条消息的位移。对于未压缩消息,它就是消息的位移;如果是压缩消息,它表示wrapper消息中最后一条inner消息的位移。由此可见,给定一个老版本的消息集合倘若要寻找该消息集合的起始位移(base offset或starting offset)是一件很困难的事情,因为这通常都需要深度遍历整个inner消息,这也就是意味着broker端需要执行解压缩的操作,因此代价非常高。

下面我们来看下如何计算消息集合大小,还是拿之前的两条Kafka消息为例。第一条消息被封装进一个消息集合,那么该消息集合总的长度 = 12 + 30 = 42字节,而包含第二条未指定key消息的消息集合总长度 = 12 + 27 = 39字节。我们做个试验来验证下:

1. 创建一个测试topic,1个分区,replication-factor = 1,然后使用console-producer脚本发送一条消息,key=“key”,value=“hello”,然后验证下底层文件日志大小是42字节。

bogon:kafka_0.10.2. huxi$ bin/kafka-topics.sh --zookeeper localhost: --create --partitions  --replication-factor  --topic test
Created topic "test".
bogon:kafka_0.10.2. huxi$ bin/kafka-console-producer.sh --broker-list localhost: --topic test --property parse.key=true --property key.separator=:
key:hello

输出结果:

bogon:test- huxi$ pwd
/Users/huxi/SourceCode/testenv/datalogs/kafka_1/test-
bogon:test- huxi$ ll *.log
-rw-r--r-- huxi staff Jul : .log

可见,我们的计算是正确的。

2. 再使用console-producer脚本发送另一条消息,不指定key,value依然是“hello”,然后验证下底层文件日志大小是42 + 39 = 81字节。

bogon:test- huxi$ ll *.log
-rw-r--r-- huxi staff Jul : .log

结果再次证明我们的计算方法是正确的。不过,老版本的消息集合在设计上有一些弊端,包括:

对空间的利用率不高,比如不论key和value的长度是多少,老版本消息都是用固定的4个字节来保存长度信息,比如value是100字节还是1000字节,v1消息都需要花费4个字节来保存整个值,但其实保存100这个值只需要7个比特就够了,也就是说只用1个字节就可以,另外3个字节都是浪费的。如果你的系统中这种情况很常见的话,那么对于磁盘/内存空间的浪费是十分可观的。
老版本设计中的offset是消息集合的最后一条消息的offset,如果用户想要获取第一条消息的位移,必须要把所有消息解压全部装入内存然后反向遍历才能获取到。显然这个代价是很大的
CRC的计算有些鸡肋。老版本设计中每条消息都需要执行CRC校验。但有些情况下我们不能想认为producer端发送的消息的CRC到consumer端消息时是不变的。比如如果用户指定的时间戳类型是LOG_APPEND_TIME,那么在broker端会对消息时间戳字段进行更新,那么重新计算之后的CRC值就会发生变化;再比如broker端进行消息格式转换也会带来CRC的变化。鉴于这些情况,再对每条消息都执行CRC校验就有点没必要了,不仅浪费空间还耽误CPU时间
每次需要单条消息的总长度信息时都需要计算而得出,没有使用一个字段来保存下来,解序列化效率不高。

鉴于以上这些弊端以及对0.11版本新功能支持的需要, Kafka社区重新设计了v2版本的消息来解决以上的问题。

三、v2消息格式

v2版本依然分消息与消息集合两个维度,只不过消息集合这个提法被消息batch所取代。v2版本的术语叫RecordBatch。我们先来看v2消息的格式,如下图所示:

这里的"可变长度"表示Kafka会根据具体的值来确定到底需要几个字节来保存。为了序列化时降低所需的字节数,0.11版本借鉴了Google PB的Zig-zag编码方式,使得绝对值较小的整数占用比较少的字节。这是符合Kafka消息使用场景的,毕竟在实际使用过程中,key或value很大的可能性并不高。比如key如果是一个有业务含义的字符串(这是很常见的使用方法),那么这个字符串的长度通常都不会太长,这样大部分情况下只需要1~2个字节就可以保存了。这比v1版本中固定使用4个字节来保存要节省得多。如果要深入了解pb的编码方式请参考:https://developers.google.com/protocol-buffers/docs/encoding

总之v2版本的消息格式比起v1有很大的变化。除了可变长度这一点,v2版本的属性字段被弃用了,CRC被移除了,另外增加了消息总长度、时间戳增量(timestamp delta)、位移增量(offset delta)和headers信息。我们分别说下:

消息总长度:直接计算出消息的总长度并保存在第一个字段中,而不需要像v1版本时每次需要重新计算。这样做的好处在于提升解序列化的效率——拿到总长度后,Kafka可以直接new出一个等长度的ByteBuffer,然后装填各个字段。同时有了这个总长度,在遍历消息时可以实现快速地跳跃,省去了很多copy的工作。
时间戳增量:消息时间戳与所属record batch起始时间戳的差值,保存差值可以进一步节省消息字节数
位移增量:消息位移与所属record batch起始位移的差值,保存差值可以进一步节省消息字节数
headers:这和本文之前提到的所有header都无关。这是0.11版本引入的新字段。它是一个数组,里面的Header只有两个字段:key和value,分别是String和byte[]类型。
v2版本不在对每条消息执行CRC校验,而是针对整个batch
v2版本不在使用属性字节,原先保存在属性字段中的诸如压缩类型、时间戳类型等信息都统一保存在外层的batch中

下面我们依然拿上面的Kafka消息举例计算下0.11版本的消息长度是多少。假设这条Kafka消息的key是“key”,value是“hello”,同时假设这是batch中的第一条消息,因此时间戳增量和位移增量都是0,另外我们还假设没有指定任何header,因此header数组个数是0。结合上图我们可以计算这条消息的长度 = 总长度值占用的字节数 + 1 + 1 + 1 + 1 + 3 + 1 + 5 + 1 =  总长度值占用的字节数 + 14,由于14小于64,因此总长度值只需1个字节,故消息总长度是15字节。同时消息的第一个字节保存的值就是15。这里提一句为什么是64? 先前提到的Zigzag编码会将有符号32位整数编码成一个无符号整数,大致的思想是:

   --->
-  --->
  --->
-   --->
  --->
...

这样做,我们不再需要为-1去保存32位的补码,只需要1个字节就能保存-1,但是zigzag会将每个字节的第一个比特作为特殊之用,故每个字节只能有7位来做实际的编码任务,也就是表示从0~127。上面的编码表中我们可以发现正数都会被编码成其2倍的数字,因此如果一旦上面例子中的长度超过了128/2=64,长度信息就需要用2个字节来保存。这就是上面64这个数字出现的原因。(希望我解释清楚了。。。。) 我们再举个例子,假设某条Kafka消息未指定key,value是“hello”,该消息在整个batch中的第100条且时间戳增量也是100,那么该消息总的字节数是=总长度值占用的字节数 + 1 + 2 + 2 + 1 + 1 + 5 + 1 = 总长度值占用的字节数 + 13 = 14字节。

谈完了消息格式,我们终于可以说说record batch了。v2的batch格式非常复杂,不废话了, 直接上图:

显然这比v1版本的batch要复杂得多,简单解释一下它和v1的主要区别:

CRC被移动batch这一层,而非消息这一层
属性字段被扩充为2个字节,而不是之前的一个字节,其中第一个字节的低3位比特保存压缩类型,第4个比特保存时间戳类型,第5个比特保存消息的事务类型(事务型消息和非事务型消息),第6个比特指定batch是否是control batch(control batch以及control message用于支持事务)
PID、producer epoch、序列号等信息都是为了实现幂等producer之用,故本文不做详细展开(其实我也不会

Kafka设计解析(十六)Kafka 0.11消息设计的相关教程结束。

《Kafka设计解析(十六)Kafka 0.11消息设计.doc》

下载本文的Word格式文档,以方便收藏与打印。