0


Flink面试题

文章目录

1、spark streaming 和 flink 的区别

Flink 是标准的实时处理引擎,基于事件驱动。而 Spark Streaming 是微批(Micro-Batch)的模型。
下面我们就分几个方面介绍两个框架的主要区别:

  1. 架构模型 Spark Streaming 在运行时的主要角色包括:Master、Worker、Driver、Executor,Flink 在运行时主要包含:Jobmanager、Taskmanager 和 Slot。
  2. 任务调度 Spark Streaming 连续不断的生成微小的数据批次,构建有向无环图 DAG,Spark Streaming 会依次创建 DStreamGraph、JobGenerator、JobScheduler。Flink 根据用户提交的代码生成 StreamGraph,经过优化生成 JobGraph,然后提交给 JobManager 进行处理,JobManager 会根据 JobGraph 生成ExecutionGraph,ExecutionGraph 是 Flink 调度最核心的数据结构,JobManager根据 ExecutionGraph 对 Job 进行调度。
  3. 时间机制 Spark Streaming 支持的时间机制有限,只支持处理时间。 Flink 支持了流处理程序在时间上的三个定义:处理时间、事件时间、注入时间。同时也支持watermark 机制来处理滞后数据。
  4. 容错机制对于 Spark Streaming 任务,我们可以设置 checkpoint,然后假如发生故障并重启,我们可以从上次 checkpoint 之处恢复,但是这个行为只能使得数据不丢失,可能会重复处理,不能做到恰好一次处理语义。Flink 则使用两阶段提交协议来解 决这个问题。

2、Flink 的容错机制(checkpoint)

  1. CheckpointCoordinator(检查点协调器) 周期性的向该流应用的所有 source 算子发送barrier(屏障)。
  2. 当某个 source 算子收到一个 barrier 时,便暂停数据处理过程,然后将自己的当前状态制作成快照,并保存到指定的持久化存储中,最后向 CheckpointCoordinator 报告自己快照制作情况,同时向自身所有下游算子广播该 barrier,恢复数据处理
  3. 下游算子收到 barrier 之后,会暂停自己的数据处理过程,然后将自身的相关状态制作成快照,并保存到指定的持久化存储中,最后向 CheckpointCoordinator 报告自身快照情况,同时向自身所有下游算子广播该 barrier,恢复数据处理。
  4. 每个算子按照步骤 3 不断制作快照并向下游广播,直到最后 barrier 传递到 sink 算子,快照制作完成。
  5. 当 CheckpointCoordinator 收到所有算子的报告之后,认为该周期的快照制作成功; 否则,如果在规定的时间内没有收到所有算子的报告,则认为本周期快照制作失败

3、Flink 中的 Time 有哪几种

在 flink 中被划分为事件时间,提取时间,处理时间三种。

  1. 如果以 EventTime 为基准来定义时间窗口那将形成 EventTimeWindow,要求消息本身就应该携带 EventTime。
  2. 如果以 IngesingtTime 为基准来定义时间窗口那将形成 IngestingTimeWindow,以source 的 systemTime 为准。
  3. 如果以 ProcessingTime 基准来定义时间窗口那将形成 ProcessingTimeWindow,以
  4. operator 的 systemTime 为准。

4、对于迟到数据是怎么处理的

Flink 中 WaterMark 和 Window 机制解决了流式数据的乱序问题,对于因为延迟而顺序有误的数据,可以根据 eventTime 进行业务处理,对于延迟的数据 Flink 也有自己的解决办法,主要的办法是给定一个允许延迟的时间,在该时间范围内仍可以接受处理延迟数据 :

  1. 设置允许延迟的时间是通过 allowedLateness(lateness: Time)
  2. 设置保存延迟数据则是通过 sideOutputLateData(outputTag: OutputTag[T])保存
  3. 获取延迟数据是通过 DataStream.getSideOutput(tag: OutputTag[X])获取

5、Flink 的运行必须依赖 Hadoop 组件吗

