面试官:Kafka中的key有什么用?

开发 架构
对于某些应用场景,消费者可以根据消息的键来进行过滤或聚合操作。例如,在实时数据分析场景中,可能需要对具有相同键的消息进行分组处理。

我们在使用 Kafka 时,最简单、最常用的方式是只设置 topic(主题)和 value(消息体),如下所示:图片这样的话获取消息的代码也很简单,如下所示:

@KafkaListener(topics = "mytopic", groupId = "my-group")
public void listen(String data) {
    System.out.println("监听到消息:" + data);
}

但是,除了我们可以设置和传递 topic 和 value 之外,我们还可以传递 key,如下图所示:图片那问题来了,发送消息时设置这个 key 有什么用呢?

key的作用

发送消息时,设置 key 的作用如下:图片

1.决定分区

当生产者发送消息时,如果指定了 key,Kafka 会根据 key 的 hash 值来决定这条消息应该发送到哪个分区。

如果没有指定 key,Kafka 会采用轮询(早期版本)或随机(最新版本)的方式将消息分配到其他分区中。

分区的具体实现源码在 DefaultPartitioner 中 partition 方法中体现,核心源码如下:

public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster, int numPartitions) {
    return keyBytes == null ? this.stickyPartitionCache.partition(topic, cluster) : BuiltInPartitioner.partitionForKey(keyBytes, numPartitions);
}

指定 key 之后的分区实现代码如下:

public static int partitionForKey(byte[] serializedKey, int numPartitions) {
    return Utils.toPositive(Utils.murmur2(serializedKey)) % numPartitions;
}

以上源码的大概含义是:使用 MurmurHash2 算法对字节数组 serializedKey 进行哈希运算,并将其结果转换为正数,然后对 numPartitions 取模,以确定键在分区中的位置,返回值表示键所在的分区编号。

所以,从上述源码可以看出,发送消息如果设置了 key 之后,会将相同 key 放到同一个分区中。

2.保证消息顺序

在 Kafka 中,同一个分区中的消息是有序的。而相同的 key,根据上面的分区算法可知,它们会存放到同一个分区,这样就能保证消息的有序性了。

3.消息过滤

对于某些应用场景,消费者可以根据消息的键来进行过滤或聚合操作。例如,在实时数据分析场景中,可能需要对具有相同键的消息进行分组处理。

Kafka 设置了 key 之后,可以通过以下方式实现消息过滤,如下代码所示:

@KafkaListener(topics = "topicName", groupId = "groupId")
public void listen(String message, ConsumerRecord<?,?> record) {
    Object key = record.key();
    if (key instanceof String && ((String) key).matches("regexPattern")) {
        // 处理满足正则表达式条件的消息
    }
}

也就是,我们在接收到消息之后,通过对 key 的正则匹配实现消息的过滤和聚合等操作。

责任编辑:武晓燕 来源: 磊哥和Java
相关推荐

2020-04-23 14:09:13

URI挖坑前端

2021-07-06 07:27:45

React元素属性

2024-03-20 15:12:59

KafkaES中间件

2022-05-05 07:38:32

volatilJava并发

2023-06-05 07:57:53

Kafka消息事务消息

2024-02-19 00:00:00

Python​starmap函数

2024-09-09 08:30:56

代码

2021-12-10 12:01:37

finalfinallyfinalize

2021-11-30 07:44:50

FinalFinallyFinalize

2024-09-19 08:42:43

2024-04-03 15:33:04

JWTSession传输信息

2021-12-20 10:30:33

forforEach前端

2023-02-17 08:10:24

2024-04-15 00:01:00

STWJava垃圾

2023-02-20 08:08:48

限流算法计数器算法令牌桶算法

2023-12-13 15:28:32

Python工具数据

2024-04-19 08:23:06

2023-07-11 08:40:02

IO模型后台

2024-04-19 00:00:00

计数器算法限流算法

2024-02-26 14:07:18

点赞
收藏

51CTO技术栈公众号