例如,有一个键控流:
+----+---------+------------+
| id | account | expiration |
+----+---------+------------+
| 1 | a | 2017-01-01 |
| 2 | a | 2018-06-01 |
| 3 | b | 2017-01-01 |
| 4 | b | 2018-01-01 |
+----+---------+------------+
我认为这是在Flink中重用相同的流,我发现当我重用它时,流的内容不受其他转换的影响,所以我认为它是同一个流的副本。 / p>
但我不知道它是否正确。
如果是,这将使用大量资源(哪些资源?)来保留副本?
答案 0 :(得分:2)
应用了多个运算符的DataStream
(或KeyedStream
)会复制所有传出消息。例如,如果你有一个程序,如:
val keyedStream: KeyedStream[event, Key] = env
.addSource(...)
.keyBy(...)
val stream1: DataStream = keyedStream.map(new MapFunc1)
val stream2: DataStream = keyedStream.map(new MapFunc2)
程序以
执行 /-hash-> Map(MapFunc1) -> ...
Source >-<
\-hash-> Map(MapFunc2) -> ...
源复制每条记录并将其发送给下游运营商(MapFunc1
和MapFunc2
)。运算符的类型(在我们的示例中为Map)并不重要。
这样做的成本是通过网络发送两次每条记录。如果所有接收运算符具有相同的并行性,则可以通过一次发送每个记录并在接收任务管理器处复制它来优化它,但目前尚未完成。
您可以通过添加单个接收运算符(例如,身份映射运算符)和另一个keyBy
来手动优化程序,从中将叉子分配给多个接收器。这不会导致网络混乱,因为所有记录都已经是本地的。但是,所有运算符必须具有相同的并行性。