Flink

一、Flink 是什么?

Flink是一个框架和分布式处理引擎,用于在无边界和有边界的数据流上进行有状态的计算

无界流:有定义流的开始 但是没有定义流的结束,会无休无止的产生数据。无界流必须持续处理,即数据被摄取后立刻处理

有界流:有定义流的开始也有定义流的结束。有界流可以在摄取所有数据后再进行计算。

二、Flink的状态:

Flink分为Operator State算子状态和Keyed State

Operator State

分为三种数据结构:

  1. 列表状态:状态表示一组数据的列表
  2. 联合列表状态:在发生故障时或从保存点(savePoint)启动应用程序时如何恢复
  3. 广播状态:如果一个算子有多项任务,而它的每项任务状态都相同,这种情况适合用广播状态

Keyed State

  1. 只能在keyed Stream (keyby)算子处理后
  2. 一般keyBy进行hashcode 重分区户基于它自己独享的内存空间就会针对每一个不同的key
  3. 分别保存一份独立的存储状态,而且接下来来了一个新的数据只能访问自己的状态,不能访问其他的key的,Flink会为每一个key维护一个状态

有状态计算:在程序计算中 Flink程序内部存储计算产生结果并提供给后续的Function活算子计算结果使用。

三、Time语义

  • processing Time:处理时间
  • Event Time:事件时间
  • Ingestion Time:进入Flink系统的时间

四、Window

window:将一个无限的stream 拆分成有限个bucket

TimeWindow

滚动窗口

  • 依据固定的窗口长度对数据进行分片
  • 特点:时间对齐,窗口长度固定无重叠,如下图

滑动窗口

  • 由固定窗口长度和滑动间隔组成
  • 特点:时间对齐,窗口长度固定有重叠,如下图:

 会话窗口

  • 根据session gap切分不同的窗口,当一个窗口在大于session gap的时间内没有接收到新数据时,窗口关闭。在这种模式下窗口长度是可变的,每个窗口的开始和结束时间并不是确定的。我们可以设置定长的session gap,也可以使用 SessionWindowTimeGapExtractor动态的确定 Session gap的长度
  • 特点:时间 无对齐

countWindow

按照指定的数据条数生成一个window,与时间无关,根据窗口中的相同key元素数量来触发执行,执行时只计算元素数量达到窗口大小的key对应结果

  • 滚动窗口:默认为指定窗口,只需指定窗口大小
  • 滑动窗口:需要指定两个参数:windowSize和slidingSize,假设windowSize=5,slidingSize=2 每个相同key的数据计算一次,每一次计算window满足5个元素

五、windowFunction

  • 增量聚合:ReducingFunction  AggregateFunction
  • 全量聚合:processWindowFunction

六、水位线

watermark 是一种衡量EventTime进展机制,可以设定延迟触发,到了时间窗口不应立刻触发窗口计算,而是等待一段时间

七、基本架构

提交任务流程

client 与JobManager构建AKKA连接,将任务提交到JobManager上,JonManager根据已注册在JobManager中的TaskManager的资源(TaskSolt)情况,将任务分配给有资源的Taskmanager,并命令taskManager 启动任务,taskManager使用slot资源启动task

TaskManager和Task Slot的关系

  • 每个Task Slot 是TaskManager一部分,若一个taskManager有三个solt,则这个三个solt会均分TaskManager的资源(仅内存,不包括CPU),有多个solt 意味着同一个jvm 会有多个子任务,会共享jvm的tcp链接和心跳信息
  • slot的个数是不是subtask个数,一个solt可以有多个subtask,在默认情况下同一个job子任务是可共享一个slot。
  • 任务提交阶段的任务并行度的最大值和集群的slot总数有关系

八、检查点

一致性

  • at-most-once:至多一次,故障发生后计算结果可能丢失
  • at-least-once:至少一次,计算结果可能大于正确值
  • Exactly-once:精确一次

checkPoint

  • Flink快照是基于“轻量级异步快照”,在计算过程中保存中间状态和数据流对应位置,这些保存信息相当于系统的checkpoint。
  • Flink 做分布式快照过程中核心一个元素 Barries的使用,这些Barries 是在数据接入到Flink之初就注入到数据流中,并随着数据流向每个算子,需要说明的有两点:
  • 算子对Barries是免疫的,即Barries 是不参与计算的
  • Barries 和数据的相对位置是保持不变的,而且Barries之间是线性递增的

