博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flink面试手册 - 核心概念和基础篇
阅读量:3655 次
发布时间:2019-05-21

本文共 8106 字,大约阅读时间需要 27 分钟。

根据官网的介绍,Flink 的特性包含:

支持高吞吐、低延迟、高性能的流处理支持有状态计算的 Exactly-once 语义支持带有事件时间的窗口 (Window) 操作支持基于轻量级分布式快照(Snapshot)实现的容错支持高度灵活的窗口 (Window) 操作,支持基于 time、count、session 以及 data-driven 的窗口操作支持具有 Backpressure 功能的持续流模型支持迭代计算一个运行时同时支持 Batch on Streaming 处理和 Streaming 处理Flink 在 JVM 内部实现了自己的内存管理支持程序自动优化:避免特定情况下 Shuffle、排序等昂贵操作,中间结果有必要进行缓存

一、 简单介绍一下 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 相比传统的 Spark Streaming 有什么区别?

这个问题是一个非常宏观的问题,因为两个框架的不同点非常之多。但是在面试时有非常重要的一点一定要回答出来: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 则使用两阶段提交协议来解决这个问题。

三、 Flink 的组件栈有哪些?

根据 Flink 官网描述,Flink 是一个分层架构的系统,每一层所包含的组件都提供了特定的抽象,用来服务于上层组件。

自下而上,每一层分别代表:

Deploy 层:该层主要涉及了Flink的部署模式,在上图中我们可以看出,Flink 支持包括local、Standalone、Cluster、Cloud等多种部署模式。
Runtime 层:Runtime层提供了支持 Flink 计算的核心实现,比如:支持分布式 Stream 处理、JobGraph到ExecutionGraph的映射、调度等等,为上层API层提供基础服务。
API层:API 层主要实现了面向流(Stream)处理和批(Batch)处理API,其中面向流处理对应DataStream API,面向批处理对应DataSet API,后续版本,Flink有计划将DataStream和DataSet API进行统一。
Libraries层:该层称为Flink应用框架层,根据API层的划分,在API层之上构建的满足特定应用的实现计算框架,也分别对应于面向流处理和面向批处理两类。面向流处理支持:CEP(复杂事件处理)、基于SQL-like的操作(基于Table的关系操作);面向批处理支持:FlinkML(机器学习库)、Gelly(图处理)。

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

Flink可以完全独立于Hadoop,在不依赖Hadoop组件下运行。

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

五、你们的Flink集群规模多大?

大家注意,这个问题看起来是问你实际应用中的Flink集群规模,其实还隐藏着另一个问题:Flink可以支持多少节点的集群规模?

在回答这个问题时候,可以将自己生产环节中的集群规模、节点、内存情况说明,同时说明部署模式(一般是Flink on Yarn),除此之外,用户也可以同时在小集群(少于5个节点)和拥有 TB 级别状态的上千个节点上运行 Flink 任务。

六、Flink的基础编程模型了解吗?

通过上图我们可以得知,Flink 程序的基本构建是数据输入来自一个 Source,Source 代表数据的输入端,经过 Transformation 进行转换,然后在一个或者多个Sink接收器中结束。数据流(stream)就是一组永远不会停止的数据记录流,而转换(transformation)是将一个或多个流作为输入,并生成一个或多个输出流的操作。执行时,Flink程序映射到 streaming dataflows,由流(streams)和转换操作(transformation operators)组成。

七、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。

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

在Flink架构角色中我们提到,TaskManager是实际负责执行计算的Worker,TaskManager 是一个 JVM 进程,并会以独立的线程来执行一个task或多个subtask。为了控制一个 TaskManager 能接受多少个 task,Flink 提出了 Task Slot 的概念。

简单的说,TaskManager会将自己节点上管理的资源分为不同的Slot:固定大小的资源子集。

这样就避免了不同Job的Task互相竞争内存资源,但是需要主要的是,Slot只会做内存的隔离。没有做CPU的隔离。

九、说说 Flink 的常用算子?

Flink 最常用的常用算子包括:

Map:DataStream → DataStream,输入一个参数产生一个参数,map的功能是对输入的参数进行转换操作。
Filter:过滤掉指定条件的数据。
KeyBy:按照指定的key进行分组。
Reduce:用来进行结果汇总合并。
Window:窗口函数,根据某些特性将每个key的数据进行分组(例如:在5s内到达的数据)

