Flink Window官网翻译

原文地址

https://ci.apache.org/projects/flink/flink-docs-release-1.12/dev/stream/operators/windows.html

简介

对 flink 官网的 window 介绍的翻译。(不是很全)

Windows

Windows 是无限流的重要核心。将 stream 放到有限的 bucket 中,在 window中我可以执行计算。这篇文章聚焦,window 如何执行,以及程序员,如何通过提供的function受益。

一个 Fink window 程序,通常如下结构。第一部分:keyed streams。第二部分:no-keyed。区别在于(keyby(…)和 window(…) 变成了 windowAll(…)).也可以作为下面文章的,路线图(目录)。

KeyedWindows

    stream
        .keyBy(...) <- 
        .window(...) <- 需要:分配器。
        [.trigger(...)] <- 可选项:触发器。(或者默认的触发器)
        [.evictor(...)] <- 可选项:清除器。(或者 no 清除器)
        [.allowLateness(...)] <- 可选项: lateness(或者 0)
        [.sideOutPutLateData(...)] <- 可以选项:output tag(或者 no 侧输出流 for 延迟数据)
        .reduce/aggregate/fold/apply() <- 必填:"function"
        [.getSideOutput(...)] <- 可选项:

Non-Keyed Windows

stream
       .windowAll(...)           <-  required: "assigner"
      [.trigger(...)]            <-  optional: "trigger" (else default trigger)
      [.evictor(...)]            <-  optional: "evictor" (else no evictor)
      [.allowedLateness(...)]    <-  optional: "lateness" (else zero)
      [.sideOutputLateData(...)] <-  optional: "output tag" (else no side output for late data)
       .reduce/aggregate/fold/apply()      <-  required: "function"
      [.getSideOutput(...)]      <-  optional: "output tag"

上面,[] 中的都是可选的。这些暴露允许,你自定义wind逻辑适应你的需求。

Window 生命周期

简单说,当属于这个窗口的第一条数据到来的时候,window 被创建;当时间(时间或者处理时间)大于他的结束时间戳+延迟时间,window 被移除。Flink 保证只移除基于时间的窗口,其他窗口不移除。例如:全局窗口。例如:一个基于时间策略的窗口,5分钟,和允许1分钟延迟。Flink 将在12:00,12:05之间,第一个数据到来的时候创建,当水印超过,12:06 的时候移除。
此外,每个window 关联有,有一个 trigger,和一个 function(ProcessWindowFunction,ReduceFunction,或者AggregateFunction)。这个Function包含对 window 内容 的计算,trigger 指定了,窗口运行function的条件。一个 Trigger 策略,可以是:elements 超过4个,或者水印超过 window 的结束时间,也可以决定在窗口的创建和移除中间的任何时间,清除window内容,在本例子中,清除仅仅指窗口中的数据,和 window 的元数据没关系,也就是说新的数据依然可以被加到这个window中。
你还可以指定 Evictor,Evictor可以移除wind中的elements,当trigger 被触发和 function被运行前后。

Keyed ,Non-Keyed Windows

通过 keyBy() 就是,keyed streams,没有 调用 keyBy() 就是 no-keyed stream。
在 keyed steams 中,事件的任何的属性都可以当做 key。Keyed Stream 允许wind并行的多个子任务中计算。相同的 key 被送到相同的 并行任务中。
在 non-keyed streams ,中原始的 stream 不会 split into 多个逻辑流中,所有的窗口逻辑在一个任务中运行。也就是说,并行度是1

window 分配器。

在指定你的 stream 是否 keyed 后,下一步就是定义一个 window 分配器。分配器,定义,element 如何被分配到 windows 中。

window Functions

在定义 window 分配器后,我们需要指定我们想在 windows 中执行的计算。这就是,window function:当系统决定 window 准备好被处理了,被用于处理窗口中的每个元素,。
window function 可以是 reduceFunction,aggregateFunction,或者 ProcessWindowFunction。前两个更高效,因为Flink 可以增量聚合元素。ProcessWindowFunction 有一个窗口中所有元素的迭代器,还有元素所属的wind信息。
ProcessWindowFunction没有另外两个高效,因为Flink 需要 buffer Wind中的所有元素。这个问题,通过,联合 ProcessWindowFunction 和 Reduce,Agg可以缓解,

ReduceFunction

(T,T)-> T

AggregateFunction

AggregateFunction 是 ReduceFunction 的一般形式。(IN,ACC)->(OUT)。IN 就是元素类型,Add In 同ACC。

ProcessWindowFunction

