Apache Flink 中 shuffle() 和 rebalance() 之间的区别



我正在做我的学士学位的最终项目,这是关于Apache Spark Streaming和Apache Flink(仅流媒体)之间的比较,我刚刚到达Flink文档中的"物理分区"。问题是,在本文档中,它没有很好地解释这两种转换的工作原理。直接从文档中:

shuffle():根据均匀分布随机划分元素。

rebalance():对元素进行轮询分区,为每个分区创建相等的负载。对于在存在数据倾斜的情况下进行性能优化非常有用。

来源: https://ci.apache.org/projects/flink/flink-docs-release-1.2/dev/datastream_api.html#physical-partitioning

两者都是自动完成的,所以我的理解是它们都平均地重新分配(shuffle()>均匀分布和rebalance()>循环)和随机数据。然后我推断rebalance()以更好的方式分发数据("每个分区的负载相等"),因此任务必须处理相同数量的数据,但shuffle()可能会创建越来越大的分区。那么,在哪些情况下,您可能更喜欢使用shuffle()而不是rebalance()

我唯一想到的是,rebalance()可能需要一些处理时间,因此在某些情况下,它可能需要更多的时间来进行重新平衡,而不是在未来的转换中改进的时间。

我一直在寻找这个,没有人谈论过这个,只是在 Flink 的邮件列表中,但他们没有解释shuffle()是如何工作的。

感谢 Sneftel 帮助我改进了我的问题,让我重新思考我想问的问题; 感谢蒂尔,他很好地回答了我的问题。 :D

如文档所述,shuffle将随机分发数据,而rebalance将以循环方式分发数据。后者更有效,因为您不必计算随机数。此外,根据随机性,您最终可能会得到某种不那么均匀的分布。

另一方面,rebalance将始终开始将第一个元素发送到第一个通道。因此,如果您只有几个元素(元素比子任务少),那么只有一些子任务会接收元素,因为您总是开始将第一个元素发送到第一个子任务。在流式处理的情况下,这最终应该无关紧要,因为您通常有一个无限的输入流。

这两种方法存在的实际原因是历史原因。 首先介绍shuffle。为了使批处理成为更相似的流式处理 API,随后引入了rebalance

Flink 的这种说法具有误导性:

对于在存在数据倾斜的情况下进行性能优化非常有用。

因为它是用来描述rebalance,而不是shuffle,所以它表明它是区分因素。我对它的理解是,如果有些项目处理速度慢,而有些项目处理速度很快,分区程序将使用下一个免费通道将项目发送到。但事实并非如此,比较rebalanceshuffle的代码.无论rebalance有多忙,它都会添加到下一个频道。

// rebalance
nextChannelToSendTo = (nextChannelToSendTo + 1) % numberOfChannels;
// shuffle
nextChannelToSendTo = random.nextInt(numberOfChannels);

该语句也可以有不同的理解:"负载"并不意味着实际处理时间,只是项目的数量。如果原始分区存在偏差(分区中的项目数差异很大),则该操作将统一将项目分配给分区。但是,在这种情况下,它适用于这两个操作。

我的结论是:shufflerebalance做同样的事情,但rebalance做得稍微好一些。但是差异是如此之小,以至于你不太可能注意到它,java.util.Random可以在我的机器上的单个线程中生成 70m 个随机数。

相关内容

  • 没有找到相关文章