流式计算中的 Window 计算笔记(一)| 青训营笔记

116 阅读4分钟

流式计算中的 Window 计算笔记(一)| 青训营笔记

这是我参与「第四届青训营 -大数据场」笔记创作活动的第6天

一、流式计算概述

简述流式计算的基本概念,与批式计算相比的难点和挑战

1. 流式计算和批式计算的对比

  • 实时性越高,数据的价值越高
项目批式计算流式计算
数据存储HDFS、HiveKafka、Pulsar
数据时效性天级别分钟级别
准确性精准精准和时效性取舍
典型计算引擎Hive、Spark、FlinkFlink
计算模型Exactly-OnceAt-Least-Once/Exactly-Once
资源模型定时调度长期持有
主要场景离线天级别数据报表实时数仓、实时营销、实时风控

2. 批处理

  • T+1离线计算模型:数据计算是天级别,每天只能看到前一天的计算结果

    • 通常使用Hive/Spark,数据和结果是确定的
  • 小时级批计算

    • 批计算每次需要申请调度资源
    • 计算需要时间

image.png

3. 处理时间窗口

  • 实时计算:处理时间窗口

    • 数据实时流动实时计算
    • 窗口结束直接发送结果不需要周期调度任务

image.png

4. 处理时间vs事件时间

  • 处理时间:数据在流式计算系统中真正处理时所在机器的当前时间
  • 事件时间:数据产生的时间,比如客户端、传感器、后段代码等上报数据的时间

image.png

5. 事件时间窗口

  • 实时计算:事件时间窗口

    • 数据实时进入到真实时间发生的窗口中进行计算
    • 可以有效处理数据延迟和乱序
  • 什么时候窗口算结束?

    • 引用watermark来表示当前的真实时间
    • 数据存在乱序时,可以用来在乱序容忍和实时性间做一个平衡
    • 当收到watermark后有比watermark小的数据时认为是延时数据 舍弃

image.png

6.小结

  • 批式计算一般是T+1的数仓架构
  • 数据实时性越高,数据的价值越高
  • 实时计算分为处理时间和事件时间
  • 事件时间需要Watermark 配合来处理乱序

二、Watermark概述

1. 什么是 Watermark

  • 当前系统认为的事件时间所在的真实时间
  • 当前真实的事件时间

2. 如何产生 Watermark

  • 一般从数据的事件时间来产生
  • 产生策略灵活多样:最常见包括使用当前事件时间的时间减去一个固定的Delay,来表示可以容忍多长时间的乱序

SQL:

CREATE TABLE Orders (
    user BIGINT,
    product STRING,
    order_time TIMESTAMP(3)
    WATERMARK FOR order_time AS order_time - IMTERVAL '5' SECOND
) WITH (...);

DataStream:

WatermarkStrategy
    .<Tuple2<Long,String>>forBoundedOutOfOrderness(Duration.ofSeconds(20))
    .withTimestampAssigner((event, timestamp)->event.f0);

3. 如何传递 Watermark

上下游task之间有数据传递关系时,上游会将watermark传递给下游;下游收到多个上游发来的watermark后,默认取最小值作为自身的watermark,同时将自己的watermark传递给下游;最后所有的算子都会有自己的watermark。

image.png

4. Watermark在生产实践中的问题

4.1 怎么观察一个任务中Watermark多少,是否正常

通过Flink UI观察算子的watermark和subtask的watermark。

4.2 per-partition/per-subtask生成watermark的优缺点
  • per-subtask watermark生成:早期版本机制。典型的问题是如果一个source subtask消费多个partition,那么多个partition之间的数据读取(读取速度不一、系统故障、传输延迟等)可能会加剧乱序程度;
  • per-partition watermark:引入基于每个partition单独的watermark,有效避免乱序度增加;
4.3 如果有部分partition/subtask会断流如何处理

上游subtask的watermark不更新,则下游所有watermark不更新;

  • 解决方法:Idle source

    • 当某个subtask断流超过配置的idle超时时间时,将当前subtask置为idle,并下发一个idle的状态给下游。
    • 下游在计算自身watermark的时候,忽略掉当前是idle的subtask。
4.4 算子对于时间晚于watermark的数据的处理
  • 迟到数据处理:晚于watermark的数据到来时认为是迟到数据,算子自身来决定如何处理迟到数据

    • window聚合:默认丢弃迟到数据
    • 双流join:outer-join则不能join到任何数据
    • CEP:默认丢弃

5. 小结

  • 含义:表示系统认为的当前真实时间
  • 生成:可以通过Watermark Generator来生成
  • 传递:取上游所有subtask的最小值
  • 部分数据断流:ldle Source
  • 迟到数据处理:Window算子是丢弃;Join 算子认为跟之前的数据无法join 到