ProcessWindowFunction,有一个迭代器,一个Context(包含时间,状态等信息,可以提供更多的灵活性

ProcessWindowFunction with Incremental Aggregation

ProcessWindowFunction 可以联合 ReduceFunction 和 AggregateFunction去增量聚合元素。当窗口 closed,ProcessWindFunction提供聚合结果。这允许,ProcessWindowFunction 获得额外窗口信息的时候进行增量聚合。
NOTE
你可以使用遗留的 WindowFunction 代替 ProcessWindowFunction。

在 ProcessWindowFunction 中 Using per-window 状态

ProcessWindowFunction 不仅可以使用 keyed state,并且可以用 window 范围的 keyed state。在这种情况下,理解窗口state指向什么很重要。有不同的 windows。

  • 定义的窗口:例如,指定滑动时间,滚动时间。
  • 定义的窗口 for given key 的实例:例如:timeWindow from 12:00 to 13:00 for user-id xyz。这个依赖于窗口的定义和将会有很多窗口,依赖于 keys 的数量。(其实就是说,根据窗口的定义,和 处理的event 落到那个时间段,会产生很多的 window 实例)

Per-window state 和窗口的实例关联。就说,如果我们处理1000 个不同的 keys 并且 fall into [12:00,13:00) 。将会有1000 个window 实例,并且每个 window实例有他自己的状态。

Context有两种类型的state

  • globalState(),
  • windowState()

NOTE 下面是自己的测试,不是官方文档上的。

   new ProcessWindowFunction<WordWithCount, WordWithCount, Tuple, TimeWindow>() {
    @Override
    public void process(Tuple tuple, Context context, Iterable<WordWithCount> elements, Collector<WordWithCount> out) throws Exception {
        // 测试 globalstate(一直累加)
        ValueState<Long> gls = context.globalState().getState(new ValueStateDescriptor<Long>("gls", Long.class));
        for (WordWithCount element : elements) {
            if (gls.value() == null) {
                gls.update(0L);
            }
            gls.update(gls.value() + 1);
        }
        System.out.println(gls.value());
        // 测试 window state(当前窗口实例有效)
        ValueState<Long> ws = context.windowState().getState(new ValueStateDescriptor<Long>("ws", Long.class));
        for (WordWithCount element : elements) {
            if (ws.value() == null) {
                ws.update(0L);
            }
            ws.update(ws.value() + 1);
        }
        System.out.println(ws.value());
        out.collect(new WordWithCount("", ws.value()));
    }
}

WindowFunction(Legacy)过期的

trigger

一个 trigger 决定一个 window 什么时候 is ready被 window function 处理。每个 windowAssigner 有默认的 trigger。默认trigger 不能满足你的需要,你可以指定自定义的 trigger(…)

Trigger 接口有5 个方法,对不同的 events 做出反应。

  • onElement():每个元素加入 window 的时候。
  • onEventTime():当注册的event-time 触发的时候。
  • onProcessingTime():当注册的 processing-time 触发的时候。
  • onMerger():?? relevant 相关
  • clear():移除窗口时候

上面的方法,有两件事情需要注意:
1.
2.

Fire and Purge

默认的 Triggers

默认的 windowAssigner 的 trigger 。所有的,event-time window 有默认的 EventTimerTrigger。这个 Trigger触发一次,当水印到达window 的结尾。

  • GlobalWindow 默认的 trigger 是永远不触发,所有你需要自定义 trigger。
  • trigger() 可以覆盖默认的。

创建自定义 Triggers

驱逐者

延迟数据

处理窗口结果

windowed 算子的处理结果是一个 DataStream,没有跟多的窗口信息保留在结果element中,所以你想要meta-inf就要,在 ProcessWindowFunction手动 manually 的将元信息编码进去。唯一的相关信息,set 同 result elements 是时间戳。设置成end时间戳-1,因为窗口结束时间是独占的。窗口操作完成后,总有一个时间戳,(event-time 或者 processing-time)。。。。。

watermarks 和 winddow 的相互作用

https://ci.apache.org/projects/flink/flink-docs-release-1.12/dev/event_time.html
水印到了以后,触发两件事情:

  • 水印触发所有的窗口计算(max 时间戳[end-1]< 新的水印)
  • 水印传递给下游stream。
    NOTE个人理解
    水印会发送给所有的窗口,触发到期的所有窗口。

连续的窗口操作

NOTE 个人
两个 window 操作可以连到一块。

状态大小的考虑

窗口可以定义很长的周期,累加到非常大的状态。下面有一组规则帮助思考这个问题。

  1. flink 为它所属的每个窗口的每个元素拷贝一个副本
  2. reduce 和 aggregate 可以显著的降低存储需求,早点聚合,只每个窗口只保留一个值。相比之下, ProcessWindowFunction 需要保留所有原因
  3. 使用 evictor 可以阻住预聚合,应该所有的元素必须通过 evictor 在应用计算之前。
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值