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

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

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

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

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

key的作用

发送消息时,设置 key 的作用如下:
image.png

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 的正则匹配实现消息的过滤和聚合等操作。

课后思考

保证 Kafka 消息的有序性,除了设置 key 之外,还有哪些实现手段?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

相关文章
|
1月前
|
消息中间件 存储 缓存
大厂面试高频:Kafka 工作原理 ( 详细图解 )
本文详细解析了 Kafka 的核心架构和实现原理,消息中间件是亿级互联网架构的基石,大厂面试高频,非常重要,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:Kafka 工作原理 ( 详细图解 )
|
4月前
|
消息中间件 存储 负载均衡
Kafka面试题及答案
Kafka面试题及答案
|
29天前
|
消息中间件 大数据 Kafka
大厂面试高频:Kafka、RocketMQ、RabbitMQ 的优劣势比较
本文深入探讨了消息队列的核心概念、应用场景及Kafka、RocketMQ、RabbitMQ的优劣势比较,大厂面试高频,必知必会,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:Kafka、RocketMQ、RabbitMQ 的优劣势比较
|
27天前
|
存储 NoSQL 算法
面试官:Redis 大 key 多 key,你要怎么拆分?
本文介绍了在Redis中处理大key和多key的几种策略,包括将大value拆分成多个key-value对、对包含大量元素的数据结构进行分桶处理、通过Hash结构减少key数量,以及如何合理拆分大Bitmap或布隆过滤器以提高效率和减少内存占用。这些方法有助于优化Redis性能,特别是在数据量庞大的场景下。
面试官:Redis 大 key 多 key,你要怎么拆分?
|
2月前
|
消息中间件 存储 缓存
美团面试: Kafka为啥能实现 10Wtps 到100Wtps ?kafka 如何实现零复制 Zero-copy?
40岁老架构师尼恩分享了Kafka如何实现高性能的秘诀,包括零拷贝技术和顺序写。Kafka采用mmap和sendfile两种零拷贝技术,前者用于读写索引文件,后者用于向消费者发送消息,减少数据在用户空间和内核空间间的拷贝次数,提高数据传输效率。此外,Kafka通过顺序写日志文件,避免了磁盘寻道和旋转延迟,进一步提升了写入性能。尼恩还提供了系列技术文章和PDF资料,帮助读者深入理解这些技术,提升面试竞争力。
美团面试: Kafka为啥能实现 10Wtps 到100Wtps ?kafka 如何实现零复制 Zero-copy?
|
2月前
|
NoSQL Redis
redis 的 key 过期策略是怎么实现的(经典面试题)超级通俗易懂的解释!
本文解释了Redis实现key过期策略的方式,包括定期删除和惰性删除两种机制,并提到了Redis的内存淘汰策略作为补充,以确保过期的key能够被及时删除。
61 1
|
2月前
|
消息中间件 存储 Kafka
面试题:Kafka如何保证高可用?有图有真相
面试题:Kafka如何保证高可用?有图有真相
|
4月前
|
存储 缓存 JavaScript
【Vue面试题十八】、你知道vue中key的原理吗?说说你对它的理解
这篇文章详细介绍了Vue中的`keep-alive`组件,解释了其作用是缓存不活动的组件实例以避免重复渲染DOM,并阐述了`keep-alive`的使用场景、props属性配置、以及如何通过源码理解其缓存机制和原理。
【Vue面试题十八】、你知道vue中key的原理吗?说说你对它的理解
|
4月前
|
JavaScript 算法
【Vue面试题十七】、你知道vue中key的原理吗?说说你对它的理解
这篇文章深入探讨了Vue中`key`的原理及其作用,解释了`key`是为每个虚拟DOM节点提供的唯一标识符,作为`diff`算法的优化策略,有助于更快速准确地识别和重用DOM元素。文章通过实际代码示例展示了使用`key`与否在列表渲染时对DOM操作的影响,分析了`key`在不同场景下的性能表现,并提供了源码层面的分析,解释了Vue如何通过`key`来识别和更新虚拟DOM节点。
【Vue面试题十七】、你知道vue中key的原理吗?说说你对它的理解
|
5月前
|
消息中间件 Kafka
面试题Kafka问题之Kafka【线上】积压消费如何解决
面试题Kafka问题之Kafka【线上】积压消费如何解决
39 0