首页 > 解决方案 > 如何将分区拆分为子分区?独特的哈希函数生成器?

问题描述

我有一个带有N分区的 Kafka 主题。记录键是一个 cookie。记录使用公式跨分区分布hash(key) % N

我想以并行方式处理来自分区的记录。假设每个分区都有M分配的工作人员来进行处理。附加要求是由单个工作线程处理相同的 cookie(以保持事件顺序)。

我不知道hash用于分区记录的功能。如果我使用and (尤其是当) ,计算my_hash(key) % M可能无法正常工作。my_hash == hashgcd(N, M) > 1N = M

由于我知道partitionId所有记录,我最初的想法是计算my_hash(key + "." + partitionId) % M,但我想知道这种分桶是否足够好。有一个机会hash(key) == h1(key + "." + (h2(key) % N)) == my_hash(key + "." + partitionId)

我想我应该生成一个独特的哈希函数。你知道这样的发电机吗?

编辑

例子:

Partition1: (cookie1, ...), (cookie1, ...), (cookie3, ...)
Partition2: (cookie2, ...), (cookie2, ...), (cookie4, ...)

我想让 2 个线程 ( N = M) 处理每个分区。我不知道hash功能,所以我可能会选择my_hash == hash.

然后我会得到:

Partition1_Subpartition1: (cookie1, ...), (cookie1, ...), (cookie3, ...)
Partition1_Subpartition2: <always_empty>
Partition2_Subpartition1: <always_empty>
Partition2_Subpartition2: (cookie2, ...), (cookie2, ...), (cookie4, ...)

而是更好的拆分,例如:

Partition1_Subpartition1: (cookie3, ...)
Partition1_Subpartition2: (cookie1, ...), (cookie1, ...)
Partition2_Subpartition1: (cookie4, ...)
Partition2_Subpartition2: (cookie2, ...), (cookie2, ...)

标签: hashapache-kafkapartitioningkafka-consumer-api

解决方案


Kafka 消费者需要在自己的单独线程中运行。不可能(或不建议)在多个消费者之间共享一个线程。所以,如果你有M线程,这意味着你有M消费者。现在,让我们来满足您的要求:

我想用 M 个线程以并行方式读取主题,以便单个线程读取具有相同 cookie 的所有记录。

这句话本身在我看来有点模糊。因为默认的散列函数确保相同的 cookie 总是会出现在同一个分区,所以无论如何你的要求都会得到满足。

我想让 2 个线程(N = M)处理每个分区。

您的意思是,您希望每个分区由两个消费者线程处理吗?这是不可能的,除非他们在不同的消费者群体中,我认为这不是你想要的。

现在,您是否尝试基于某些功能(可能是时间戳或其他)将特定键(cookie)重定向到不同的分区,如果您知道,它可以转到集合中的任何分区(p1,p2 , ... pn) 那么你想让一个消费者消费所有这些 n 个分区吗?那么如果同一个 cookie 的所有出现都出现在同一个分区中,那么与这种情况相比,你会得到什么?因为最终它是消费它的同一个 Kafka 消费者线程。而且,沿着同一条线,我认为如果您的 Kafka 消费者线程将处理作业委托给线程池(您可能正在谈论),那么您是从同一分区还是从一组不同的分区中使用相同的密钥也没关系分区,线程池大小将决定您将实现多少并行度。


推荐阅读