大数据面试题——Flink面试题(二)
大数据面试题——Flink面试题(一):https://www.nowcoder.com/discuss/1025734
大数据面试题——Flink面试题(三):https://www.nowcoder.com/discuss/1027153
6 Flink的基础编程模型了解吗?
上图是来自Flink官网的运行流程图。通过上图我们可以得知,Flink程序的基本构建是数据输入来自一个Source,Source代表数据的输入端,经过Transformation进行转换,然后在一个或者多个Sink接收器中结束。数据流(stream)就是一组永远不会停止的数据记录流,而转换(transformation)是将一个或多个流作为输入,并生成一个或多个输出流的操作。执行时,Flink程序映射到streaming dataflows,由流(streams)和转换操作(transformation operators)组成。
7 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。
8 说说Flink资源管理中Task Slot的概念
在Flink架构角色中我们提到,TaskManager是实际负责执行计算的Worker,TaskManager是一个JVM进程,并会以独立的线程来执行一个task或多个subtask。为了控制一个TaskManager能接受多少个task,Flink提出了Task Slot的概念。简单的说,TaskManager会将自己节点上管理的资源分为不同的Slot:固定大小的资源子集。这样就避免了不同Job的Task互相竞争内存资源,但是需要主要的是,Slot只会做内存的隔离。没有做CPU的隔离。
9 说说Flink的常用算子?
Flink最常用的常用算子包括:Map:DataStream → DataStream,输入一个参数产生一个参数,map的功能是对输入的参数进行转换操作。Filter:过滤掉指定条件的数据。KeyBy:按照指定的key进行分组。Reduce:用来进行结果汇总合并。Window:窗口函数,根据某些特性将每个key的数据进行分组(例如:在5s内到达的数据)
10 说说你知道的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 classCustomPartitionerimplementsPartitioner<String> { @Override publicintpartition(String key, int numPartitions) { switch (key){ case "1": return 1; case "2": return 2; case "3": return 3; default: return 4; } } }
11 Flink的并行度了解吗?Flink的并行度设置是怎样的?
Flink中的任务被分为多个并行任务来执行,其中每个并行的实例处理一部分数据。这些并行实例的数量被称为并行度。我们在实际生产环境中可以从四个不同层面设置并行度:
操作算子层面(Operator Level)
执行环境层面(Execution Environment Level)
客户端层面(Client Level)
系统层面(System Level)
需要注意的优先级:算子层面>环境层面>客户端层面>系统层面。
12 Flink的Slot和parallelism有什么区别?
官网上十分经典的图:
slot是指taskmanager的并发执行能力,假设我们将taskmanager.numberOfTaskSlots配置为3那么每一个taskmanager中分配3个TaskSlot, 3个taskmanager一共有9个TaskSlot。
parallelism是指taskmanager实际使用的并发能力。假设我们把parallelism.default设置为1,那么9个TaskSlot只能用1个,有8个空闲。
13 Flink有没有重启策略?说说有哪几种?
Flink实现了多种重启策略。
固定延迟重启策略(Fixed Delay Restart Strategy)
故障率重启策略(Failure Rate Restart Strategy)
没有重启策略(No Restart Strategy)
Fallback重启策略(Fallback Restart Strategy)
14用过Flink中的分布式缓存吗?如何使用?
Flink实现的分布式缓存和Hadoop有异曲同工之妙。目的是在本地读取文件,并把他放在taskmanager节点中,防止task重复拉取。
val env = ExecutionEnvironment.getExecutionEnvironment // register a file from HDFS env.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()
15说说Flink中的广播变量,使用时需要注意什么?
我们知道Flink是并行的,计算过程可能不在一个Slot中进行,那么有一种情况即:当我们需要访问同一份数据。那么Flink中的广播变量就是为了解决这种情况。我们可以把广播变量理解为是一个公共的共享变量,我们可以把一个dataset数据集广播出去,然后不同的task在节点上都能够获取到,这个数据在每个节点上只会存在一份。
16说说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)
17说说Flink中的状态存储?
Flink在做计算的过程中经常需要存储中间状态,来避免数据丢失和状态恢复。选择的状态存储策略不同,会影响状态持久化如何和checkpoint交互。Flink提供了三种状态存储方式:MemoryStateBackend、FsStateBackend、RocksDBStateBackend。
18 Flink中的时间有哪几类
Flink中的时间和其他流式计算系统的时间一样分为三类:事件时间,摄入时间,处理时间三种。如果以EventTime为基准来定义时间窗口将形成EventTimeWindow,要求消息本身就应该携带EventTime。如果以IngesingtTime为基准来定义时间窗口将形成IngestingTimeWindow,以source的systemTime为准。如果以ProcessingTime基准来定义时间窗口将形成ProcessingTimeWindow,以operator的systemTime为准。
19 Flink中水印是什么概念,起到什么作用?
Watermark是Apache Flink为了处理EventTime窗口计算提出的一种机制,本质上是一种时间戳。 一般来讲Watermark经常和Window一起被用来处理乱序事件。
20 Flink Table & SQL熟悉吗?TableEnvironment这个类有什么作用
TableEnvironment是Table API和SQL集成的核心概念。这个类主要用来:
在内部catalog中注册表
注册外部catalog
执行SQL查询
注册用户定义(标量,表或聚合)函数
将DataStream或DataSet转换为表
持有对ExecutionEnvironment或StreamExecutionEnvironment的引用
21 Flink SQL的实现原理是什么?是如何实现SQL解析的呢?
首先大家要知道Flink的SQL解析是基于Apache Calcite这个开源框架。
基于此,一次完整的SQL解析过程如下:
用户使用对外提供Stream SQL的语法开发业务应用
用calcite对StreamSQL进行语法检验,语法检验通过后,转换成calcite的逻辑树节点;最终形成calcite的逻辑计划
采用Flink自定义的优化规则和calcite火山模型、启发式模型共同对逻辑树进行优化,生成最优的Flink物理计划
对物理计划采用janino codegen生成代码,生成用低阶API DataStream描述的流应用,提交到Flink平台执行