Kafka Streams 如何处理包含不完整数据的分区?
How does Kafka Streams work with Partitions that contain incomplete Data?
Kafka Streams 引擎将分区映射到恰好一个工作程序(即 Java 应用程序),以便该分区中的所有消息都由该工作程序处理。我遇到了以下情况,正在尝试了解它是否仍然可行。
我有一个主题 A(有 3 个分区)。发送给它的消息由 Kafka 随机分区(即没有密钥)。我发送给它的消息具有如下架构
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
由于我有 3 个分区,并且消息在它们之间随机分区,相同型号的汽车 可以写入不同的分区。例如
P1
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Toyota", color: "Blue", timeStampEpoch: 14334343342}
P2
{carModel: "Toyota", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Nissan", color: "Blue", timeStampEpoch: 14334343342}
P3
{carModel: "Nissan", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Nissan", color: "Blue", timeStampEpoch: 14334343342}
现在假设我想计算 carModel 看到的 汽车总数。我编写了一个 Kafka Streams 应用程序来监听主题 A,通过 carModel 映射消息,即
carStream.map((key, value) -> KeyValue.pair(value["carModel"], value))
并将总数写入另一个主题 B,形式为
的消息
{carModel: "Nissan", totalCount: 5}
然后我启动它的 3 个实例,都是 同一个消费者组 的一部分。然后,Kafka 会有效地将每个分区映射到其中一个工作人员。例子
P1 --> Worker A
P2 --> Worker B
P3 --> Worker C
但是,由于每个 Worker 只能看到 1 个分区,因此它只会看到每个车型的部分信息。它将丢失来自其他分区的相同车型的数据。
问:我的理解是否正确?
如果是这样,我可以想象我可以通过 carModel 重新分区(即重新洗牌)我的数据以使这个用例正常工作。
但我只是想确保我没有误解这是如何工作的,事实上 Kafka 确实神奇地处理了我在应用程序中进行内部映射后的重新分区。
Kafka Streams 将自动对您的数据进行重新分区。您的程序将类似于:
stream.map(...).groupByKey().count();
对于这种模式,Kafka Streams 检测到您在 map
中设置了一个新键,因此将在后台自动创建一个主题来为 groupByKey().count()
步骤(从 v0 开始)重新分区数据.10.1 通过 KAFKA-3561).
Note, map()
"marks" the stream that it requires repartitioning and .groupByKey().count()
will create the topic for repartitioning. With this regard, repartitioning is "lazy", i.e., it is only done if required. If there is no .groupByKey().count()
there would be no repartitioning introduced.
基本上,上述程序的执行方式与
相同
stream.map(...).through("some-topic").groupByKey().count();
Kafka Streams 自动 "insert" through()
步骤,从而计算出正确的结果。
If you are using Kafka Streams 0.10.0, you will need to create the repartition topic manually with the desired number of partitions and you will need to add the call to through()
to your code, too.
Kafka Streams 引擎将分区映射到恰好一个工作程序(即 Java 应用程序),以便该分区中的所有消息都由该工作程序处理。我遇到了以下情况,正在尝试了解它是否仍然可行。
我有一个主题 A(有 3 个分区)。发送给它的消息由 Kafka 随机分区(即没有密钥)。我发送给它的消息具有如下架构
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
由于我有 3 个分区,并且消息在它们之间随机分区,相同型号的汽车 可以写入不同的分区。例如
P1
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Toyota", color: "Blue", timeStampEpoch: 14334343342}
P2
{carModel: "Toyota", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Nissan", color: "Blue", timeStampEpoch: 14334343342}
P3
{carModel: "Nissan", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Honda", color: "Red", timeStampEpoch: 14334343342}
{carModel: "Nissan", color: "Blue", timeStampEpoch: 14334343342}
现在假设我想计算 carModel 看到的 汽车总数。我编写了一个 Kafka Streams 应用程序来监听主题 A,通过 carModel 映射消息,即
carStream.map((key, value) -> KeyValue.pair(value["carModel"], value))
并将总数写入另一个主题 B,形式为
的消息{carModel: "Nissan", totalCount: 5}
然后我启动它的 3 个实例,都是 同一个消费者组 的一部分。然后,Kafka 会有效地将每个分区映射到其中一个工作人员。例子
P1 --> Worker A
P2 --> Worker B
P3 --> Worker C
但是,由于每个 Worker 只能看到 1 个分区,因此它只会看到每个车型的部分信息。它将丢失来自其他分区的相同车型的数据。
问:我的理解是否正确?
如果是这样,我可以想象我可以通过 carModel 重新分区(即重新洗牌)我的数据以使这个用例正常工作。
但我只是想确保我没有误解这是如何工作的,事实上 Kafka 确实神奇地处理了我在应用程序中进行内部映射后的重新分区。
Kafka Streams 将自动对您的数据进行重新分区。您的程序将类似于:
stream.map(...).groupByKey().count();
对于这种模式,Kafka Streams 检测到您在 map
中设置了一个新键,因此将在后台自动创建一个主题来为 groupByKey().count()
步骤(从 v0 开始)重新分区数据.10.1 通过 KAFKA-3561).
Note,
map()
"marks" the stream that it requires repartitioning and.groupByKey().count()
will create the topic for repartitioning. With this regard, repartitioning is "lazy", i.e., it is only done if required. If there is no.groupByKey().count()
there would be no repartitioning introduced.
基本上,上述程序的执行方式与
相同stream.map(...).through("some-topic").groupByKey().count();
Kafka Streams 自动 "insert" through()
步骤,从而计算出正确的结果。
If you are using Kafka Streams 0.10.0, you will need to create the repartition topic manually with the desired number of partitions and you will need to add the call to
through()
to your code, too.