我要求澄清在事件已通过窗口发送并且应用了某些运算符(例如reduce()或process())之后,Apache Flink(1.6.0)究竟如何处理KeyedStreams中的事件。 / p>
假设在执行键控窗口流上的运算符后,单个节点集群的左边是正好1个DataStream或正好是 k 个DataStream(其中 k 是键的唯一值的数量)?
为澄清起见,请考虑需要从某些来源读取事件,并按 k 键,将键控事件发送到某些窗口流中,进行精简,然后再执行其他任何操作。下面的两个图表中的哪一个实际上可以构建?
图表A
|--------------|
| source |
| (DataStream) |
|--------------|
|
[all events]
|
v
|--------------|
| key by( k ) |
| (KeyedStream)|
|--------------|
/ | \
/ | \
[ k = 1 ] [ k = 2 ] [ k = 3 ]
/ | \
/ | \
v v v
|------------------||------------------||------------------|
| sliding window || sliding window || sliding window |
| (WindowedStream) || (WindowedStream) || (WindowedStream) |
|------------------||------------------||------------------|
| | |
[ k = 1 ] [ k = 2 ] [ k = 3 ]
| | |
v v v
|----------| |----------| |----------|
| reduce | | reduce | | reduce |
|----------| |----------| |----------|
| | |
[ k = 1 ] [ k = 2 ] [ k = 3 ]
| | |
v v v
|--------------| |--------------| |--------------|
| foo | | foo | | foo |
| (DataStream) | | (DataStream) | | (DataStream) |
|--------------| |--------------| |--------------|
图表B
|--------------|
| source |
| (DataStream) |
|--------------|
|
[all events]
|
v
|--------------|
| key by( k ) |
| (KeyedStream)|
|--------------|
/ | \
/ | \
[ k = 1 ] [ k = 2 ] [ k = 3 ]
/ | \
/ | \
v v v
|------------------||------------------||------------------|
| sliding window || sliding window || sliding window |
| (WindowedStream) || (WindowedStream) || (WindowedStream) |
|------------------||------------------||------------------|
| | |
[ k = 1 ] [ k = 2 ] [ k = 3 ]
| | |
v v v
|----------| |----------| |----------|
| reduce | | reduce | | reduce |
|----------| |----------| |----------|
\ | /
\ | /
\ | /
\ | /
\ | /
\ | /
\ | /
[all products]
|
v
|--------------|
| foo |
| (DataStream) |
|--------------|
编辑(2018-09-22)
基于David的回答,我认为我误解了KeyedStreams与窗口或其他流结合使用的确切方式。不知何故,我的印象是KeyedStream通过在幕后创建多个流而不是仅使用同一流将对象按某个值分组在一起来对传入流进行分区。
我认为Flink的作用相当于:
List<Foo> eventsForKey1 = ...;
List<Foo> eventsForKey2 = ...;
List<Foo> eventsForKey3 = ...;
...
List<Foo> eventsForKeyN = ...;
我现在看到Flink实际上在做以下事情:
Map<Key, List<Foo>> events = ...;
答案 0 :(得分:1)
探讨各种情况下工作图的最佳方法是编写一些简单的应用程序,并在Flink随附的仪表板上检查其工作图。
我不确定如何解释在keyBy之后显示的扇出,这很难回答您的问题。如果您询问生成的foo DataStream的并行性,则可以是您想要的任何形式。
如果keyBy前后的并行度均为1,则流不会像您显示的那样被拆分。取而代之的是,只有一个Window运算符可以处理所有键。 (尽管键操作符(例如,滑动窗口及其归约功能)无法利用大于键数量的并行性,但是并行性与键的数量无关。)
但是,即使在单个节点中,您也可以具有多个核心,并将window运算符的并行度设置为3。如果需要的话,reduce函数的结果可以由后续运算符并行处理。但是不管并行性如何,您的那部分工作将只有一个DataStream(foo)。
如果我对它的解释有误,请更新您的问题,然后再试一次。
答案 1 :(得分:0)
我思考您真正要问的是,您是否在KeyedStream
操作之后收到reduce
。如果是这样,那么答案是否定的,所以您会得到常规的DataStream
。
尽管可以通过DataStreamUtils.reinterpretAsKeyedStream(DataStream, KeySelector)
将其强制转换回KeyedStream
,但是如果要确保未更改用于创建密钥的字段值,请注意窗口。