Apache Flink - 如何对齐 Flink 和 Kafka 分片

3
我正在为高吞吐量的流式应用程序(每秒数千万事件)开发基于DataStream的Flink应用程序。数据从Kafka主题中消费,并已根据某个键分片。我的意图是在Flink端创建特定于键的状态以运行自定义分析。我无法理解的主要问题是如何在不通过keyBy()强制进行传入数据重分区的情况下创建键控状态。
我可以保证Flink作业的最大并行度将小于或等于源Kafka主题中的分区数量,因此逻辑上不需要洗牌。这个StackOverflow问题的答案表明,可能可以以与Flink期望相兼容的方式将数据写入Kafka,然后使用reinterpretAsKeyedStream()。对于这个应用程序,我很乐意这样做。有人能分享所需的步骤吗?
提前感谢您。

这个Flink应用程序的输出是什么?它是类似于摄取服务还是数据处理:过滤、查询等? - themoah
@themoah 这是一个数据处理应用程序,通过过滤和聚合实时金融数据来得出各种分析见解。输出是一系列以秒为精度的桶,其中包含计算出的数据点。 - mr_v
1个回答

3
你需要做的是确保每个事件都被写入到Kafka分区中,以便被分配给相同任务槽的密钥。以下是使其正常工作所需了解的内容:
(1) Kafka分区按循环方式分配给任务槽:分区0分配给槽0,分区1分配给槽1,以此类推,如果分区数超过槽数,则回到槽0。
(2) 将键映射到键组,并将键组分配给槽。键组的数量由最大并行度确定(这是一个配置参数,默认为128)。
通过以下公式计算密钥的键组:
keygroupId = MathUtils.murmurHash(key.hashCode()) % maxParallelism

然后根据情况分配插槽。

slotIndex = keygroupId * actualParallelism / maxParallelism

(3) 接着使用DataStreamUtils.reinterpretAsKeyedStream将预分区的流转换成键值流,以便Flink能够对待。

采用这种方法的一个影响是,如果您需要更改并发度,则会很痛苦。


1
谢谢你,David。无法更改作业的实际并行性确实很不幸。是否有其他设计方法可以考虑? - mr_v
1
不,我看不到。 - David Anderson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接