Flink 可以完全独立于 Hadoop,在不依赖 Hadoop 组件下运行。但是做为大数据的基础设施,Hadoop 体系是任何大数据框架都绕不过去的。Flink 可以集成众多 Hadooop 组件,例如 Yarn、Hbase、HDFS 等等。例如,Flink 可以和 Yarn 集成做资源调度,也可以读写HDFS,或者利用 HDFS 做检查点。

6、Flink 资源管理中 Task Slot 的概念

在 Flink 中每个 TaskManager 是一个 JVM 的进程, 可以在不同的线程中执行一个或多个子任务。为了控制一个 worker 能接收多少个 task。worker 通过 task slot(任务槽)来进行 控制(一个 worker 至少有一个 task slot)。

7、Flink 的重启策略了解吗

Flink 支持不同的重启策略,这些重启策略控制着 job 失败后如何重启:
固定延迟重启策略
固定延迟重启策略会尝试一个给定的次数来重启 Job,如果超过了最大的重启次数,Job 最终将失败。在连续的两次重启尝试之间,重启策略会等待一个固定的时间。
失败率重启策略
失败率重启策略在 Job 失败后会重启,但是超过失败率后,Job 会最终被认定失败。在两个连续的重启尝试之间,重启策略会等待一个固定的时间。
无重启策略
Job 直接失败,不会尝试进行重启。

8、 Flink 是如何保证 Exactly-once 语义的

Flink 通过实现两阶段提交和状态保存来实现端到端的一致性语义。分为以下几个步骤:

  1. 开始事务(beginTransaction)创建一个临时文件夹,来写把数据写入到这个文件夹里面
  2. 预提交(preCommit)将内存中缓存的数据写入文件并关闭
  3. 正式提交(commit)将之前写完的临时文件放入目标目录下。这代表着最终的数据会有一些
  4. 延迟丢弃(abort)丢弃临时文件若失败发生在预提交成功后,正式提交前。可以根据状态来提交预提交的数据,也可删除预提交的数据。

9、Flink 是如何处理反压的

Flink 内部是基于 producer-consumer 模型来进行消息传递的,Flink 的反压设计也是基于这个模型。Flink 使用了高效有界的分布式阻塞队列,就像 Java 通用的阻塞队列(BlockingQueue)一样。下游消费者消费变慢,上游就会受到阻塞。

10、Flink 中的状态存储

Flink 在做计算的过程中经常需要存储中间状态,来避免数据丢失和状态恢复。选择的状态存储策略不同,会影响状态持久化如何和 checkpoint 交互。Flink 提供了三种状态存储方式:MemoryStateBackend、FsStateBackend、 RocksDBStateBackend。

11、Flink 是如何支持批流一体的

这道题问的比较开阔,如果知道 Flink 底层原理,可以详细说说,如果不是很了 解,就直接简单一句话:Flink 的开发者认为批处理是流处理的一种特殊情况。批处理是有限的流处理。Flink 使用一个引擎支持了 DataSet API 和 DataStreamAPI。

12、Flink 的内存管理是如何做的

Flink 并不是将大量对象存在堆上,而是将对象都序列化到一个预分配的内存块 上。此外,Flink 大量的使用了堆外内存。如果需要处理的数据超出了内存限制,则会将部分数据存储到硬盘上。Flink 为了直接操作二进制数据实现了自己的序列化框架。

13、简单介绍一下 Flink

Flink 核心是一个流式的数据流执行引擎,其针对数据流的分布式计算提供了数据分布、数据通信以及容错机制等功能。基于流执行引擎,Flink 提供了诸多更高抽象层的 API 以便用户编写分布式任务:DataSet API, 对静态数据进行批处理操作,将静态数据抽象成分布式的数据集,用户可以方便地使用 Flink 提供的各种操作符对分布式数据集进行处理,支持 Java、Scala 和 Python。DataStream API,对数据流进行流处理操作,将流式的数据抽象成分布式的数据流,用户可以方便地对分布式数据流进行各种操作,支持 Java 和 Scala。Table API,对结构化数据进行查询操作,将结构化数据抽象成关系表,并通过类 SQL 的 DSL 对关系表进行各种查询操作,支持 Java 和 Scala。此外,Flink 还针对特定的应用领域提供了领域库,例如:Flink ML,Flink 的机器学习库,提供了机器学习 Pipelines API 并实现了多种机器学习算法。Gelly,Flink 的图计算库,提供了图计算的相关 API 及多种图计算算法实现。

