0

我有一个在 Amazon 的 Kinesis Data Analytics Service(托管 Flink 集群)中运行的 Flink 应用程序。在应用程序中,我从 Kinesis 流 keyBy userId 中读取用户数据,然后聚合一些用户信息。在问了这个问题之后,我了解到 Flink 会在集群中的物理主机之间拆分流的读取。然后,Flink 会将传入的事件转发到将聚合器任务分配给与给定事件对应的键空间的主机。

考虑到这一点,我试图决定使用什么作为我的 Flink 应用程序读取的 Kinesis 流的分区键。我的目标是限制 Flink 集群中主机之间的网络流量,以优化我的 Flink 应用程序的性能。我可以随机分区,因此事件在分片中均匀分布,或者我可以通过 userId 对分片进行分区。

这个决定取决于 Flink 内部是如何工作的。Flink 是否足够聪明,可以为主机上的本地聚合器任务分配一个密钥空间,该密钥空间将对应于同一主机上的 Kinesis 消费者任务正在读取的分片的密钥空间?如果是这种情况,那么按 userId 进行分片将导致网络流量,因为每个事件都由将聚合它的主机流式传输。似乎 Flink 没有明确的方法来做到这一点,因为它不知道 Kinesis 流是如何分片的。

或者,Flink 是否为每个 Flink 消费者任务随机分配一个分片子集以读取并随机分配聚合器任务的一部分键空间?如果是这种情况,那么分片的随机分区似乎会导致最少的网络流量,因为至少有一些事件将被与事件的聚合器任务位于同一主机上的 Flink 消费者读取。这比通过 userId 进行分区然后必须通过网络转发所有事件要好,因为分片的 keySpace 与本地聚合器的分配的 key Space 不一致。

4

1 回答 1

1

10 年前,通过网络传输尽可能少的数据非常重要。5 年来,网络变得如此之快,以至于您注意到通过网络或内存访问大量数据之间几乎没有区别(随机访问当然仍然要快得多),因此我不会为额外的流量而烦恼(除非您必须为此付费)。有趣的是,Google Datastream 开始在两个任务之间将所有数据流式传输到中央 shuffle 服务器,从而有效地使流量翻了一番;但他们仍然在他们的 PB 网络上体验到巨大的加速。

因此,考虑到这一点,让我们转向 Flink。Flink 目前无法动态调整分片,因为它们会随着时间的推移来来去去。在 FLIP-27 的半年内,情况可能会有所不同。

目前,有一种变通方法,目前主要用于 Kafka-land(静态分区)。DataStreamUtils#reinterpretAsKeyedStream允许您指定keyby没有物理洗牌的逻辑。当然,您有责任确保提供的分区符合实际情况,否则您会得到错误的结果。

于 2020-02-18T14:52:09.057 回答