Flink中的Window计算(上)|青训营笔记

101 阅读3分钟

这是我参与「第四届青训营」笔记创作活动的第五天。

基本概念

Task:物理流程图上的节点,是数据流计算的基本工作单元,由Flink运行时来调度执行。任务代表了一个算子或者算子链的并行实例。

Sub-Task:它负责处理数据流分区上的任务。子任务代表的是同一个算子或者算子链具有多个并行的任务。

Operator:对数据流当中的元素进行计算处理操作,如source、sink

slot:TM中的最小资源调度单位,表示一个TM进程处理多少个子任务数。

Shuffle:可分为sort-shuffle、hash-shuffle,主要作用是上下游数据交换时将数据持久化到外部存储,便于下游算子并行地处理数据。

聚集函数(aggregate function):运行在行组上,返回单个值的函数; TVF(table valued function)表值函数,返回表类型数据的函数

State

State一般被认为是缓存在内存或存储系统上的中间数据,如各算子正在处理的数据或读取数据的偏移量等等。

状态快照是Flink实现Exactly-Once语义的基础

Flink基本类型有两种状态:托管状态(Managed State)和原生状态(Raw State)

托管状态主要应用于Flink提供的算子,由Flink进行管理、存储、恢复等操作。

原生状态只要应用于用户自定义的算子,由用户进行序列化等操作。

托管状态又可细分为keyed State和Operator State

keyed state用于Keyed Stream(使用keyBy函数分组的数据)上,每个key对应着一个状态,因此可以自动地随着key进行水平地扩展。

Operator State可用于所有算子上,每个算子实例共享一个状态。

Memory/FileSystem/Rocksdb statebackend:将状态数据存储在堆/TM节点内存/Rocksdb中,可以支持的状态大小和窗口长度依次增大。

Window

时间

  • Processing Time:处理时间,算子对数据流进行处理的时间
  • Event Time:事件时间
  • Ingestion Time:摄入时间,即数据流进入Flink应用的时间 Flink中的时间设置:
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

如果要使用Event Time语义,则必须:

  1. 使用一个时间戳为数据流中每个事件的Event Time赋值;
  2. 生成Watermark,用于处理乱序。

WaterMark

WaterMark的生成

watermark是Flink插入数据流的一种特殊数据结构,用以表示系统认为的当前的时间事件。 Flink假设时间戳为t的watermark后的所有数据的时间事件应大于t。

WaterMark的传播

各个算子会维护一个列表存储来自不同上游算子的watermark时间戳,一般依据其中的最小值向下传递

一些问题

  1. per-partition 机制下subtask 消费多个partition的数据可能会加剧乱序程度 per-subtask可以为每个partition单独生成 watermark。
  2. 有部分算子的watermark停滞时可能影响下游算子的watermark更新。一种解决方案是引入周期性根据系统时间生成watermark的机制。或者引入Idle source:当subtask断流时间超过设置的idle超时时间后将其设置为idle,下游算子在计算自身的watermark时将其忽略。
  3. 迟到数据处理,由算子自身决定如何处理。