14、Flink 的并行度有了解吗?Flink 中设置并行度需要注意什么?

Flink 程序由多个任务(Source、Transformation、Sink)组成。任务被分成多个并行实例来执行,每个并行实例处理任务的输入数据的子集。任务的并行实例的数量称之为并行度。Flink 中人物的并行度可以从多个不同层面设置:操作算子层面(Operator Level)、执行环境层面(Execution Environment Level)、客户端层面(Client Level)、系统层面(SystemLevel)。Flink 可以设置好几个 level 的 parallelism,其中包括 Operator Level、ExecutionEnvironment Level、Client Level、System Level 在 flink-conf.yaml 中通过parallelism.default 配置项给所有 execution environments 指定系统级的默认parallelism;在 ExecutionEnvironment 里头可以通过 setParallelism 来给 operators、data sources、data sinks 设置默认的 parallelism;如果 operators、data sources、datasinks 自己有设置 parallelism 则会覆盖 ExecutionEnvironment 设置的 parallelism。

15、Flink 支持哪几种重启策略?分别如何配置?

重启策略种类:固定延迟重启策略(Fixed Delay Restart Strategy)故障率重启策略(Failure Rate Restart Strategy)无重启策略(No Restart Strategy)Fallback 重启策略(Fallback Restart Strategy)

16、Flink 的分布式缓存有什么作用?如何使用?

Flink 提供了一个分布式缓存,类似于 hadoop,可以使用户在并行函数中很方便的读取本地文件,并把它放在 taskmanager 节点中,防止 task 重复拉取。此缓存的工作机制如下:程序注册一个文件或者目录(本地或者远程文件系统,例如 hdfs 或者s3),通过 ExecutionEnvironment 注册缓存文件并为它起一个名称。当程序执行,Flink 自动将文件或者目录复制到所有 taskmanager 节点的本地文件系统,仅会执行一次。用户可以通过这个指定的名称查找文件或者目录,然后从 taskmanager 节点的本地文件系统访问它。

17、Flink 中的广播变量,使用广播变量需要注意什么事项?

在 Flink 中,同一个算子可能存在若干个不同的并行实例,计算过程可能不在同一个 Slot 中进行,不同算子之间更是如此,因此不同算子的计算数据之间不能像 Java 数组之间一样互相访问,而广播变量 Broadcast 便是解决这种情况的。我们可以把广播变量理解为是一个公共的共享变量,我们可以把一个 dataset 数据集广播出去,然后不同的 task 在节点上都能够获取到,这个数据在每个节点上只会存在一份。

18、Flink 中对窗口的支持包括哪几种?说说他们的使用场景

  1. Tumbling Time Window 假如我们需要统计每一分钟中用户购买的商品的总数,需要将用户的行为事件按每一分钟进行切分,这种切分被成为翻滚时间窗口(Tumbling Time Window)。翻滚窗口能将数据流切分成不重叠的窗口,每一个事件只能属于一个窗口。
  2. Sliding Time Window 我们可以每 30 秒计算一次最近一分钟用户购买的商品总数。这种窗口我们称为滑动时间窗口(Sliding Time Window)。在滑窗中,一个元素可以对应多个窗口。
  3. Tumbling Count Window 当我们想要每 100 个用户购买行为事件统计购买总数,那么每当窗口中填满 100 个元素了,就会对窗口进行计算,这种窗口我们称之为翻滚计数窗口(Tumbling Count Window),上图所示窗口大小为 3 个。
  4. Session Window在这种用户交互事件流中,我们首先想到的是将事件聚合到会话窗口中(一段用户持续活跃的 周期),由非活跃的间隙分隔开。如上图所示,就是需要计算每个用户在活跃期间总共购买的 商品数量,如果用户 30 秒没有活动则视为会话断开(假设 raw data stream 是单个用户的购 买行为流)。一般而言,window 是在无限的流上定义了一个有限的元素集合。这个集合可以 是基于时间的,元素个数的,时间和个数结合的,会话间隙的,或者是自定义的。Flink 的 DataStream API 提供了简洁的算子来满足常用的窗口操作,同时提供了通用的窗口机制来允 许用户自己定义窗口分配逻辑

