在未加密的 Flink 流中强制执行平衡的并行性
Enforcing well balanced parallelism in a unkeyed Flink stream
基于我对Flink的理解,引入了基于键(keygroups)的并行。但是,假设有人有大量未加密的流并且希望并行完成工作,那么实现这一目标的最佳方法是什么?
如果流有一些字段,人们可能会考虑任意按字段之一进行键控,但这并不能保证工作负载会得到适当的平衡。例如,因为该字段中的一个值可能出现在 90% 的消息中。因此我的问题是:
如何在不事先了解流中内容的情况下,在 Flink 中实施均衡的并行性
我能想到的一个可能的解决方案是为每条消息分配一个随机数(如果您希望并行度为 3,则为 1-3,如果您希望并行度更灵活,则为 1-1000)。但是,我想知道这是否是推荐的方法,因为它感觉不太优雅。
keyBy
是指定流分区的一种方法,它特别有用,因为可以保证具有相同键的所有流元素将一起处理。这是使用 Flink 进行有状态流处理的基础。
然而,如果您不需要使用键分区状态,而是关心确保分区均衡,您可以使用 shuffle()
或 rebalance()
来产生随机或循环分区。有关详细信息,请参阅 docs。如果您想要更明确的控制,您还可以实现自定义分区程序。
顺便说一句,如果您确实想通过随机数作为流的密钥,不要做类似keyBy(new Random.nextInt(n))
的事情。关键选择器必须是确定性的。这是必要的,因为密钥不会随流记录一起移动——相反,密钥选择器函数用于在需要时计算密钥。因此,对于随机键控,向您的事件添加另一个字段并用随机数填充它,并将其用作键。当您想使用键控状态或计时器但没有任何适合用作键的东西时,此技术很有用。
基于我对Flink的理解,引入了基于键(keygroups)的并行。但是,假设有人有大量未加密的流并且希望并行完成工作,那么实现这一目标的最佳方法是什么?
如果流有一些字段,人们可能会考虑任意按字段之一进行键控,但这并不能保证工作负载会得到适当的平衡。例如,因为该字段中的一个值可能出现在 90% 的消息中。因此我的问题是:
如何在不事先了解流中内容的情况下,在 Flink 中实施均衡的并行性
我能想到的一个可能的解决方案是为每条消息分配一个随机数(如果您希望并行度为 3,则为 1-3,如果您希望并行度更灵活,则为 1-1000)。但是,我想知道这是否是推荐的方法,因为它感觉不太优雅。
keyBy
是指定流分区的一种方法,它特别有用,因为可以保证具有相同键的所有流元素将一起处理。这是使用 Flink 进行有状态流处理的基础。
然而,如果您不需要使用键分区状态,而是关心确保分区均衡,您可以使用 shuffle()
或 rebalance()
来产生随机或循环分区。有关详细信息,请参阅 docs。如果您想要更明确的控制,您还可以实现自定义分区程序。
顺便说一句,如果您确实想通过随机数作为流的密钥,不要做类似keyBy(new Random.nextInt(n))
的事情。关键选择器必须是确定性的。这是必要的,因为密钥不会随流记录一起移动——相反,密钥选择器函数用于在需要时计算密钥。因此,对于随机键控,向您的事件添加另一个字段并用随机数填充它,并将其用作键。当您想使用键控状态或计时器但没有任何适合用作键的东西时,此技术很有用。