Apache Flink 中 shuffle() 和 rebalance() 的区别
Difference between shuffle() and rebalance() in Apache Flink
我正在做我学士的期末项目,这是关于 Apache Spark Streaming 和 Apache Flink(仅流媒体)之间的比较,我刚刚到达 Flink 文档中的“物理分区”。问题在于,在本文档中,它没有很好地解释这两个转换是如何工作的。直接来自文档:
shuffle()
: Partitions elements randomly according to a uniform distribution.
rebalance()
: Partitions elements round-robin, creating equal load per partition. Useful for performance optimisation in the presence of data skew.
两者都是自动完成的,所以我的理解是它们都平等地重新分配(shuffle()
> 统一分配 & rebalance()
> 循环法)和随机数据。然后我推断 rebalance()
以更好的方式分布数据(“每个分区的负载相等”),因此任务必须处理相同数量的数据,但 shuffle()
可能会创建更大或更小的分区。 那么,在哪些情况下您可能更愿意使用 shuffle()
而不是 rebalance()
?
我唯一想到的是,可能 rebalance()
需要一些处理时间,因此在某些情况下,它可能需要更多的时间来进行重新平衡,而不是在未来的转换中改进的时间。
我一直在寻找这个,但没有人谈论过这个,只是在 Flink 的邮件列表中,但他们没有解释 shuffle()
是如何工作的。
感谢 Sneftel who has helped me to improve my question asking me things to let me rethink about what I wanted to ask; and to Till 很好地回答了我的问题。 :D
如文档所述,shuffle
将随机分发数据,而 rebalance
将以循环方式分发数据。后者效率更高,因为您不必计算随机数。此外,根据随机性,您最终可能会得到某种不太均匀的分布。
另一方面,rebalance
将始终开始将第一个元素发送到第一个通道。因此,如果你只有很少的元素(元素比子任务少),那么只有一些子任务会接收元素,因为你总是开始将第一个元素发送到第一个子任务。在流式传输的情况下,这最终应该无关紧要,因为您通常有一个无界输入流。
这两种方法存在的实际原因是历史原因。 shuffle
最先介绍。为了让batch an streaming API更像,于是引入了rebalance
。
Flink 的这种说法具有误导性:
Useful for performance optimisation in the presence of data skew.
因为它用于描述 rebalance
,而不是 shuffle
,这表明它是区分因素。我的理解是,如果某些项目处理速度慢而某些项目处理速度快,则分区程序将使用下一个空闲通道将项目发送到。但事实并非如此,比较rebalance
and shuffle
的代码。 rebalance
只是添加到下一个频道,不管它有多忙。
// rebalance
nextChannelToSendTo = (nextChannelToSendTo + 1) % numberOfChannels;
// shuffle
nextChannelToSendTo = random.nextInt(numberOfChannels);
语句也可以换个方式理解:"load"不是实际处理时间,只是条目数。如果您的原始分区存在偏差(分区中的项目数量大不相同),则该操作会将项目统一分配给分区。但是在这种情况下,它适用于两种操作。
我的结论: shuffle
和 rebalance
做同样的事情,但是 rebalance
做的效率稍微高一点。但差异是如此之小,以至于你不太可能注意到它,java.util.Random
在我的机器上可以在单个线程中生成 70m 个随机数。
我正在做我学士的期末项目,这是关于 Apache Spark Streaming 和 Apache Flink(仅流媒体)之间的比较,我刚刚到达 Flink 文档中的“物理分区”。问题在于,在本文档中,它没有很好地解释这两个转换是如何工作的。直接来自文档:
shuffle()
: Partitions elements randomly according to a uniform distribution.
rebalance()
: Partitions elements round-robin, creating equal load per partition. Useful for performance optimisation in the presence of data skew.
两者都是自动完成的,所以我的理解是它们都平等地重新分配(shuffle()
> 统一分配 & rebalance()
> 循环法)和随机数据。然后我推断 rebalance()
以更好的方式分布数据(“每个分区的负载相等”),因此任务必须处理相同数量的数据,但 shuffle()
可能会创建更大或更小的分区。 那么,在哪些情况下您可能更愿意使用 shuffle()
而不是 rebalance()
?
我唯一想到的是,可能 rebalance()
需要一些处理时间,因此在某些情况下,它可能需要更多的时间来进行重新平衡,而不是在未来的转换中改进的时间。
我一直在寻找这个,但没有人谈论过这个,只是在 Flink 的邮件列表中,但他们没有解释 shuffle()
是如何工作的。
感谢 Sneftel who has helped me to improve my question asking me things to let me rethink about what I wanted to ask; and to Till 很好地回答了我的问题。 :D
如文档所述,shuffle
将随机分发数据,而 rebalance
将以循环方式分发数据。后者效率更高,因为您不必计算随机数。此外,根据随机性,您最终可能会得到某种不太均匀的分布。
另一方面,rebalance
将始终开始将第一个元素发送到第一个通道。因此,如果你只有很少的元素(元素比子任务少),那么只有一些子任务会接收元素,因为你总是开始将第一个元素发送到第一个子任务。在流式传输的情况下,这最终应该无关紧要,因为您通常有一个无界输入流。
这两种方法存在的实际原因是历史原因。 shuffle
最先介绍。为了让batch an streaming API更像,于是引入了rebalance
。
Flink 的这种说法具有误导性:
Useful for performance optimisation in the presence of data skew.
因为它用于描述 rebalance
,而不是 shuffle
,这表明它是区分因素。我的理解是,如果某些项目处理速度慢而某些项目处理速度快,则分区程序将使用下一个空闲通道将项目发送到。但事实并非如此,比较rebalance
and shuffle
的代码。 rebalance
只是添加到下一个频道,不管它有多忙。
// rebalance
nextChannelToSendTo = (nextChannelToSendTo + 1) % numberOfChannels;
// shuffle
nextChannelToSendTo = random.nextInt(numberOfChannels);
语句也可以换个方式理解:"load"不是实际处理时间,只是条目数。如果您的原始分区存在偏差(分区中的项目数量大不相同),则该操作会将项目统一分配给分区。但是在这种情况下,它适用于两种操作。
我的结论: shuffle
和 rebalance
做同样的事情,但是 rebalance
做的效率稍微高一点。但差异是如此之小,以至于你不太可能注意到它,java.util.Random
在我的机器上可以在单个线程中生成 70m 个随机数。