19、Flink 中的 State Backends 是什么?有什么作用?分成哪几类?说说他们各自的优缺点?

Flink 流计算中可能有各种方式来保存状态:

  1. 窗口操作
  2. 使用了 KV 操作的函数
  3. 继承了 CheckpointedFunction 的函数 当开始做 checkpointing 的时候,状态会被持久化到 checkpoints 里来规避数据丢失和状态恢复。选择的状态存储策略不同,会导致状态持久化如何和 checkpoints 交互。Flink 内部提供了这些状态后端:
  4. MemoryStateBackend
  5. FsStateBackend
  6. RocksDBStateBackend 如果没有其他配置,系统将使用 MemoryStateBackend。

20、Flink 中的时间种类有哪些?各自介绍一下?

Flink 中的时间与现实世界中的时间是不一致的,在 flink 中被划分为事件时间,摄入时间,处理时间三种。如果以 EventTime 为基准来定义时间窗口将形成 EventTimeWindow,要求消息本身就应该携带 EventTime 如果以 IngesingtTime 为基准来定义时间窗口将形成IngestingTimeWindow,以 source 的 systemTime 为准。如果以 ProcessingTime 基准来定义时间窗口将形成 ProcessingTimeWindow,以 operator 的 systemTime 为准。

21、WaterMark 是什么?是用来解决什么问题?

Watermark 是 Apache Flink 为了处理 EventTime 窗口计算提出的一种机制,本质上也是一种时间戳。watermark 是用于处理乱序事件的,处理乱序事件通常用 watermark 机制结合window 来实现。

22、Flink 的 table 和 SQL 熟悉吗?Table API 和 SQL 中TableEnvironment 这个类有什么作用

TableEnvironment 是 Table API 和 SQL 集成的核心概念。它负责:

  1. 在内部 catalog 中注册表
  2. 注册外部 catalog
  3. 执行 SQL 查询
  4. 注册用户定义(标量,表或聚合)函数
  5. 将 DataStream 或 DataSet 转换为表持有对 ExecutionEnvironment 或 StreamExecutionEnvironment 的引用

23、Flink 如何实现 SQL 解析的呢?

StreamSQL API 的执行原理如下:

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

24、Flink 是如何做到批处理与流处理统一的?

Flink 设计者认为:有限流处理是无限流处理的一种特殊情况,它只不过在某个时间点停止而
已。Flink 通过一个底层引擎同时支持流处理和批处理。

25、Flink 中的数据传输模式是怎么样的?

上游的 task 产生数据后,会写在本地的缓存中,然后通知 JM 自己的数据已经好了,JM 通知下游的 Task 去拉取数据,下游的 Task 然后去上游的 Task 拉取数据,形成链条。

但是在何时通知 JM?这里有一个设置,比如 pipeline 还是 blocking,pipeline 意味着上游哪怕产生一个数据,也会去通知,blocking 则需要缓存的插槽存满了才会去通知,默认是pipeline。

虽然生产数据的是 Task,但是一个 TaskManager 中的所有 Task 共享一个NetworkEnvironment,下游的 Task 利用 ResultPartitionManager 主动去上游 Task 拉数据,底层利用的是 Netty 和 TCP 实现网络链路的传输。

那么,一直都在说 Flink 的背压是一种自然的方式,为什么是自然的了?

从上面的图中下面的链路中可以看到,当下游的 process 逻辑比较慢,无法及时处理数据时,他自己的 local buffer 中的消息就不能及时被消费,进而导致 netty 无法把数据放入local buffer,进而 netty 也不会去 socket 上读取新到达的数据,进而在 tcp 机制中,tcp 也不会从上游的 socket 去读取新的数据,上游的 netty 也是一样的逻辑,它无法发送数据,也就不能从上游的 localbuffer 中消费数据,所以上游的 localbuffer 可能就是满的,上游的operator 或者 process 在处理数据之后进行 collect.out 的时候申请不能本地缓存,导致上游的 process 被阻塞。这样,在这个链路上,就实现了背压。

