Flink 面试题
简单介绍一下 Flink
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及多种图计算算法实现。
Flink的主要特点是什么?
Flink的主要特点包括:
- 流式处理和批处理一体化:Flink既支持流式处理,也 支持批处理,可以无缝地在流处理和批处理之间切换。
- 事件驱动的处理模型:Flink使用事件时间和处理时间的概念,支持基于事件的处理和窗口操作,适用于实时数据处理和分析。
- 高性能和低延迟:Flink的优化引擎可以实现高吞吐量和低延迟的数据处理,适用于需要快速响应的应用场景。
- 容错性和可靠性:Flink具有容错机制,可以在节点故障时保证数据处理的正确性和一致性。
- 灵活的编程模型:Flink支持多种编程模型,包括基于流的API(DataStream API)和基于批的API(DataSet API),并提供了多种编程语言接口。
Flink的应用场景有哪些?
Flink 适用于以下应用场景:
- 实时数据处理和分析:Flink 可以处理实时数据流,支持实时数据处理和分析,适用于实时监控、实时报表和实时分析等场景。
- 批处理任务:Flink 可以处理有界数据集,支持批处理任务,适用于离线数据处理和大规模数据分析等场景。
- 基于事件的应用:Flink 的事件驱动处理模型适合构建基于事件的应用,如实时推荐系统、欺诈检测和实时预测等场景。
- 流批一体化应用:Flink 的流批一体化特性使得可以将流式和批式处理结合起来,适用于需要实时和离线处理结合的应用场景。
- 数据挖掘和机器学习:Flink 可以处理大规模的数据集,并支持各种数据挖掘和机器学习算法,适用于构建大规模 的数据挖掘和机器学习应用。
- 实时计算和决策:Flink 支持实时计算和决策,可以根据实时数据流进行实时决策和行动,适用于需要实时决策和行动的场景,如实时定价、实时广告投放等。
- 物联网应用:Flink 可以处理大规模的实时数据流,适用于处理物联网应用中的实时数据,如智能家居、智能城市、智能交通等场景。
Flink 是一个通用的大数据处理框架,可以适用于各种大规模数据处理和分析的场景,尤其适用于需要实时处理和分析的场景。
Flink编程模型是什么?
1)Flink分层模型
Flink底层通过封装和抽象,提供四级分层编程模型,以此支撑业务开发实时和批处理程序。
结合示意图,我们由下而上进行介绍。
Runtime层:
Flink程序的最底层入口。提供基础的核心接口完成流、状态、事件、时间等复杂操作,功能灵活但使用成本较高,一般面向源码研发人员。DataStream/Dataset API层:
这一层主要面向开发者。基于Runtime层抽象为两类API,其中DataStream API处理实时流程序;Dataset API处理批数据程序。Table API:
统一DataStream/DataSet API,抽象成带有Schema信息的表结构API。通过Table操作和注册表完成数据计算,支持与DataStream/Dataset相互转换。SQL:
面向数据分析和开发人员,抽象为SQL操作,降低开发门槛和平台化。
2)Flink计算模型
Flink的计算模型和Spark的模型有些类似。包含输入端(source)、转换(Transform)、输出端(sink)。
source端
:Flink程序的输入端,支持多个数据源对接Transformation
:Flink程序的转换过程,实现DataStream/Dataset的计算和转换sink端
: Flink的输出端,支持内部和外部输出源
Flink 工作原理
Flink底层执行分为客户端
(Client)、Job管理器
(JobManager)、任务执行器
(TaskManager)三种角色组件。其中Client负责Job提交;JobManager负责协调Job执行和Task任务分配;TaskManager负责Task任务执行。
Flink常见执行流程如下(调度器不同会有所区别):
- 1)用户提交流程序Application。
- 2)Flink
解析StreamGraph
。Optimizer
和Builder模块解析程序代码,生成初始StreamGraph
并提交至Client
。 - 3)Client
生成JobGraph
。上述StreamGraph由一系列operator chain构成,在client中会被转换为JobGraph
,即优化多个chain为一个节点,最终提交到JobManager
。 - 4)JobManager
调度Job
。JobManager和Client的ActorSystem
保持通信,并生成ExecutionGraph
(并行化JobGraph)。随后Schduler和Coordinator模块协调并调度Jobz执行。 - 5)TaskManager
部署Task
。TaskManager
和JobManager
的ActorSystem
保持通信,接受job调度计划
并在内部划分TaskSlot
部署执行Task任务
。 - 6)Task
执行
。Task执行期间,JobManager、TaskManager和Client之间保持通信,回传任务状态
和心跳信息
,监控任务执行。
公司怎么提交Flink实时任务的?
顾名思义,这里涉及Flink的部署模式内容。一般Flink部署模式除了Standalone之外,最常见的为Flink on Yarn和Flink on K8s模式,其中Flink on Yarn模式在企业中应用最广。
Flink on Yarn模式细分由可以分为Flink session、Flink per-job和Flink application模式
1)Flink session模式
Flink Session模式会首先启动一个集群
,按照配置约定,集群中包含一定数量的JobManager
和TaskManager
。后面所有提交的Flink Job均共享该集群内的JobManager和TaskManager,即所有的 Flink Job 竞争相同资源。
这样做的好处是节省作业提交资源开销(集群已存在),减少资源和线程切换工作。但是所有作业共享一个JobManager,导致JobManager
压力激增,同时一旦某Job发生故障时会影响到其他作业(中断或重启)。一般仅适用于短周期
、小容量
作业。
Flink-session模式的作业提交流程:
- (1)整体流程分为两部分:yarn-session 集群启动、Job提交。
- (2)
yarn-session集群启动
。请求YarnRM
启动JobManager
,随后JobManager内部启动Dispatcher
和Flink-yarnRM
进程,等待后续Job提交
。 - (3)
Client
提交Job
。Client
连接Dispatcher
开始提交Job,包含jars
和解析过的JobGraph
拓扑数据结构。 - (4)
Dispatcher
启动JobMaster
,JobMaster
向Yarn RM请求slots资源
。 - (5)Flink-Yarn RM 向 Yarn RM 请求
Container
资源,准备启动TaskManager
。 - (6)Yarn启动
TaskManager进程
。TaskManage
r同时向Flink RM反向注册(自身可用的slots槽数) - (7)
TaskManager
为新的作业提供slots
,与JobMaster
通信。 - (8)
JobMaster
将执行的任务分发
给TaskManager
,开始部署执行任务
2)Flink Per-job模式
Flink Per-job模式为每个提交的作业启动集群,各集群间相互独立,并在各自作业完成后销毁,最大限度保障资源隔离。每个Job均衡分发
自身的JobManager,单独进行job的调度和执行。
虽然该模式提供了资源隔离,但是每个job均维护一个集群,启动、销毁以及资源请求消耗时间长,因此比较适用于长时间的任务执行(批处理任务)。
Per-job模式在Flink 1.15中弃用,目前推荐使用applicaiton模式。