如下图所示,Barriers将将数据流分成了一个个数据集。值得提醒的是,当barriers流经算子时,会触发与checkpoint相关的行为,保存的barriers的位置和状态(中间计算结果)

对齐机制

接收不止一个数据输入的operator需要基于屏障对齐输入数据流。详述如下:

  • 当operator接收到快照的屏障n 后不能直接处理之后的数据,而是需要等待其他数据快照的屏障n,否则的话会将快照n的数据和快照n+1的数据混在一起,如下图所示:operator 即将要收到数据流1(图中的6,5,4,3,2,1),下面的当成输数据流2好了,当1,2,3在屏障n之后到达operator,这个时候如果数据流1继续流里,那么operator就会包含n屏障之后的数据(1,2,3),但是operator中此刻在接收和处理数据流2,数据(a,b,c)就会和数据流中的(1,2,3)混合

  • 快照n的数据流会被暂时放到一边。从这些数据流中获取到的数据不会被处理,而是存储到一个缓冲中。图中第一个所示,因为数据流2的屏障n还没到,所以operator持续接收1,2,3然而并不做任何处理。但是需要将1,2,3存入到buffer中。此时第二个数据流接到a,b,则直接发送,接到c发送c

  • 一旦最后一个数据流收到了快照n,opertor就会将发出所有阻塞的数据,并发出自己的屏障。如图中第三个所示,operator最后收到了另一个数据流的屏障n,然后再发出a,b,c(图中operator中的c,b,a)以后,发出自己的屏障,这个时候buffer中又增加了一个4,变成(4,3,2,1)。

  • 之后operator会重新开始处理所有的输入数据流,先处理buffer中的数据,处理完之后再处理输入数据流的数据。如图第四个所示,先将buffer中的1,2,3,4先处理完,在接收并处理这两个数据源的数据。

九、Flink分区

GlobalPartitioner:数据被分发到下游算子的第一个实例中进行处理

ShufflePartitioner:数据会被随机分发到下游算子的每个实例

RebalabcePartitioner:数据会被循环发送到下游的每一个实例中进行处理

RescalePartitioner:这种分区器会根据上下游算子并行度,循环方式输入到下游算子的每个实例

BroadcastPartitioner:广播分区会将上游数据输出到下游算子的每个实例找那个,适合于大数据集做join场景

ForwadPartitioner:用户将记录输出到下游本地的算子实例,要求下游算子并行度一样

KeyGroupStreamPartitoner:hash 分区器,根据key的hash值输出到下游算子的实例中

CustomPartitonWrapper:用户自定义分区

十、Flink并行度优先级

算子> 环境> 客户> 系统

十一、Flink重启策略

  • 固定延迟重启策略
  • 达到一定故障率重启
  • 无重启
  • Fallback重启

十二、Flink 广播变量

Flink 计算是在多个 slot中进行的,当我们需要访问同一份数据广播变量就是为了解决这种情况

广播变量可以理解为一个公共的共享变量,我么可以把一个dataSet 数据集广播出去然后不同的task在节点上都可以获取到,这个数据只会在每个节点存一份。

十三、Flink状态存储

MemoryStateBackend:

MemoryStateBackend 将工作状态数据保存在 taskmanager 的 java 内存中。key/value 状态和 window 算子使用哈希表存储数值和触发器。进行快照时(checkpointing),生成的快照数据将和 checkpoint ACK 消息一起发送给 jobmanager,jobmanager 将收到的所有快照保存在 java 内存中。

适用场景

  • 每个 state 的默认大小被限制为 5 MB(这个值可以通过 MemoryStateBackend 构造函数设置)
  • 每个 task 的所有 state 数据 (一个 task 可能包含一个 pipline 中的多个 Operator) 大小不能超过 RPC 系统的帧大小(akka.framesize,默认 10MB)
  • jobmanager 收到的 state 数据总和不能超过 jobmanager 内存

FsStateBackend

FsStateBackend 需要配置一个 checkpoint 路径,例如“hdfs://namenode:40010/flink/checkpoints” 或者 “file:///data/flink/checkpoints”,我们一般配置为 hdfs 目录
FsStateBackend 将工作状态数据保存在 taskmanager 的 java 内存中。进行快照时,再将快照数据写入上面配置的路径,然后将写入的文件路径告知 jobmanager。jobmanager 中保存所有状态的元数据信息(在 HA 模式下,元数据会写入 checkpoint 目录)。
FsStateBackend 默认使用异步方式进行快照,防止阻塞主线程的 pipline 处理。可以通过 FsStateBackend 构造函数取消该模式。