如果还有相应的上游,则会一直反压上去,一直影响到 source,导致 source 也放慢从外部消息源读取消息的速度。一旦瓶颈解除,网络链路畅通,则背压也会自然而然的解除。

26、Flink 的容错机制

Flink 基于分布式快照与可部分重发的数据源实现了容错。用户可自定义对整个 Job 进行快照的时间间隔,当任务失败时,Flink 会将整个 Job 恢复到最近一次快照,并从数据源重发快照之后的数据。

27、Flink 在使用 Window 时出现数据倾斜,你有什么解决办法?

注意:这里 window 产生的数据倾斜指的是不同的窗口内积攒的数据量不同,主要是由源头数据的产生速度导致的差异。

28、Flink 任务,delay 极高,请问你有什么调优策略?

首先要确定问题产生的原因,找到最耗时的点,确定性能瓶颈点。比如任务频繁反压,找到反压点。主要通过:资源调优、作业参数调优。资源调优即是对作业中的 Operator 的并发数(parallelism)、CPU(core)、堆内存(heap_memory)等参数进行调优。作业参数调优包括:并行度的设置,State 的设置,checkpoint 的设置。

29、Flink 集群有哪些角色?各自有什么作用?

Flink 程序在运行时主要有 TaskManager,JobManager,Client 三种角色。

JobManager 扮演着集群中的管理者 Master 的角色,它是整个集群的协调者,负责接收Flink Job,协调检查点,Failover 故障恢复等,同时管理 Flink 集群中从节点TaskManager。

TaskManager 是实际负责执行计算的 Worker,在其上执行 Flink Job 的一组 Task,每个TaskManager 负责管理其所在节点上的资源信息,如内存、磁盘、网络,在启动的时候将资源的状态向 JobManager 汇报。

Client 是 Flink 程序提交的客户端,当用户提交一个 Flink 程序时,会首先创建一个 Client,该 Client 首先会对用户提交的 Flink 程序进行预处理,并提交到 Flink 集群中处理,所以Client 需要从用户提交的 Flink 程序配置中获取 JobManager 的地址,并建立到JobManager 的连接,将 Flink Job 提交给 JobManager。

30、公司怎么提交的实时任务,有多少 Job Manager?

  1. 我们使用 yarn session 模式提交任务;另一种方式是每次提交都会创建一个新的 Flink集群,为每一个 job 提供资源,任务之间互相独立,互不影响,方便管理。任务执行完成之后创建的集群也会消失。线上命令脚本如下:bin/yarn-session.sh -n 7 -s 8 -jm 3072 -tm 32768 -qu root. . -nm - -d其中申请 7 个 taskManager,每个 8 核,每个 taskmanager 有 32768M 内存。
  2. 集群默认只有一个 Job Manager。但为了防止单点故障,我们配置了高可用。对于standlone 模式,我们公司一般配置一个主 Job Manager,两个备用 JobManager,然后结合 ZooKeeper 的使用,来达到高可用;对于 yarn 模式,yarn 在Job Mananger 故障会自动进行重启,所以只需要一个,我们配置的最大重启次数是10 次。

31、Flink 的并行度了解吗?Flink 的并行度设置是怎样的?

Flink 中的任务被分为多个并行任务来执行,其中每个并行的实例处理一部分数据。这些并行实例的数量被称为并行度。我们在实际生产环境中可以从四个不同层面设置并行度:

  • 操作算子层面(Operator Level)
  • 执行环境层面(Execution Environment Level)
  • 客户端层面(Client Level)
  • 系统层面(System Level)

需要注意的优先级:算子层面>环境层面>客户端层面>系统层面。

32、Flink 的 Checkpoint 存在哪里

可以是内存,文件系统,或者 RocksDB。

33、Exactly-Once 的保证