十、说说你知道的Flink分区策略?

什么要搞懂什么是分区策略。

分区策略是用来决定数据如何发送至下游。目前 Flink 支持了8中分区策略的实现。

上图是整个Flink实现的分区策略继承图:

GlobalPartitioner

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

ShufflePartitioner

数据会被随机分发到下游算子的每一个实例中进行处理。

RebalancePartitioner

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

RescalePartitioner

这种分区器会根据上下游算子的并行度,循环的方式输出到下游算子的每个实例。
这里有点难以理解,假设上游并行度为2,编号为A和B。下游并行度为4,编号为1,2,3,4。
那么A则把数据循环发送给1和2,B则把数据循环发送给3和4。
假设上游并行度为4,编号为A,B,C,D。下游并行度为2,编号为1,2。那么A和B则把数据发送给1,C和D则把数据发送给2。

BroadcastPartitioner

广播分区会将上游数据输出到下游算子的每个实例中。适合于大数据集和小数据集做Jion的场景。

ForwardPartitioner

ForwardPartitioner 用于将记录输出到下游本地的算子实例。它要求上下游算子并行度一样。
简单的说,ForwardPartitioner用来做数据的控制台打印。

KeyGroupStreamPartitioner

Hash分区器。会将数据按 Key 的 Hash 值输出到下游算子实例中。

CustomPartitionerWrapper

用户自定义分区器。需要用户自己实现Partitioner接口,来定义自己的分区逻辑。
例如:

static class CustomPartitioner implements Partitioner
{ @Override public int partition(String key, int numPartitions) { switch (key){ case "1": return 1; case "2": return 2; case "3": return 3; default: return 4; } } }

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

Flink中的任务被分为多个并行任务来执行,其中每个并行的实例处理一部分数据。这些并行实例的数量被称为并行度。

我们在实际生产环境中可以从四个不同层面设置并行度:

  • 操作算子层面(Operator Level)

  • 执行环境层面(Execution Environment Level)

  • 客户端层面(Client Level)

  • 系统层面(System Level)

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

十二、Flink的Slot和parallelism有什么区别?

官网上十分经典的图:

slot是指taskmanager的并发执行能力,假设我们将 taskmanager.numberOfTaskSlots 配置为3

那么每一个 taskmanager 中分配3个 TaskSlot, 3个 taskmanager 一共有9个TaskSlot。

parallelism是指taskmanager实际使用的并发能力。假设我们把 parallelism.default 设置为1,那么9个 TaskSlot 只能用1个,有8个空闲。

十三、Flink有没有重启策略?说说有哪几种?

Flink 实现了多种重启策略。

  • 固定延迟重启策略(Fixed Delay Restart Strategy)

  • 故障率重启策略(Failure Rate Restart Strategy)

  • 没有重启策略(No Restart Strategy)

  • Fallback重启策略(Fallback Restart Strategy)

十四、用过Flink中的分布式缓存吗?如何使用? 

Flink实现的分布式缓存和Hadoop有异曲同工之妙。目的是在本地读取文件,并把他放在 taskmanager 节点中,防止task重复拉取。

val env = ExecutionEnvironment.getExecutionEnvironment// register a file from HDFSenv.registerCachedFile("hdfs:///path/to/your/file", "hdfsFile")// register a local executable file (script, executable, ...)env.registerCachedFile("file:///path/to/exec/file", "localExecFile", true)// define your program and execute...val input: DataSet[String] = ...val result: DataSet[Integer] = input.map(new MyMapper())...env.execute()

十五、说说Flink中的广播变量,使用时需要注意什么? 

我们知道Flink是并行的,计算过程可能不在一个 Slot 中进行,那么有一种情况即:当我们需要访问同一份数据。那么Flink中的广播变量就是为了解决这种情况。

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

十六、说说Flink中的窗口? 

来一张官网经典的图:

Flink 支持两种划分窗口的方式,按照time和count。如果根据时间划分窗口,那么它就是一个time-window 如果根据数据划分窗口,那么它就是一个count-window。

flink支持窗口的两个重要属性(size和interval)

