Apache Kafka - 没有密钥的消息

Apache Kafka - message without key

在阅读 kafka 权威指南时,我遇到了这个短语

When the key is null and the default partitioner is used, the record will be sent to one of the available partitions of the topic at random. A round-robin algorithm will be used to balance the messages among the partitions.

这是否意味着这仅适用于使用 默认分区程序

嗯,不,您可以实施 自定义分区程序 来处理 null 键。但是如果没有消息密钥,您的 自定义分区程序 应该表现得像 默认分区程序 (即使使用简单的随机算法)。 否则它如何区分发送消息的正确分区?

作为 soft 规则,如果未提供密钥,请坚持使用 默认分区程序

关于 Kafka custom partitioner 的好文档。

  • 如果指定了有效的分区号,发送记录时将使用该分区。

  • 如果未指定分区但存在键,将使用键的散列选择分区(DefaultPartitioner - 请参阅下文了解更多详细信息)。

  • 如果键和分区都不存在,将以循环方式分配分区


Kafka 使用 DefaultPartitioner (org.apache.kafka.clients.producer.internals.DefaultPartitioner) 来跨主题分区分发消息:

/**
 * Compute the partition for the given record.
 *
 * @param topic The topic name
 * @param key The key to partition on (or null if no key)
 * @param keyBytes serialized key to partition on (or null if no key)
 * @param value The value to partition on or null
 * @param valueBytes serialized value to partition on or null
 * @param cluster The current cluster metadata
 */
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
    if (keyBytes == null) {
        return stickyPartitionCache.partition(topic, cluster);
    } 
    List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
    int numPartitions = partitions.size();
    // hash the keyBytes to choose a partition
    return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
}

本质上,DefaultPartitioner 利用了 MurmurHash,一种非加密散列函数,通常用于基于散列的查找。然后在模运算 (% numPartitions) 中使用此哈希,以确保返回的分区在 [0, N] 范围内,其中 N 是主题的分区数。