本章我们开始讲解kafka的一些设计原理,并根据此走入Kafka的内部

我们首先讲解的是一些在broker端的设计

Broker是我们率先接触的Kafka组件,是构成Kafka的消息持久化以及将消息从生产者端传递到消费者端的载体,本章我们将讲解broker的一个设计思想,

首先是kafka的消息格式设计,如果按照Java来设计

图片

基本如上,但是一个消息在Kafka中并不会以对象的形式存在,因为会存在一些额外的内存开销工作,比如在Java会存在着对齐操作.

所以Kafka把消息实现为了ByteBuffer进行传递保存消息,从而降低了空间消耗和占用.

而Kafka消息的格式在整个过程中并不是一成不变的.基本可以分为了三个版本,V0,V1,V2,

对于V0版本,是最早的消息版本,基本格式如下图

图片

包含的字段为

CRC 4字节校验码,防止消息篡改

Magic 单字节,消息的版本号

Attribute 属性字段,但只使用了低3位来表示消息的压缩类型

Key长度,4字节的key消息长度,没有key就赋值为-1

Key值,可变长度

Value长度,4字节的消息长度,没有value就赋值为-1

Value值,可变长度

那么一条消息的长度基本为14字节,如果加上key value,那么会变得更大,因此Kafka进行了改进,演进为了V1版本

引进了时间戳字段

在整个消息中加入了8字节的时间戳字段,那么整个消息膨胀到了22字节,这还不算任何的消息.而时间戳也分类型CREATE_TIME和LOG_APPEND_TIME,前者表示消息创建的时候指定时间戳,后者表示发送到broker的时候由broker指定时间戳.

那么V2呢,做了什么改进,V2的改进主要存在于消息集合侧,这个消息集合我们在之前没有讲解,但是并不难理解,就是在生产者中,往往消息并不是单独一条的发送,而是等待汇聚为一批消息进行发送.

V0,1版本的消息集合的对象,名称被称为日志项,是由一条浅层消息和日志项头部组成

浅层消息如果不包装,就是消息本身

日志项头部,包含offset的信息,用于回来搜索查看特定的消息

图片

那么一条消息的日志项,会在原本的消息长度之上,增加12个字节.

不过在这种存在空间利用率的问题,不管key和value哟多少,都是使用4字节保存部分消息

而且总是保存最新消息位移,如果是用压缩,那么这个版本的offset是所有消息的最后一条消息的offset.如果获取其中消息的位移,还需要解压缩.

而且没有保存消息长度,导致单个消息的总字节数还需要计算得到.

因此衍生了V2版本,改进了上面的问题.

首先是采用了可变长度,来进行保存数据,这样就可以剩下固定拜纳姆

其次不在每个消息中保存全量时间戳,而是保存时间戳增量,减少了空间占用

对于位移,在一个消息批次中,也是保存的位移增量

增加了元数据头部,这个头部是给用户存放一些元数据使用的.

去掉了消息级别CRC校验

废弃了attribute字段,保存在了消息批次之中.

那么我们来看V2版本的消息批次数据

图片

这个头中,保存了单个消息中移除的CRC,attribute字段

引入了PID,producer epoch和序列号,用于支持Producer中的事务做的.防止重复生产消息.

V2版本的开销增加到了61字节,似乎比V0 V1版本的增加了不少,但是将某些字段中的值集中在了消息批次中,而且因为producer大部分是多消息集合,所以总体上节省了空间.

发表评论

邮箱地址不会被公开。 必填项已用*标注