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

时间:2017-05-13 18:18:12

标签: apache partitioning apache-flink flink-streaming bigdata

我正在攻读我的学士学位的最终项目,这是关于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帮助我改进问题的问题,我想让我重新思考一下我想问的问题;和Till谁回答了我的问题。 :d

2 个答案:

答案 0 :(得分:9)

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

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

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

答案 1 :(得分:0)

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

  

在存在数据倾斜的情况下用于性能优化。

由于它用来描述rebalance,而不是shuffle,因此表明它是区别因素。我的理解是,如果某些项目处理缓慢而某些速度很快,则分区程序将使用下一个空闲通道将项目发送至。情况并非如此,请比较rebalanceshuffle的代码。 rebalance只会添加到下一个频道,无论它有多忙。

// rebalance
nextChannelToSendTo = (nextChannelToSendTo + 1) % numberOfChannels;

// shuffle
nextChannelToSendTo = random.nextInt(numberOfChannels);

对语句的理解也有所不同:“加载”并不意味着实际的处理时间,而只是项目的数量。如果您的原始分区有偏斜(分区中的项目数量大不相同),则该操作会将项目统一分配给分区。但是,在这种情况下,这两种操作都适用。

我的结论shufflerebalance的作用相同,但是rebalance的处理效率略高。但是差异是如此之小,以至于您不太可能会注意到它,java.util.Random可以在我的机器上的单个线程中生成70m随机数。