kafka为什么有的消息的时间戳的值是-1

Posted 不识君的荒漠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kafka为什么有的消息的时间戳的值是-1相关的知识,希望对你有一定的参考价值。

背景

我在检索消息的时候,意外发现一些消息的时间值是-1,如下:

而另外两条消息却有正常的时间。

想找下相关原因,所以查阅了一下kafka官方文档,有了相关结论。

官方说明

kafka消息的格式有多个版本,在老版本中,是没有时间戳这个字段的。

官方文档地址:Apache Kafka

按照文档说明,在0.11之前的版本中,消息的发送和存储都是在消息集合中,每条消息都有相关元数据信息,这时候消息格式有两个版本:版本0和版本1,如下:

在版本1的消息格式中,才有了消息的时间信息。 

上面的消息格式是0.11版本之前,那0.11版本及其之后呢?如下官方说明:

从0.11开始连名字都变了,在0.11之前,消息叫做message,发送的批次叫做Message Set,也就是消息集。而从0.11叫做record,发送的批次叫做Record Batch了。不过,意思还是一个意思。

也就是在0.11开始,引入了消息头信息:Record Header。

这个消息版本是叫V2了。

从文档中显示的V2消息格式,可以看到通用信息,比如压缩算法这些都已经没有了。

这是因为这个版本做了优化,把这些通用信息,都抽了出来放在外层的消息集合,不用每条消息都保存了,所以可以看到arrtibutes部分现在都是未使用状态。上面消息格式中后面跟着delta的是相对值,相对当前批次第一条计算出来的一个相对值。

源码说明

我查看了github的代码:kafka/ProducerRecord.java at 0.10.0 · apache/kafka · GitHub

在0.10版本中已经有了kafka发送消息记录的时候,已经有了时间戳字段,但是在之前的版本中却没有了。

我在下面例出来了。

0.9版本的ProdcuerRecord属性如下:

    private final String topic;
    private final Integer partition;
    private final K key;
    private final V value;

0.10版本如下,已经有了timestamp:

    private final String topic;
    private final Integer partition;
    private final K key;
    private final V value;
    private final Long timestamp;

0.11版本如下,引入了消息头:

    private final String topic;
    private final Integer partition;
    private final Headers headers;
    private final K key;
    private final V value;
    private final Long timestamp;

然后一直到现在最新的3.1版本还是这样。

另外,关于这个时间字段,默认是生产者设置的创建时间,也就是当时的客户端的系统时间。这个时间类型是可以修改的,如下,默认是broker和一个属性,值是CreateTime:

也可以将这个值修改为LogAppendTime,就是broker端写入时的系统时间。

结论

如果消息的时间字段是-1,应该是客户端版本太老,使用的消息格式不支持时间字段。

备注

上图示例用的控制台地址:GitHub - xxd763795151/kafka-console-ui: 一款快捷易用的轻量级kafka可视化管理平台

以上是关于kafka为什么有的消息的时间戳的值是-1的主要内容,如果未能解决你的问题,请参考以下文章

Apache Kafka 根据消息的值对窗口消息进行排序

如何将消息直接从现有的大型机应用程序发布到 Kafka 主题?

KafkaKafka版本的 watermark 迟来的消息 直接报错

获取 Kafka 压缩消息大小

面试官:你是如何诊断Kafka消息发送到瓶颈在哪里(有的放矢才是性能优化的正确打开方式)

仅读取来自 kafka 主题的特定消息