下级存储支持事务:Flink 可以通过实现两阶段提交和状态保存来实现端到端的一致性语义。分为以下几个步骤:

  1. 开始事务(beginTransaction)创建一个临时文件夹,来写把数据写入到这个文件夹里面
  2. 预提交(preCommit)将内存中缓存的数据写入文件并关闭
  3. 正式提交(commit)将之前写完的临时文件放入目标目录下。这代表着最终的数据会有一些延迟
  4. 丢弃(abort)丢弃临时文件
  5. 若失败发生在预提交成功后,正式提交前。可以根据状态来提交预提交的数据,也可删除预提交的数据。> 下级存储不支持事务:具体实现是幂等写入,需要下级存储具有幂等性写入特性。

34、说一下 Flink 状态机制

Flink 在做计算的过程中经常需要存储中间状态,来避免数据丢失和状态恢复。选择的状态存储策略不同,会影响状态持久化如何和 checkpoint 交互。Flink 提供了三种状态存储方式:MemoryStateBackend、FsStateBackend、RocksDBStateBackend。

35、Flink 中的 Watermark 机制

Watermark 是一种衡量 Event Time 进展的机制,可以设定延迟触发

Watermark 是用于处理乱序事件的,而正确的处理乱序事件,通常用 Watermark 机制结合window 来实现;

数据流中的 Watermark 用于表示 timestamp 小于 Watermark 的数据,都已经到达了,因此,window 的执行也是由 Watermark 触发的

36、Flink 分布式快照的原理是什么

Flink 的容错机制的核心部分是制作分布式数据流和操作算子状态的一致性快照。 这些快照充当一致性 checkpoint,系统可以在发生故障时回滚。 Flink 用于制作这些快照的机制在“分布式数据流的轻量级异步快照”中进行了描述。 它受到分布式快照的标准 Chandy-Lamport算法的启发,专门针对 Flink 的执行模型而定制。

barriers 在数据流源处被注入并行数据流中。快照 n 的 barriers 被插入的位置(我们称之为Sn)是快照所包含的数据在数据源中最大位置。

例如,在 Apache Kafka 中,此位置将是分区中最后一条记录的偏移量。 将该位置 Sn 报告给checkpoint 协调器(Flink 的 JobManager)。

然后 barriers 向下游流动。当一个中间操作算子从其所有输入流中收到快照 n 的 barriers时,它会为快照 n 发出 barriers 进入其所有输出流中。

一旦 sink 操作算子(流式 DAG 的末端)从其所有输入流接收到 barriers n,它就向checkpoint 协调器确认快照 n 完成。

在所有 sink 确认快照后,意味快照着已完成。一旦完成快照 n,job 将永远不再向数据源请求Sn 之前的记录,因为此时这些记录(及其后续记录)将已经通过整个数据流拓扑,也即是已经被处理结束。

37、介绍一下 Flink 的 CEP 机制

CEP 全称为 Complex Event Processing,复杂事件处理

Flink CEP 是在 Flink 中实现的复杂事件处理(CEP)库

CEP 允许在无休止的事件流中检测事件模式,让我们有机会掌握数据中重要的部分

一个或多个由简单事件构成的事件流通过一定的规则匹配,然后输出用户想得到的数据 ——满足规则的复杂事件

38、 Flink CEP 编程中当状态没有到达的时候会将数据保存在哪

在流式处理中,CEP 当然是要支持 EventTime 的,那么相对应的也要支持数据的迟到现象,也就是 watermark 的处理逻辑。CEP 对未匹配成功的事件序列的处理,和迟到数据是类似的。在 Flink CEP 的处理逻辑中,状态没有满足的和迟到的数据,都会存储在一个 Map 数据结构中,也就是说,如果我们限定判断事件序列的时长为 5 分钟,那么内存中就会存储 5 分钟的数据,这在我看来,也是对内存的极大损伤之一。

标签: flink big data

本文转载自: https://blog.csdn.net/XGkerwin1/article/details/125053733
版权归原作者 XGkerwin 所有, 如有侵权,请联系我们删除。

“Flink面试题”的评论:

还没有评论