Kafka如何处理与分区相关的键控消息

时间:2019-10-30 00:59:24

标签: apache-kafka data-partitioning mmsi

任何人都可以解释:

  1. Kafka实际上如何存储键入消息?分区仅分配给键吗?我的意思是,分区是否可能存储具有多个键的消息?
  2. 如果第一个问题的答案是“是”,那么密钥数是否大于可用分区?

我的用例是,我正在考虑将大量船运数据发送给经纪人,并以ship_id(如果知道,则为MMSI)作为密钥进行存储。问题是,我不知道那时会收到多少艘船。所以我不能提前定义分区号。

2 个答案:

答案 0 :(得分:0)

  

分区是否可能存储具有多个键的消息?

是的,murmur2哈希(Kafka使用的算法)修改主题中分区的数量可以产生相同的数量。例如,如果您只有一个分区,那么显然任何键都将移至同一分区

  

键的数量是否超过可用分区的数量?

哈希是取模的,因此它总是被分配一个有效的分区

现在,如果您具有定义明确的密钥,则可以保证将消息按顺序排列到分区中,因此,对分区数量的回答实际上取决于单个分区可以处理的吞吐量,而且没有简短的答案-您要发送多少数据,并且一个消费者可以在“高峰”消耗时从一个分区快速获得该数据?做适当的性能测试,然后将分区号扩大到新主题上,以应对将来可能出现的负载

您还需要考虑“热” /“冷”数据。例如,如果您有10个分区映射到ID的第一位,则所有数据均以偶数开头,则最终将有一半分区为空

答案 1 :(得分:0)

1。 Kafka消息是键和值的形式,并存储在主题中。主题被划分为多个分区程序,每个分区又进一步划分为段,每个段都有一个日志文件,以键-值形式以及消息的索引或偏移量存储实际消息。 密钥是可选的,如果密钥为空,则用于标识要存储消息的分区,然后消息以循环方式存储;而如果密钥不为空,则它将使用具有模块分区大小的哈希密钥,以保证选择其中一个分区。 例如

hash(key)%num_partition

public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
        List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
        int numPartitions = partitions.size();
        if (keyBytes == null) {
            int nextValue = nextValue(topic);
            List<PartitionInfo> availablePartitions = cluster.availablePartitionsForTopic(topic);
            if (availablePartitions.size() > 0) {
                int part = Utils.toPositive(nextValue) % availablePartitions.size();
                return availablePartitions.get(part).partition();
            } else {
                // no partitions are available, give a non-available partition
                return Utils.toPositive(nextValue) % numPartitions;
            }
        } else {
            // hash the keyBytes to choose a partition
            return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
        }
    }

因此,由于它的使用模块,它将始终将消息存储在可用分区的范围内,这就是为什么多个键可能进入同一分区。消息密钥的主要好处是将相同的消息密钥存储到同一分区。

2。。因此,您不必担心可以根据密钥数定义分区数。如上所述,密钥用于根据默认分区程序逻辑将消息存储到不同的分区。分区号基本上有助于使进程并行化以实现高吞吐量。

  

注意:您还要确保通过使用键来分区数据可能会导致   分配不均等,因此如果您不用担心,请保持键为null,以选择循环上的分区

     

其他方法是创建自定义分区程序,以进一步优化分区选择逻辑。   here