我有一个在 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 不一致。