我请求澄清apache flink(1.6.0)在通过窗口发送事件并应用某些操作符(如reduce()或process())之后,如何处理keyedstreams中的事件。
假设一个单节点集群,在键控窗口流上的一个操作符被执行之后,是只剩下1个数据流还是只剩下k个数据流(其中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 = ...;
2条答案
按热度按时间irlmq6kh1#
探索各种场景的作业图的最佳方法是编写一些简单的应用程序,并在flink附带的 Jmeter 板中检查它们的作业图。
我不知道如何解释你在keyby之后显示的扇出,这使得回答你的问题很困难。如果您询问生成的foo数据流的并行性,它可以是您想要的任何形式。
如果keyby前后的并行度都是1,那么流将不会像您所示那样被分割。相反,将有一个窗口操作符来处理所有键(并行性与键的数量无关,尽管键控操作符(例如滑动窗口及其reduce函数)不能利用大于键的数量的并行性。)
但即使在单个节点中,也可以有多个核心,并将窗口操作符的并行度设置为3。reduce函数的结果可以被后续的操作符并行处理,如果你想要的话。但不管并行性如何,这部分作业将只有一个数据流(foo)。
请更新您的问题,如果我误解了它,我会再试一次。
rks48beu2#
我想你真正想问的是你最后是否会
KeyedStream
跟随reduce
操作。如果是这样的话,那么答案是否定的,你最终会得到一个固定的答案DataStream
.虽然可以通过
DataStreamUtils.reinterpretAsKeyedStream(DataStream, KeySelector)
把它扔回到一个KeyedStream
,如果您小心确保没有更改用于创建窗口键的字段值。