我有一个流,其中记录按顺序到达 . 我应用了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]接收元素 . 如果仅在子任务之间维护排序,那么每个密钥中的排序如何得以保留?
1 回答
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)
之前到达 .