首页  

Flink 知识点汇总     所属分类 flink 浏览量 1006
2019 大数据实时计算  流计算
Blink 阿里内部 Flink 分支版本

核心概念和基础  整体架构 核心概念 算子等
进阶          数据传输 容错机制 序列化 数据热点 反压等 
源码          核心代码实现 Job提交流程 数据交换 分布式快照机制 FlinkSQL 



基础篇
Flink简介 分布式处理引擎 用于对无界和有界数据流进行有状态计算 提供 数据分布 容错机制及资源管理等功能 DataSet API 对静态数据进行批处理,将静态数据抽象成分布式数据集 DataStream API 对数据流进行流处理 ,将流式数据抽象成分布式数据流 Table API 对结构化数据进行查询操作,将结构化数据抽象成关系表,通过类SQL的DSL对关系表进行各种查询操作 特定领域的库 FlinkML Flink 机器学习库 Gelly Flink图计算库 CEP 复杂事件处理 支持高吞吐 低延迟 高性能的流处理 支持带有事件时间的窗口 (Window) 操作 支持高度灵活的窗口 (Window) 操作,支持基于 time count session 以及 data-driven 的窗口操作 支持有状态计算的 Exactly-once 语义 支持具有 Backpressure 功能的持续流模型 支持基于轻量级分布式快照(Snapshot)实现的容错 运行时同时支持 Batch onStreaming 处理和 Streaming 处理 Flink 在 JVM 内部实现了自己的内存管理 支持迭代计算 支持程序自动优化 避免特定情况下 Shuffle 排序等昂贵操作,可缓存中间结果
Flink 与 Spark 比较 Flink 是实时处理引擎,基于事件驱动 Spark Streaming 微批(Micro-Batch) 架构模型 Spark Streaming 运行时主要角色 Master Worker Driver Executor Flink 运行时主要包含 Jobmanager Taskmanager和Slot 任务调度 Spark Streaming 连续不断的生成微小的数据批次,构建有向无环图DAG 依次创建 DStreamGraph JobGenerator JobScheduler Flink 根据用户提交的代码生成 StreamGraph,经过优化生成 JobGraph 然后提交给 JobManager进行处理,JobManager 根据 JobGraph 生成 ExecutionGraph ExecutionGraph 是 Flink 调度最核心的数据结构 JobManager 根据 ExecutionGraph 对 Job 进行调度 时间机制 Spark Streaming 只支持处理时间 Flink 支持 处理时间 事件时间 注入时间 支持 watermark机制来处理滞后数据 容错机制 Spark Streaming 任务,可设置 checkpoint 可以从上次 checkpoint 之处恢复,可能会重复处理,不能做到恰好一次处理语义 Flink使用两阶段提交协议来解决该问题
Flink集群角色及作用 Flink 程序 运行时主要有 TaskManager JobManager Client三种角色 JobManager 集群 Master ,整个集群的协调者, 负责接收 Job,协调检查点,Failover 故障恢复等 ,同时管理集群从节点TaskManager TaskManager 负责执行计算的Worker ,执行 Job的一组Task 每个TaskManager负责管理其所在节点上的资源信息,如内存 磁盘 网络 启动时候将资源的状态向JobManager汇报 Client 提交一个Flink程序时,首先创建一个Client 对提交的Flink程序进行预处理 ,然后提交给JobManager
Task Slot TaskManager 将节点上管理的资源分为不同的Slot,固定大小的资源子集 避免不同Job的Task互相竞争内存资源,Slot只做内存隔离,没有做CPU隔离
Flink 常用算子 Map Filter KeyBy Reduce Window
分区策略 分区策略用来决定数据如何发送至下游 GlobalPartitioner ShufflePartitioner RebalancePartitioner RescalePartitioner BroadcastPartitioner ForwardPartitioner KeyGroupStreamPartitioner CustomPartitionerWrapper 用户自定义分区器 实现Partitioner接口 public interface Partitioner< K> extends java.io.Serializable, Function { int partition(K key, int numPartitions); }
并行度设置 任务并行执行 可以从四个不同层面设置并行度 操作算子层面(Operator Level) 执行环境层面(Execution Environment Level) 客户端层面(Client Level) 系统层面(System Level) 优先级 算子层面 > 环境层面 > 客户端层面 > 系统层面
Slot和parallelism slot是指taskmanager的并发执行能力 taskmanager.numberOfTaskSlots 配置为3 那么每个 taskmanager 中分配3个 TaskSlot 3个 taskmanager 一共有9个TaskSlot parallelism.default parallelism 并行度 并发度
重启策略 固定延迟重启策略(Fixed Delay Restart Strategy) 故障率重启策略(Failure Rate Restart Strategy) 没有重启策略(No Restart Strategy) Fallback重启策略(Fallback Restart Strategy)
Flink中的分布式缓存 taskmanager 本地缓存,避免重复读取数据 org.apache.flink.api.java.ExecutionEnvironment public void registerCachedFile(String filePath, String name) public void registerCachedFile(String filePath, String name, boolean executable) val env = ExecutionEnvironment.getExecutionEnvironment // register a file from HDFS env.registerCachedFile( "hdfs:///path/to/your/file", "hdfsFile") // register a local file env.registerCachedFile( "file:///path/to/exec/file", "localExecFile", true)
Flink中的广播变量 可理解为一个共享变量,可以把一个dataset 数据集广播出去 然后不同的task在节点上都能够获取到,在每个节点上只会存在一份
窗口 time-tumbling-window 不重叠 timeWindow(Time.seconds(5)) time-sliding-window 有重叠 timeWindow(Time.seconds(5), Time.seconds(3)) count-tumbling-window countWindow(5) count-sliding-window countWindow(5,3) org.apache.flink.streaming.api.datastream.KeyedStream.timeWindow(Time, Time) public WindowedStream< T, KEY, TimeWindow> timeWindow(Time size, Time slide) DataStream< WordWithCount> windowCounts = ... .keyBy("word") .timeWindow(Time.seconds(5), Time.seconds(1)) .reduce(new ReduceFunction< WordWithCount>() { public WordWithCount reduce(WordWithCount a, WordWithCount b) { return new WordWithCount(a.word, a.count + b.count); } });
状态存储 计算过程存储中间状态 避免数据丢失和状态恢复 影响状态持久化 checkpoint 保存点 MemoryStateBackend FsStateBackend RocksDBStateBackend
流处理中的时间 事件时间 摄入时间 处理时间 EventTime EventTimeWindow IngesingtTime IngestingTimeWindow 以 source 的systemTime为准 ProcessingTime ProcessingTimeWindow 以 operator 的systemTime 为准
Watermark 概念和作用 Watermark 是 为了处理 EventTime 窗口计算提出的一种机制, 本质上是一种时间戳 Watermark 和 Window 一起用来处理乱序事件
Flink Table & SQL TableEnvironment的作用 TableEnvironment作用 在内部catalog中注册表 注册外部catalog 执行SQL查询 注册用户定义(标量,表或聚合)函数 将DataStream或DataSet转换为表 持有对ExecutionEnvironment或StreamExecutionEnvironment的引用
Flink SQL SQL解析基于 Apache Calcite SQL解析过程 使用 SQL 开发业务应用 用calcite对SQL进行语法检验 转换成逻辑树节点 ,最终形成逻辑计划 采用Flink自定义的优化规则和calcite火山模型、启发式模型共同对逻辑树进行优化,生成最优的物理计划 对物理计划采用janino codegen生成代码,生成用低阶API描述的流应用 提交执行
进阶篇
如何支持批流一体 批处理是流处理的一种特殊情况 DataSet API 和 DataStream API DataSet API 会被废弃 DataStream API 可设置成批处理模式
如何做到高效的数据交换 数据在不同的task中进行交换 TaskManager 负责 先从缓冲buffer中收集records,然后再发送 批次发送
如何容错 State CheckPoint savepoint State 存储计算过程中的中间状态 Checkpoint 定时快照 备份状态 分布式快照原理 根据Chandy-Lamport算法 持续创建分布式数据流及其状态的一致快照 核心思想是在 input source 端插入 barrier, 控制 barrier 的同步来实现 snapshot 的备份和 exactly-once 语义
如何保证Exactly-once语义 幂等 和 事务 两阶段提交 两阶段提交和状态保存来实现端到端的一致性语义 开始事务(beginTransaction)创建一个临时文件夹,写入数据 预提交(preCommit)将内存中缓存的数据写入文件并关闭 正式提交(commit)将之前写完的临时文件放入目标目录下 丢弃(abort)丢弃临时文件 若失败发生在预提交成功后,正式提交前。可以根据状态来提交预提交的数据,也可删除预提交的数据。
kafka 连接器 独立的connector模块
内存管理机制 MemorySegment 堆外内存利用 数据超出内存限制,溢写到磁盘 避免序列化开销 直接操作字节 Network Buffers TaskManager启动时分配,每个块是32K,默认分配2048个 taskmanager.network.numberOfBuffers Memory Manage pool MemorySegment块,用于运行时的算子(Sort/Join/Shuffle等) User Code 除了Memory Manager之外的内存用于User code和TaskManager本身的数据结构
序列化 Java自带的序列化和反序列化 占内存 效率低 性能不高 flink序列化机制 包含 类型描述符,泛型类型提取和类型序列化框架 TypeInformation 支持以下几种类型 BasicTypeInfo 任意Java 基本类型或 String 类型 BasicArrayTypeInfo 任意Java基本类型数组或 String 数组 WritableTypeInfo 任意 Hadoop Writable 接口的实现类 TupleTypeInfo 任意的 Flink Tuple 类型 支持Tuple1 to Tuple25 CaseClassTypeInfo 任意的 Scala CaseClass(包括 Scala tuples) PojoTypeInfo 任意的 POJO (Java or Scala) GenericTypeInfo 任意无法匹配之前几种类型的类 针对前六种类型数据集,Flink可自动生成对应的TypeSerializer,高效地对数据集进行序列化和反序列化
Window数据倾斜如何处理 数据进入窗口前做预聚合 重新设计窗口聚合的key
使用聚合函数 GroupBy Distinct KeyBy 等出现数据热点如何处理 在业务上规避这类问题 单独处理热点数据 Key设计 热点key拆分 参数设置 Flink 1.9.0 SQL(Blink Planner) 性能优化中一项重要的改进就是升级了微批模型,即 MiniBatch 缓存一定的数据后再触发处理,以减少对State的访问,从而提升吞吐和减少数据的输出量
Flink任务延迟高如何解决 后台任务管理 查看哪个算子和task出现了反压 最主要的手段是资源调优和算子调优 资源调优 对作业中的Operator的并发数(parallelism) CPU(core) 堆内存(heap_memory)等参数进行调优 作业参数调优 并行度设置 State设置 checkpoint设置
反压机制 内部基于 producer-consumer 模型进行消息传递, 反压基于该模型 高效有界的分布式阻塞队列 下游消费慢,阻塞上游
Flink和Strom反压机制区别 Storm 通过监控 Bolt 中的接收队列负载情况 超过高水位值就会将反压信息写到 Zookeeper Zookeeper 上的 watch 会通知该拓扑的所有 Worker 都进入反压状态,最后 Spout 停止发送 tuple Flink反压使用高效有界的分布式阻塞队列,下游消费慢,阻塞上游 Flink逐级反压,Storm直接从源头降速
Operator Chains(算子链) 尽可能地将operator的subtask链接(chain)在一起形成task 每个task在一个线程中执行 减少线程之间的切换,减少消息的序列化/反序列化,减少数据在缓冲区的交换,减少延迟的同时提高整体的吞吐量 算子链 算子融合
Operator chain 算子链 形成条件 上下游的并行度一致 下游节点的入度为1 上下游节点都在同一个 slot group 中 下游节点的 chain 策略为 ALWAYS(可以与上下游链接 map flatmap filter等默认是ALWAYS) 上游节点的 chain 策略为 ALWAYS 或 HEAD(只能与下游链接,不能与上游链接,Source默认是HEAD) 两个节点间数据分区方式是 forward 没有禁用 chain
Flink1.9新特性 支持hive读写 支持UDF Flink SQL TopN和GroupBy等优化 Checkpoint跟savepoint针对实际业务场景做了优化 Flink state查询
消费kafka数据时如何处理脏数据 处理前加一个fliter算子, 过滤掉脏数据
源码篇
Job提交流程 Job 转化成DAG任务运行 StreamGraph JobGraph ExecutionGraph JobManager与Client的交互基于Akka,消息驱动 整个Flink Job的提交还包含 ActorSystem的创建,JobManager的启动,TaskManager的启动和注册
三层图结构 StreamGraph JobGraph ExecutionGraph StreamGraph 最接近代码所表达的逻辑层面的计算拓扑结构 按照用户代码的执行顺序向StreamExecutionEnvironment添加StreamTransformation构成流式图 JobGraph 从StreamGraph生成,将可以串联合并的节点进行合并, 设置节点之间的边,安排资源共享slot槽位和放置相关联的节点, 上传任务所需的文件,设置检查点配置等 相当于经过部分初始化和优化处理的任务图。 ExecutionGraph 由JobGraph转换而来,包含了任务具体执行所需的内容,是最贴近底层实现的执行图
JobManger作用 负责整个 Flink 集群任务的调度以及资源的管理 从客户端中获取提交的应用,然后根据集群中 TaskManager 上 TaskSlot 的使用情况 为提交的应用分配相应的 TaskSlot 资源并命令 TaskManager 启动 应用 相当于整个集群的 Master 节点 JobManager 和 TaskManager 之间通过 Actor System 通信 获取任务执行的情况并通过 Actor System 将应用的任务执行情况发送给客户端 任务执行过程中, JobManager 会触发 Checkpoint 操作 每个 TaskManager 节点 收到 Checkpoint 指令后,完成 Checkpoint 操作 所有的 Checkpoint 协调过程都在 Fink JobManager 中完成 任务完成后,Flink 将任务执行的信息反馈给客户端,并且释放掉 TaskManager 中的资源
JobManger在集群启动过程中的作用 接收Flink作业,调度Task,收集作业状态和管理TaskManager 包含一个Actor,完成如下操作 RegisterTaskManage SubmitJob CancelJob UpdateTaskExecutionState 由TaskManager发送,用来更新执行节点(ExecutionVertex)的状态 RequestNextInputSplit TaskManager上的Task请求下一个输入split,成功则返回NextInputSplit,否则返回null JobStatusChanged 作业状态变化(RUNNING, CANCELING, FINISHED等)
TaskManager作用 相当于整个集群的 Slave 节点,负责具体的任务执行和对应任务在每个节点上的资源申请和管理 客户端提交任务给 JobManager JobManager 根据已注册的 TaskManager 资源情况 将任务分配给TaskManager节点,然后启动并运行任务 TaskManager 使用 Slot 资源启动 Task, TaskManager 之间的数据交互 多个任务和 Task 之间通过 TaskSlot 方式共享系统资源 TaskManager 管理多个 TaskSlot 资源池 启动流程 org.apache.flink.runtime.taskmanager.TaskManager selectNetworkInterfaceAndRunTaskManager 启动后向JobManager注册,注册完成后,进行部分模块的初始化
计算资源调度机制 Task slot 多个task运行在同一个JVM中
数据抽象及数据交换过程 MemorySegment 32kb 内存块 堆内或堆外内存 Buffer StreamRecord
分布式快照机制 分布式数据流和操作算子状态的一致性快照 一致性checkpoint,在发生故障时回滚 基于Chandy-Lamport算法 barriers在数据流源处被注入并行数据流中 快照n的barriers被插入的位置(称之为Sn)是快照所包含的数据在数据源中最大位置 例如,在Kafka中,此位置是分区中最后一条记录的偏移量 将该位置报告给checkpoint协调器(JobManager) 然后barriers向下游流动 当一个中间操作算子从其所有输入流中收到快照n的barriers时 它会为快照n发出barriers进入其所有输出流中 一旦sink操作算子(流式DAG的末端)从其所有输入流接收到barriers n,它就向checkpoint协调器确认快照n完成 在所有sink确认快照后,意味快照着已完成 一旦完成快照n job将永远不再向数据源请求Sn之前的记录
FlinkSQL实现 SQL 校验 解析以及 优化交给 Apache Calcite SQL query 经过 Calcite 解析器转变成 SQL 节点树 通过验证后构建成 Calcite 的抽象语法树 Table API 上的调用构建成 Table API 的抽象语法树 通过 Calcite 提供的 RelBuilder 转变成 Calcite 的抽象语法树 然后依次转换成逻辑执行计划和物理执行计划
小巧的Java编译器 Janino flink流处理WordCount 实例

上一篇     下一篇
flink 运行模式 批处理与流处理模式

BigDecimal 使用注意点

小巧的Java编译器 Janino

Flink Watermark 机制

Spark核心设计思想

spark 原理及特点