kafka消息自带时间戳类型

背景

事情起源于flink消费kafka消息的一个项目,大概流程是根据kafka记录中的时间戳进行分窗统计一批记录中包含某种模式的消息的个数,有一天,由于目前的kafka集群要更新维护,运维反馈我们可以切换到另一个kafka集群中消费消息,也就是这时候我们收到了flink作业频繁失败的告警,告警的日志里面显示flink task内存OOM,当时百思不得其解,这两个kafka集群是新旧两个job写进去的,不过两个job逻辑都是一样的,对比好几条消息的内容也是一样的,那为什么呢?

追查真相

既然我们确认消息的内容是一样的,那么这两个kafka的消息有什么不一样的地方呢?难道是消息头不一样?意识到这是两个不同版本的kafka集群后,我们突然意识到是不是消费的消息的时间戳字段不一样,导致按照时间戳分窗的时候窗口没法结束?想到了这个问题,我们对比了两个集群的某个消息的所有内容,包括消息头,发现之前的kafka集群的消息确实带了timestamp字段,并且有值,但是目前的kafka集群的消息的timestamp字段为-1,真相原来如此。
下面我们来看看不同的kafka版本这个字段的赋值情况:

kafka 版本:
<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>0.9.0.1</version>
</dependency>
 
public final class ProducerRecord<K, V> {
 
    private final String topic;
    private final Integer partition;
    private final K key;
    private final V value;
 
}
 
 
kafka 版本:
<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>0.10.2.2</version>
</dependency>
 
public class ProducerRecord<K, V> {
 
    private final String topic;
    private final Integer partition;
    private final K key;
    private final V value;
    private final Long timestamp;
 
}
 
kafka版本:
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-clients</artifactId>
            <version>0.11.0.3</version>
        </dependency>
 
public class ProducerRecord<K, V> {
    private final String topic;
    private final Integer partition;
    private final Headers headers;
    private final K key;
    private final V value;
    private final Long timestamp;
}
 
 
kafka版本:
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-clients</artifactId>
            <version>3.2.0</version>
        </dependency>
 
public class ProducerRecord<K, V> {
 
    private final String topic;
    private final Integer partition;
    private final Headers headers;
    private final K key;
    private final V value;
    private final Long timestamp;
}  

以kafka 0.11.0作为分界点,之后的kafka版本肯定是带了时间戳的字段的,最后一个问题是这个时间戳字段代表什么含义?
关于kafka每条记录中的时间字段的含义是由kafka的Broker中的配置值:log.message.timestamp.type决定的,如果取值为CreateTime,那么表示消费者获取到的记录的时间戳字段使用的是kafka客户端生成的ProducerRecord记录中的timestamp时间戳字段,时间是毫秒,如果取值是LogAppendTime,那么表示消费者获取到的记录的时间戳字段是kafka的Broker把ProducerRecord记录写入到日志文件时的系统时间,此时会忽略ProducerRecord记录中自带的时间戳字段的值.

总结

老版本的kafka集群的消息是不带时间戳字段的,也就是里面的值是-1,而新版本的kafka集群的消息是带时间戳字段的,这个时间戳的含义是表示记录的创建时间,还是表示记录被写到kafka日志文件的时间由kafka服务端的配置值log.message.timestamp.type决定

你可能感兴趣的:(kafka,kafka,java,大数据)