如果size=interval,那么就会形成tumbling-window(无重叠数据)

如果size>interval,那么就会形成sliding-window(有重叠数据)
如果size< interval, 那么这种窗口将会丢失数据。比如每5秒钟,统计过去3秒的通过路口汽车的数据,将会漏掉2秒钟的数据。

通过组合可以得出四种基本窗口:

  • 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)

十七、说说Flink中的状态存储? 

Flink在做计算的过程中经常需要存储中间状态,来避免数据丢失和状态恢复。选择的状态存储策略不同,会影响状态持久化如何和 checkpoint 交互。

Flink提供了三种状态存储方式:MemoryStateBackend、FsStateBackend、RocksDBStateBackend。

十八、Flink 中的时间有哪几类

Flink 中的时间和其他流式计算系统的时间一样分为三类:事件时间,摄入时间,处理时间三种。

如果以 EventTime 为基准来定义时间窗口将形成EventTimeWindow,要求消息本身就应该携带EventTime。

如果以 IngesingtTime 为基准来定义时间窗口将形成 IngestingTimeWindow,以 source 的systemTime为准。
如果以 ProcessingTime 基准来定义时间窗口将形成 ProcessingTimeWindow,以 operator 的systemTime 为准。

十九、Flink 中水印是什么概念,起到什么作用? 

Watermark 是 Apache Flink 为了处理 EventTime 窗口计算提出的一种机制, 本质上是一种时间戳。

一般来讲Watermark经常和Window一起被用来处理乱序事件。

二十、Flink Table & SQL 熟悉吗?TableEnvironment这个类有什么作用 

TableEnvironment是Table API和SQL集成的核心概念。

这个类主要用来:

  • 在内部catalog中注册表

  • 注册外部catalog

  • 执行SQL查询

  • 注册用户定义(标量,表或聚合)函数

  • 将DataStream或DataSet转换为表

  • 持有对ExecutionEnvironment或StreamExecutionEnvironment的引用

二十、Flink SQL的实现原理是什么?是如何实现 SQL 解析的呢? 

首先大家要知道 Flink 的SQL解析是基于Apache Calcite这个开源框架。

基于此,一次完整的SQL解析过程如下:

  • 用户使用对外提供Stream SQL的语法开发业务应用

  • 用calcite对StreamSQL进行语法检验,语法检验通过后,转换成calcite的逻辑树节点;最终形成calcite的逻辑计划

  • 采用Flink自定义的优化规则和calcite火山模型、启发式模型共同对逻辑树进行优化,生成最优的Flink物理计划

  • 对物理计划采用janino codegen生成代码,生成用低阶API DataStream 描述的流应用,提交到Flink平台执行

转载地址:http://eucfn.baihongyu.com/

你可能感兴趣的文章
flask04前端路由网络访问
查看>>
flask05 flask中的Template
查看>>
flask06 flask模型操作
查看>>
flask07 flask中的flask-restful
查看>>
cocopod 换源,加速,(清华源)
查看>>
swfit项目 gitignore语法忽略文件,多级上级文件夹
查看>>
ios学习笔记01-弹出框,自动布局,类与对象,继承和重写
查看>>
ios学习笔记02-optionnal类型,制作查询天气app(网络访问)
查看>>
ios学习笔记03-Todo app(tableview的使用,UserDefaults简单存储)
查看>>
ios学习笔记04-本地存储和realm移动端数据库的使用-结合todo项目
查看>>
SwiftUI tutorials:Fatal error: No ObservableObject of type DataType found.
查看>>
苹果官方网站SwiftUI教程笔记01:
查看>>
苹果官方网站SwiftUI教程02
查看>>
linux,Mac下安装pyenv
查看>>
pyenv 如何安装管理多个环境,以及国内镜像加速(换源),安装虚拟环境
查看>>
update Homebrew 太慢,更换Homebrew的更新源
查看>>
Swift 使用mapkit 实现在地图上两点(多点)画线,画多条·多种颜色的线
查看>>
ios swfit-如何简单通过UIScrollView实现滑动横行换界面
查看>>
swfti-ios实现自定义UIView等控件的方法。
查看>>
Swfit语言在xcode中进行文档注释,代码注释分段
查看>>