我有一个流,其中记录按顺序到达。我应用了map函数,然后使用keyBy函数。是否使用相同的密钥在每个记录流中维护记录的顺序?
Ordering of Records in Stream中有类似的问题。但我在那里给出的答案和从“https://ci.apache.org/projects/flink/flink-docs-release-1.2/concepts/programming-model.html”链接复制的以下说明中感到困惑。
“在重新分发的交换中,元素之间的排序仅保留在每对发送和接收子任务中(例如,map()的子任务[1]和keyBy / window的子任务[2]。所以在此例如,保留每个密钥中的排序,但并行性确实引入了关于不同密钥的聚合结果到达接收器的顺序的非确定性。“
在给出的示例中,keyBy的子任务[2]接收来自map的子任务[1]和子任务[2]的元素。如果仅在子任务之间维护排序,那么每个密钥中的排序如何得以保留?
答案 0 :(得分:3)
keyBy操作仅维护来自相同子任务的事件的顺序。对于来自不同子任务的事件,Flink不会给您任何订单保证。
为了说明这一点,假设以下情形:您有两个地图子任务map1
和map2
以及两个接收子任务sink1
和sink2
。在映射器和接收器之间,您可以进行keyBy
操作。
map1
生成以下事件序列(1, A), (2, B), (1, C), (2, D)
和map2
生成(1, U), (1, V), (2, W), (2, X)
,其中第一个元组条目是我们的密钥。这意味着sink1
将收到集{(1, A), (1, C), (1, U), (1, V)}
,而sink2
会收到集{(2, B), (2, D), (2, W), (2, X)}
。
不失一般性,让我们来看看sink1
的顺序。你可以说的是,来自同一个生成子任务的所有事件都按照它们生成的顺序到达。因此,(1, A)
将在(1, C)
之前到达。但是,您无法说明来自不同生成子任务的事件之间的顺序是什么。因此,您不知道(1, A)
是否在(1, U)
之前到达。