flink面试常见题带答案(持续更新)
- 1. 什么是Apache Flink (为什么使用 Flink 替代 Spark?)
- 2. Flink的核心概念
- 3. 作业在很多情况下有可能会失败。失败之后重新去运行时,我们如何保证数据的一致性?
- 4. Flink的时间语义
- 5. Flink的API可分为哪几层?
- 6. Flink运行时组件
- 7. flink任务提交流程
- 8. flink执行图
- 9. flink的分区策略
- 10. Flink 的状态分为哪两类
- 11.KeyedState都有哪几类
- 12.Flink中watermark的概念
- 13.什么是Flink的全局快照
- 14.为什么需要全局快照
- 15.Flink的容错机制
- 16.Flink是如何实现End-To-End Exactly-once的?
- 17.解释下两阶段提交?
- 18.Flink 的 checkpoint 存在哪里?
- 19.海量 key 去重
- 20.Flink 的 checkpoint 机制对比 spark 有什么不同和优势?
- 21.Flink CEP 编程中当状态没有到达的时候会将数据保存在哪里?
- 22.Flink 程序在面对数据高峰期时如何处理?
- 23.Flink 的运行必须依赖 Hadoop组件吗?
- 24.Flink 资源管理中 Task Slot 的概念
- 25.Flink的重启策略都有哪些?
- 26.Flink中的广播变量,使用时需要注意什么?
- 27.Flink的内存模型
- 28.数据倾斜问题
- 29.Flink连接API
- 30.Flink-On-Yarn常见的提交模式有哪些,分别有什么优缺点?
- 31.Flink如何处理迟到数据
- 32.Flink任务延迟高如何解决
- 33.Flink Operator Chains
- 34.Flink什么情况下才会把Operator chain在一起形成算子链?
- 35.Flink中应用在ableAPI中的UDF有几种?
1. 什么是Apache Flink (为什么使用 Flink 替代 Spark?)
- Apache Flink 是一个开源的基于流的有状态计算架。它是分布式地执行的,具备低延迟、高吞吐的优秀性能,并且非常擅长处理有状态的复杂计算逻辑场景。
2. Flink的核心概念
- Event Streams:即事件流,事件流可以是实时的也可以是历史的。Flink 是基于流的,但它不止能处理流,也能处理批,而流和批的输入都是事件流,差别在于实时与批量。
- State: Flink 擅长处理有状态的计算。通常的复杂业务逻辑都是有状态的,它不仅要处理单一的事件,而且需要记录一系列历史的信息,然后进行计算或者判断
- Time: 最主要处理的问题是数据乱序的时候,一致性如何保证
- Snapshots: 实现了数据的快照、故障的恢复,保证数据一致性和作业的升级迁移等
3. 作业在很多情况下有可能会失败。失败之后重新去运行时,我们如何保证数据的一致性?
- Fink 基于 Chandv-Lampot 算法,会把分布式的每一个节点的状态保存到分布式文件系统里面作为 Checkpoint(检点),过程大致如下。首先,从数据源端开始注入 Checkpoint Barrier,它是一种比较特殊的消息。
- 然后它会跟普通的事件一样随着数据流去流动,当 Barrier 到达算子之后,这个算子会把它当前的本地状态进行快照保存,当 Barrier流动到 Sink,所有的状态都保存完整了之后,它就形成一个全局的快照。
- 这样当作业失败之后,就可以通过远程文件系统里面保存的 Checkpoint 来进行回滚:先把 Source 回滚到 Checkpoint 记录的ofset,然后把有状态节点当时的状态回滚到对应的时间点,进行重新计算。这样既可以不用从头开始计算,又能保证数据语义的一致性。
4. Flink的时间语义
- Event Time: 事件创建的时间
- Ingestion Time: 数据进入Flink的时间
- Processing Time: 执行操作算子的本地系统时间,与机器相关
5. Flink的API可分为哪几层?
- SQL & Tale AP!同时适用于批处理和流处理,这意味着你可以对有界数据流和无界数据流以相同的语义进行查询,并产生相同的结果。除了基本查询外, 它还支持自定义的标量函数,聚合函数以及表值函数,可以满足多样化的查询需求。
- DataStream & DataSet API 是 Flink 数据处理的核心 APL,支持使用 Java 语言或 Scala 语言进行调用,提供了数据读取,数换和数据输出等一系列常用操作的封装。
- Stateful Stream Processing 是最低级别的抽象,它通过 Process Function 函数内嵌到 DataStream AP1 中。ProcessEunction 是 Elink 提供的最底层 API,具有最大的灵活性,允许开发者对于时间和状态进行细粒度的控制。
6. Flink运行时组件
-
- 作业管理器 (JobManager)
- 1.控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的Jobmanager所控制执行
- 2.Jobmanager会先接收到要执行的应用程序,这个应用程序会包括: 作业图(Job Graph) 、逻辑数据流图 (Logical dataflowgraph) 和打包了所有的类、库和其它资源的JAR包。
- 3.Jobmanager会把Jobgraph转换成一个物理层面的数据流图,这个图被叫做“执行图”Executiongraph),包含了所有可以并发执3行的任务。Job Manager会向资源管理器(Resourcemanager) 请求执行任务必要的资源,也就是任务管理器(Taskmanacer)上的插槽slot。一旦它获取到了足够的资源,就会将执行图分发到真正运行它们的 Taskmanager上。而在运行过程中Jobmanagera会负责所有需要中央协调的操作,比如说检查点(checkpoints)的协调。
-
- 任务管理器 (TaskManager)
- 1.Flink中的工作进程。通常在 Flink中会有多个Taskmanager运行,每个Taskmanager都包含了一定数量的插槽(slots)。插槽的数量限制了Taskmanager能够执行的任务数量。
- 2.启动之后,Taskmanager会向资源管理器注册它的插槽,收到资源管理器的指令后,Taskmanager就会将一个或者多个插槽提供给Jobmanager调用。Jobmanager就可以向插槽分配任务(tasks)来执行了。
- 3.在执行过程中,一个Taskmanager可以跟其它运行同一应用程序的Taskmanager交换数据
-
- 资源管理器 (ResourceManager)
- 1.主要负责管理任务管理器(TaskManager)的插槽(slot)Taskmanger插槽是Flink中定义的处理资源单元
- 2.Flink为不同的环境和资源管理工具提供了不同资源管理器,比如YARN、K8s,以及 standalone部署。
- 3.当Jobmanager申请插槽资源时,Resourcemanager会将有空闲插槽的Taskmanager分配给Jobmanager。如果Resourcemanager没有足够的插槽来满足 Jobmanaer的请求,它还可以向资源提供平台发起会话,以提供启动 Taskmanager进程的容器。
7. flink任务提交流程
- 1.Flink任务提交后,Client向HDFS上传Flink的Jar包和配置
- 2.随后向Yarn ResourceManager提交任务,ResourceManager分配Container资源并通知对应的NodeManager启动
- 3.ApplicationMaster,ApplicationMaster启动后加载Flink的Jar包和配置构建环境
- 4.然后启动 JobManager,之后ApplicationMaster向ResourceManager申请资源启动 TaskManager
- 5.ResourceManager分配Container资源后,由ApplicationMaster通知资源所在节点的NodeManager启动TaskManager
- 6.NodeManager加载Flink的Jar包和配置构建环境并启动TaskManager
- 7.TaskManager启动后向JobManager发送心跳包,并等待JobManager向其分配任务
8. flink执行图
Flink中的执行图可以分成四层: Streamgraph -> Jobgraph -> Executiongraph -> 物理执行图
- 1.Streamgraph: 是根据用户通过 Stream APl编写的代码生成的最初的图。用来表示程序的拓扑结构。
- 2.Jobgraph: Streamgraph经过优化后生成了 Jobgraph,提交给 Jobmanager的数据结构。主要的优化为,将多个符合条件的节点chain在一起作为一个节点。
- 3.Execution Graph: Jobmanager根据 Jobgraph生成,是 Jbgraph的并行化版本,是调度层最核心的数据结构。
- 4.物理执行图: Jobmanager根据 Executiongraph对Job进行调度后,在各个Taskmanager上部署Task后形成的“图”,并不是一个具体的数据结构。
9. flink的分区策略
- 按照key值分区
- 全部发往一个分区
- 广播
- 上下游并行度一样时一对一发送
- 随机均匀分配
- 轮流分配
10. Flink 的状态分为哪两类
作为对状态支持比较好的系统,Flink内部提供了可以使用的很多种可选的状态原语。从大的角度看.所有状态可以分为KeyedState和OperatorState 两类。
11.KeyedState都有哪几类
Keyed State 可以进一步划分为下面的 5 类,它们分别是
。比较常用的: ValueState、ListState、MapState
。不太常用的: ReducingState 和 AggregationState
12.Flink中watermark的概念
- watermark是一种街量Event Time进展的机制,它是数据本身的一个隐藏属性。通常基于Event Time的数据,自身都包含一个timestamp.watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用walermark机制结合window来实现。
- 流处理从事件产生,到流经source,再到operator,中间是有一个过程和时间的。虽然大部分情况下,流到operator的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络、背压等原因,导致乱序的产生 ou-of-order或者说late element)。
但是对于late element,我们又不能无限期的等下去,必须要有个机制来保证一个特定的时间后,必须发window去进行计算了。这个特别的机制,就是watermark。
13.什么是Flink的全局快照
- 全局快照首先是一个分布式应用,它有多个进程分布在多个服务器上:
- 其次,它在应用内部有自己的处理逻辑和状态:
- 第三,应用间是可以互相通信的:
- 第四,在这种分布式的应用,有内部状态,硬件可以通信的情况下,某一时刻的全局状态,就叫做全局的快照
14.为什么需要全局快照
- 第一,用它来做检查点,可以定期对全局状态做备份,当应用程序故障时,就可以拿来恢复:
- 第二,做死锁检测,进行快照后当前的程序继续运行,然后可以对快照进行分 析,看应用程序是不是存在死锁状态,如果是就可以进行相应的处理。
15.Flink的容错机制
- Exacty once是指每条 event 会且只会对 state 产生一次影响,这里的“一次”并非端到端的严格一次,而是指在 Flink 内部只处理一次,不包括 source和 sink 的处理。
- Atleast once,是指每条 event 会对 state 产生最少一次影响,也就是存在重复处理的可能。
- At most once,是指每条 event 会对 state 产生最多一次影响,就是状态可能会在出错时丢失。
16.Flink是如何实现End-To-End Exactly-once的?
- Flink通过状态和两次提交协议来保证了端到端的exactly-once语义
- Source: 支持数据的replay,如Kafka的offset。
- Transformation: 借助于checkpoint
- Sink: Checkpoint + 两阶段事务提交
17.解释下两阶段提交?
- 一旦Flink开始做checkpoint操作,就会进入pre-commit “预提交”阶段,同时JobManager的Coordinator会将Barrier注入数据流中
- 当所有的barrier在算子中成功进行一遍传递《就是Checkpoint完成),并完成快照后,“预提交”阶
等所有的算子完成“预提交” - 就会发起一个commit “提交”动作,但是任何一个“预提交” 失败都会导致回滚到最近的checkooint.
18.Flink 的 checkpoint 存在哪里?
可以是内存,文件系统,或者 RocksDB。
19.海量 key 去重
如果是海量数据的话,Set结构是不现实的,可以考虑使用布隆过滤器来去重。
20.Flink 的 checkpoint 机制对比 spark 有什么不同和优势?
- spark streaming 的 checkpoint 仅仅是针对 driver 的故障恢复做了数据和元数据的 checkpoint。而 flink 的 checkpoint 机制要复杂了很多,它采用的是轻量级的分布式快照,实现了每个算子的快照。及流动中的数据的快照。
21.Flink CEP 编程中当状态没有到达的时候会将数据保存在哪里?
- 在 Flink CEP 的处理逻辑中,状态没有满足的和迟到的数据,都会存储在一个 Map 数据结构中,也就是说,如果我们限定判断事件序列的时长为 5 分钟,那么内存中就会存储 5 分钟的数据。
22.Flink 程序在面对数据高峰期时如何处理?
使用大容量的 Kafka 把数据先放到消息队列里面作为数据源,再使用Flink 进行消费,不过这样会影响到一点实时性。
23.Flink 的运行必须依赖 Hadoop组件吗?
Flink可以完全独立于Hadoop,在不依赖Hadoop组件下运行。但是做为大数据的基础设施,Hadoop体系是任何大数据框架都绕不过去的。Flink可以集成众多Hadooop 组件,例如Yarn、Hbase、HDFS等等。例如。Flink可以和Yarn集成做资源调度,也可以读写HDFS,或者利用HDFS做检查点。
24.Flink 资源管理中 Task Slot 的概念
- 在Flink架构角色中我们提到,TaskManager是实际负责执行计算的Worker, TaskManager 是一个JVM 进程,并会以独立的线程来执行一个task或多个subtask。为了控制一个 TaskManager 能接受多少个 task, Flink 提出了 Task Slot 的概念。
- 简单的说,TaskManager会将自己节点上管理的资源分为不同的Slot: 固定大小的资源子集。这样就避免了不同Job的Task互相竞争内存资源,但是需要主要的是,Slot只会做内存的隔离。没有做CPU的隔离。
25.Flink的重启策略都有哪些?
- 固定延迟重启策略 (Fixed Delay Restart Strategy)
- 故障率重启策略 (Failure Rate Restart Strategy)
- 没有重启策略(No Restart Strategy)
- Fallback重启策略 (Fallback Restart Strategy)
26.Flink中的广播变量,使用时需要注意什么?
- 我们知道Flink是并行的,计算过程可能不在一个 Slot 中进行,那么有一种情况即:当我们需要访问同一份数据。那么Fink中的广播变量就是为了解决这种情况。
- 我们可以把广播变量理解为是一个公共的共享变量,我们可以把一个dataset 数据集广播出去,然后不同的task在节点上都能够获取到,这个数据在每个节点上只会存在一份。
27.Flink的内存模型
28.数据倾斜问题
- 1.keyBy之前发生数据倾斜
如果keyBy之前就存在数据倾斜,上游算子的某些实例可能处理的数据较多,某些实例可能处理的数据较少,产生该情况可能是因为数据源的数据本身就不均匀,例如由于某些原因Kafka的topic中某些partition的数据量较大,某些partition的数据量较少。对于不存在kevBy的Flink任务也会出现该情况。
这种情况,需要让Flink任务强制进行shuffle。使用shuffle、rebalance、rescale算子即可将数据均匀分配,从而解决数据倾斜的过 - 2.keyBy之后无开窗聚合数据倾斜
map端使用状态先预聚合,达到一定时间或者一定size后再同一输出 (localkeyby) 。 - 3.keyBy后的窗口聚合操作存在数据倾斜
因为使用了窗口,变成了有界数据的处理,窗口默认是触发时才会输出一条结果发往下游。所以可以使用两阶段聚合的方式:第一阶段聚合: key拼接随机数前缀或后缀,进步keyby、开窗、聚合
第二阶段聚合: 去掉随机数前缀或后缀,按照原来的key及windowEnd作keyby、聚合。
29.Flink连接API
- union 多流合并,类型一致
- connect 两条流分别处理,类型可不一致,可共享状态
- join 相当于innerjoin
- coGroup 实现左外连接,第一个流没有join上,也要输出
30.Flink-On-Yarn常见的提交模式有哪些,分别有什么优缺点?
- 1.yarn-session 式
这种方式需要先启动集群,然后在提交作业,接着会向varn申请一块空间后,资源永远保持不变。如果资源满了,下一个就任务就无法提交,只能等到varn中其中一个作业完成后,程放了资源,那下-个作业才会正常提交,这种方式资源被限制在sesSi0n中,不能超过比较适合特定的运行环境或测试环境。 - 2.per-job模式
这种方式直接在yarn上提交任务运行Flink作业,这种方式的好处是一个任务会对应一个job,即每提交一个作业会根据自身的情况.向yarn中申请资源,直到作业执行完成,并不会影响下一个作业的正常运行,除非是yarn上面没有任何资源的情况下。一般生产环境是采用此方式运行。这种方式需要保证集群资源足够。
31.Flink如何处理迟到数据
- watermark可以设置容错时间
- window的allowedLateness方法,可以设置窗口允许外理迟到数据的时间。
- window的sideOutoutlLateData方法,可以将迟到的数据写入侧输出流
32.Flink任务延迟高如何解决
- 在Flink的后台任务管理中,我们可以看到Flink的那个算子和task出现了反压。最主要的手段是资源调优和算子调优。
- 例如调大并发。
- 增加运行任务的资源。缩短窗口时长。
33.Flink Operator Chains
为了更高效地分布式执行,Flink会尽可能地将operator的subtask链接 chain) 在一起形成task。每个task在一个线程中执行。将operatorst技成ask是非带有效的优化:它能减少线程之同的切授,减少消息的序列化/反成列化,减少少了是迟的同时提高整体的吞吐量。这就是我们所说的算子链。其实就是尽量把操作逻辑放入到同一个subtask里就是一个槽taskSlot
34.Flink什么情况下才会把Operator chain在一起形成算子链?
- 上下游并行度一致
- 下游数据没有其他的输入
- 上下游节点都在同一个soltqroup中,默认是一样的,如果不是,单独指定的算子资源,会独占TaskSolt
- 没有keyed操作
- 数据发送策路是forward
- 用户没有禁用chain
35.Flink中应用在ableAPI中的UDF有几种?
- scalar function: 针对一条record的一个字段的操作,返回一个字段。
- table function: 针对一条record的一个字段的操作,返回多个字段
- aggregate function: 针对多条记录的一个字段操作,返回一条记录