FsStateBackend 适合的场景:

  • 大状态、长窗口、大键值(键或者值很大)状态的作业
  • 适合高可用方案

RocksDBStateBackend

RocksDBStateBackend 也需要配置一个 checkpoint 路径
RocksDB 是一种可嵌入的持久型的 key-value 存储引擎,提供 ACID 支持。由 Facebook 基于 levelDB 开发,使用 LSM 存储引擎,是内存和磁盘混合存储。
RocksDBStateBackend 将工作状态保存在 taskmanager 的 RocksDB 数据库中;checkpoint 时,RocksDB 中的所有数据会被传输到配置的文件目录,少量元数据信息保存在 jobmanager 内存中( HA 模式下,会保存在 checkpoint 目录)。
RocksDBStateBackend 使用异步方式进行快照。
RocksDBStateBackend 的限制:

  • 由于 RocksDB 的 JNI bridge API 是基于 byte[] 的,RocksDBStateBackend 支持的每个 key 或者每个 value 的最大值不超过 2^31 bytes((2GB))。
  • 要注意的是,有 merge 操作的状态(例如 ListState),可能会在运行过程中超过 2^31 bytes,导致程序失败。

RocksDBStateBackend 适用于以下场景:

  • 超大状态、超长窗口(天)、大键值状态的作业
  • 适合高可用模式

使用 RocksDBStateBackend 时,能够限制状态大小的是 taskmanager 磁盘空间(相对于 FsStateBackend 状态大小限制于 taskmanager 内存 )。这也导致 RocksDBStateBackend 的吞吐比其他两个要低一些。因为 RocksDB 的状态数据的读写都要经过反序列化/序列化。

RocksDBStateBackend 是目前三者中唯一支持增量 checkpoint 的。

十四、FinkSQL执行流程

  • 用户使用对外提供Stream Sql语法开发业务应用
  • 用 calcite 对 Stream Sql进行语法检验,通过后转换为 calcite 逻辑树节点,最终形成calcite逻辑计划
  • 采用Flink自定义的优化规则和calcite火焰山模型启发式模型共同对逻辑树优化生成Flink最终的物理计划
  • 对物理计划采用 janino codegen 生成代码,生成低阶 API DataStream 描述流应用 提交到Flink平台

十五、Flink如如何保持高效的数据交换

taskManager 网络组建从buffer中得到record再发送

十六、Flink 如何保证exactly-once:

  • 开始事务:创建一个副本
  • 预提交:将内存中缓存数据写入文件并关闭
  • 正式提交:将之前写完的临时文件放入目标目录上
  • 合并:合并临时文件

十七、Flink内存管理

  •  Network Buffers:这个是在TaskManager启动的时候分配的,这是一组用于缓存网络数据的内存,每个块是32K,默认分配2048个,可以通过“taskmanager.network.numberOfBuffers”修改
  • Memory Manage pool:大量的Memory Segment块,用于运行时的算法(Sort/Join/Shufflt等),这部分启动的时候就会分配。下面这段代码,根据配置文件中的各种参数来计算内存的分配方法。),内存的分配支持预分配和lazy load,默认懒加载的方式。
  •  User Code,这部分是除了Memory Manager之外的内存用于User code和TaskManager本身的数据结构。

十八、Flink三层图

  • StreamGraph :逻辑层面的计算拓扑结构

  • 按照用户代码的执行顺序向 StreamExecutionEnvironment 添加 StreamTransformation 构成流式图。
  • JobGraph :经过部分吃屎和和优化处理的任务图
  • JobGraph 从 StreamGraph 生成,将可以串联合并的节点进行合并,设置节点之间的边,安排资源共享 slot 槽位和放置相关联的节点,上传任务所需的文件,设置检查点配置等
  • ExecutionGraph :包含了任务具体执行内容的、最贴近底层实现的执行图。
     

十九、Flink调优

  • 看是否产生背压:数据的序列化和反序列化造成性能性能影响,一些数据结构使用keyBy影响性能,是否频繁的gc
  • 看延迟的指标和吞吐:checkPoint时间过长能在一定程度上影响job的吞吐
  • 提高资源使用率
  • 是否发生数据倾斜
  • 源头和数据源并发度是否保持一致
  • 非堆内存调优
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值