窗口操作符行为澄清后的apache flink keyedstream

g2ieeal7  于 2021-06-21  发布在  Flink
关注(0)|答案(2)|浏览(367)

我请求澄清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 = ...;
irlmq6kh

irlmq6kh1#

探索各种场景的作业图的最佳方法是编写一些简单的应用程序,并在flink附带的 Jmeter 板中检查它们的作业图。
我不知道如何解释你在keyby之后显示的扇出,这使得回答你的问题很困难。如果您询问生成的foo数据流的并行性,它可以是您想要的任何形式。
如果keyby前后的并行度都是1,那么流将不会像您所示那样被分割。相反,将有一个窗口操作符来处理所有键(并行性与键的数量无关,尽管键控操作符(例如滑动窗口及其reduce函数)不能利用大于键的数量的并行性。)
但即使在单个节点中,也可以有多个核心,并将窗口操作符的并行度设置为3。reduce函数的结果可以被后续的操作符并行处理,如果你想要的话。但不管并行性如何,这部分作业将只有一个数据流(foo)。
请更新您的问题,如果我误解了它,我会再试一次。

rks48beu

rks48beu2#

我想你真正想问的是你最后是否会 KeyedStream 跟随 reduce 操作。如果是这样的话,那么答案是否定的,你最终会得到一个固定的答案 DataStream .
虽然可以通过 DataStreamUtils.reinterpretAsKeyedStream(DataStream, KeySelector) 把它扔回到一个 KeyedStream ,如果您小心确保没有更改用于创建窗口键的字段值。

相关问题