1:什么是flink ?
Apache Flink 是一个分布式的开源的大数据处理框架,用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。
2:总结一线大厂
阿里巴巴,腾讯,字节跳动,网易,百度,美团,滴滴,京东,小米
抖音,快手
3: Flink 主要的应用场景
1. 电商和市场营销
举例:实时数据报表、广告投放、实时推荐
2. 物联网(IOT)
举例:传感器实时数据采集和显示、实时报警,交通运输业
3. 物流配送和服务业
举例:订单状态实时更新、通知信息推送
4. 银行和金融业
举例:实时结算和通知推送,实时检测异常行为
4:flink与spark streaming 的区别?
1:数据处理方式
Spark 以批处理为根本,并尝试在批处理之上支持流计算;万物皆批次
Flink 则认为,流处理才是最基本的操作,批处理也可以统一为流处理。在 Flink 的世
界观中,万物皆流,
2:底层数据结构
Spark 和 Flink 在底层实现最主要的差别就在于数据模型不同。
Spark 底层数据模型是弹性分布式数据集(RDD),Spark Streaming 进行微批处理的底层接口 DStream,实际上处理的也是一组组小批数据 RDD 的集合。
而 Flink 的基本数据模型是数据流(DataFlow),以及事件(Event)序列。
5:什么是有状态的流数据?
我们可以把需要的额外数据保存成一个“状态”,然后针对这条数据进行处理,并且更新
状态。在传统架构中,这个状态就是保存在数据库里的。这就是所谓的“有状态的流处理”。
(为了加快访问速度,我们可以直接将状态保存在本地内存当应用收到一
个新事件时,它可以从状态中读取数据,也可以更新状态。而当状态是从内存中读写的时候,
这就和访问本地变量没什么区别了,实时性可以得到极大的提升。 )
6:第一代以 Storm 为代表的第一代分布式开源流处理器,主要专注于具有毫秒延迟的事件处理,特点就是一个字“快”;而对于准确性和结果的一致性,是不提供内置支持的,因为结果有可能取决于到达事件的时间和顺序。另外,第一代流处理器通过检查点来保证容错性,但是故障恢 复的时候,即使事件不会丢失,也有可能被重复处理——所以无法保证“exactly-once”。
可以说第一代流处理器牺牲了结果的准确性,用来换取更低的延迟。而
批处理器恰好反过来,牺牲了实时性,换取了结果的准确。
6:第二代 lambda架构?
Lambda 架构主体是传统批处理架构的增强。它的“批处理层”(Batch Layer)就是由传统
的批处理器和存储组成,而“实时层”(Speed Layer)则由低延迟的流处理器实现。
Lambda 架构的优点非常明显,它兼具了批处理器和第一代流处理器的特点,同时保证了
低延迟和结果的准确性。而它的缺点同样非常明显。首先,Lambda 架构本身就很难建立和维护;而且,它需要我们对一个应用程序,做出两套语义上等效的逻辑实现,因为批处理和流处 理是两套完全独立的系统,它们的 API 也完全不同。为了实现一个应用,付出了双倍的工作量,这对程序员显然不够友好。
7:第三代flink
第三代流处理器通过巧妙的设计,完美解决了乱序数据对结果正确性所造成的影响。这一
代系统还做到了精确一次(exactly-once)的一致性保障,是第一个具有一致性和准确结果的 开源流处理器除了低延迟、容错和结果准确性之外,新一代流处理器还在不断添加新的功能,例如高可 用的设置,以及与资源管理器(如 YARN 或 Kubernetes)的紧密集成等等。
8:flink的资源管理器
目前比较流行的资源管理框架有Hadoop Yarn,K8s,Mesos,它们可以提供硬件资源的抽象、计算任务的隔离、资源的管理等特性。
9:flink核心特性
1:高吞吐和低延迟。每秒处理数百万个事件,毫秒级延迟。
2:结果的准确性。Flink 提供了事件时间(event-time)和处理时间(processing-time)
语义。对于乱序事件流,事件时间语义仍然能提供一致且准确的结果。
3:精确一次(exactly-once)的状态一致性保证
4:可以连接到最常用的存储系统,如 Apache Kafka、Apache Cassandra、Elasticsearch、
JDBC、Kinesis 和(分布式)文件系统,如 HDFS 和 S3。
5:高可用。本身高可用的设置,加上与 K8s,YARN 和 Mesos 的紧密集成,再加上从故
障中快速恢复和动态扩展任务的能力,Flink 能做到以极少的停机时间实现 7×24 全
天候运行。
6:能够更新应用程序代码并将作业(jobs)迁移到不同的 Flink 集群,而不会丢失应用
程序的状态
10:总结常用的FS(分布式存储系统)
目前主流的分布式文件系统有:GFS、HDFS、S3、NFS、Ceph、Lustre、MogileFS、MooseFS、FastDFS、TFS、GridFS等。
11:flink中几个关键组件?
Flink运行时的组件包括:作业管理器、任务管理器、资源管理器、客户端。
12:命令
启动bin/start-cluster.sh
关闭 bin/stop-cluster.sh
13:总结提交方式
1:在 Web UI 上提交作业 Submit New Job ----+ Add New
2:命令行提交作业
bin/flink run -m hadoop102:8081 -c com.flinkscala.wc.StreamWordCount ./FlinkTutorial-1.0-SNAPSHOT.jar
这里的参数 –m 指定了提交到的 JobManager,-c 指定了入口类。
查看日志:cat flink-flinkscala-taskexecutor-0-hadoop102.out
14:flink部署模式 区别?
1:会话模式(Session Mode) 适合于单个规模小、执行时间短的大量作业
2:单作业模式(Per-Job Mode)会话模式因为资源共享会导致很多问题,所以为了更好地隔离资源,我们可以考虑为每个提交的作业启动一个集群,Flink 本身无法直接这样运行,所以单作业模式一般需要借助一些资源管
理平台来启动集群,比如 YARN、Kubernetes。
3:应用模式(Application Mode) 不要客户端,直接把应用提交到 JobManger 上运行。
为每一个提交的应用单独启动一个 JobManager 也就是创建一个集群,执行结束之后 JobManager 也就关闭这就是所谓的应用模
它们的区别主要在于:集群的生命周期以及资源的分配方式;以及应用的 main 方法到底
在哪里执行——客户端(Client)还是 JobManager。
应用模式与单作业模式,都是提交作业之后才创建集群;会话模式、单作业模式是通过客户端来提的,客户端解析出的每一个作业对应一个集群;而应用模式下,是直接由 JobManager 执行应用程序的,并且即使应用包含了多个作业,也只创建一个集群。
15:什么是单作业模式?Per-Job Mode
为了更好地隔离资源,为每个提交的作业启动一个集群
16:flink型对于spark的优点:
Flink 的延迟是毫秒级别,而 Spark Streaming 的延迟是秒级延迟。
Flink 提供了严格的精确一次性语义保证。
Flink 的窗口 API 更加灵活、语义更丰富。
Flink 提供事件时间语义,可以正确处理延迟数据。
Flink 提供了更加灵活的可对状态编程的 API。
17:总结提交命令
1:独立模式下的应用部署
1:将应用程序的 jar 包放到 lib/目录下
2:启动 JobManager
./bin/standalone-job.sh start --job-classname com.flinkscala.wc.StreamWordCount
3:使用 bin 目录下的脚本,启动 TaskManager
./bin/taskmanager.sh start
4:如果希望停掉集群,同样可以使用脚本,命令如下。
$ ./bin/standalone-job.sh stop
$ ./bin/taskmanager.sh stop
2:yarn模式
1;会话模式部署
向 YARN 集群申请资源,开启一个 YARN 会话,启动 Flink 集群。
$ bin/yarn-session.sh -nm test
提交作业两种方式 :通过 Web UI 提交作业与上雷同
通过命令行提交作业
① 将 Standalone 模式讲解中打包好的任务运行 JAR 包上传至集群
② 执行以下命令将该任务提交到已经开启的 Yarn-Session 中运行。
$ bin/flink run
-c com.flinkscala.wc.StreamWordCount FlinkTutorial-1.0-SNAPSHOT.jar
2:单作业模式部署
在 YARN 环境中,由于有了外部平台做资源调度,所以我们也可以直接向 YARN 提交一 个单独的作业,从而启动一个 Flink 集群。
(1)执行命令提交作业。
$ bin/flink run -d -t yarn-per-job -c com.flinkscala.wc.StreamWordCount
FlinkTutorial-1.0-SNAPSHOT.jar
早期版本也有另一种写法:
$ bin/flink run -m yarn-cluster -c com.flinkscala.wc.StreamWordCountFlinkTutorial-1.0-SNAPSHOT.jar
(3)可以使用命令行查看或取消作业,命令如下。
$ ./bin/flink list -t yarn-per-job -Dyarn.application.id=application_XXXX_YY
$ ./bin/flink cancel -t yarn-per-job -Dyarn.application.id=application_XXXX_YY
这里的 application_XXXX_YY 是当前应用的 ID,
业,整个 Flink 集群也会停掉。
3应用程序部署
应用模式同样非常简单,与单作业模式类似,直接执行 flink run-application 命令即可。
(1)执行命令提交作业。
$ bin/flink run-application -t yarn-application -c com.
flinkscala.wc.StreamWordCount FlinkTutorial-1.0-SNAPSHOT.jar
2)在命令行中查看或取消作业。
$ ./bin/flink list -t yarn-application -Dyarn.application.id=application_XXXX_YY
$ ./bin/flink cancel -t yarn-application-Dyarn.application.id=application_XXXX_YY
3)也可以通过 yarn.provided.lib.dirs 配置选项指定位置,将 jar 上传到远程。
$ ./bin/flink run-application -t yarn-application
-Dyarn.provided.lib.dirs="hdfs://myhdfs/my-remote-flink-dist-dir"
hdfs://myhdfs/jars/my-application.jar
这种方式下 jar 可以预先上传到 HDFS,而不需要单独发送到集群,这就使得作业提交更
加轻量了
18:flink运行时架构中最重要的两大组件
作业管理器(JobManger)和任务管理器
JobManager 是真正意义上的“管理者”(Master), 负责管理调度
TaskManager 是“工作者”(Worker、Slave),负责执行任务处理数据,所以可以有一个或多个
19:作业管理器(JobManger)包含组件,作用?
1.JobMaster:
1:JobMaster 接收到要执行的应用。把作业图( JobGraph) 转换成执行图”(ExecutionGraph),它包含了所有可以并发 执行的任务。
2:JobMaster 会向资源管理器(ResourceManager)发出请求,申请资源。一旦它获取到了足够的资源,就会将执行图分发到真正运行它们TaskManager 上。
3:运行过程中,JobMaster 会负责所有需要中央协调的操作,比如说检查点(checkpoints)
的协调。
2.资源管理器(ResourceManager)
1:ResourceManager 主要负责资源的分配和管理,针对不同的环境和资源管理平台(比如 Standalone 部署,或者YARN),有不同的具体实现在 Standalone 部署时,因为 TaskManager 是单独启动的(没有Per-Job 模式),所以 ResourceManager 只能分发可用 TaskManager 的任务槽,不能单独启动新 TaskManager。 而在有资源管理平台时,就不受此限制。当新的作业申请资源时,ResourceManager 会将有空闲槽位的 TaskManager 分配给 JobMaster。如果 ResourceManager 没有足够的任务槽,它还可以向资源提供平台发起会话,请求提供启动 TaskManager 进程的容器。另外, ResourceManager 还负责停掉空闲的 TaskManager,释放计算资源。
3. 分发器(Dispatcher)
主要负责提供一个 REST 接口,用来提交作业,
并且负责为每一个新提交的作 业启动一个新的 JobMaster 组件。
Dispatcher 也会启动一个 Web UI,用来方便地展示和监控作业执行的信息。
Dispatcher 在架构中并不是必需的,在不同的部署模式下可能会被忽略掉
20:任务管理器(taskManager)作用?
1:负责数据流的具体计算任务(task)
2:管理slot,包含了一定数量的任务槽(task slots)。Slot 是资源调度的最小单位,slots
的数量限制了 TaskManager 能够并行处理的任务数量。
3:向资源管理器注册slots
4:可以缓冲数据,还可以跟其他运行同一应用的 TaskManager 交换数据
21:画出作业提交流程
(1)客户端(App)通过分发器提供的REST接口,将作业提交给JobManager。
(2)由分发器启动 JobMaster,并将作业(包含 JobGraph)提交给 JobMaster。
(3)(3)JobMaster 将 JobGraph 解析为可执行的 ExecutionGraph,得到所需的资源数量,然后向资源管理器请求任务槽资源(slots)。
(4)资源管理器判断当前是否由足够的可用资源;如果没有,启动新的 TaskManager。
(5)TaskManager 启动之后,向 ResourceManager 注册自己的可用任务槽(slots)。
(6)资源管理器通知 TaskManager 为新的作业提供 slots。
(7)TaskManager 连接到对应的 JobMaster,提供 slots。
(8)JobMaster 将需要执行的任务分发给 TaskManager。
(9)TaskManager 执行任务,互相之间可以交换数据(统一应用)
22:Flink 程序都可以归纳为由三部分构成
为由三部分构成:Source、Transformation 和 Sink。
⚫ Source 表示“源算子”,负责读取数据源。
⚫ Transformation 表示“转换算子”,利用各种算子进行处理加工。
⚫ Sink 表示“下沉算子”,负责数据的输出
23:并行度设置?什么是并行度(Parallelism)?
Flink 执行过程中,每一个算子(operator)可以包含一个或多个子任务(operator subtask),
这些子任务在不同的线程、不同的物理机或不同的容器中完全独立地执行。
一个特定算子的子任务(subtask)的个数被称之为其并行度(parallelism)。这样,包含并
行子任务的数据流,就是并行数据流,
(1)代码中设置
stream.map((_,1)).setParallelism(2) 对当前算子有效。
全局设定并行度: env.setParallelism(2)
(2)提交作业时设置bin/flink run –p 2
–c com.flinkscala.wc.StreamWordCount ./FlinkTutorial-1.0-SNAPSHOT.jar
(3)配置文件中设置
集群的配置文件 flink-conf.yaml 中直接更改默认并行度:
24:算子链(Operator Chain)的好处
定义:并行度相同的一对一算子操作
禁用算子链disableOperatorChaining(全局禁用)disableChaining(单个算子禁用)
好处:能够减少不必要的数据交换、序列化和上下文切换,从而提高作业的执行效率。
25:算子任务间的数据传输形式?
1:一对一(one to one)的直通模式(forwarding)
2:重分区(redistributing)模式
26:flink中任务执行调度图
逻辑流图(StreamGraph)→ 作业图(JobGraph)→ 执行图(ExecutionGraph)→ 物理
图(Physical Graph)。
27:flink支持的数据类型
(1)基本类型
所有 Java 基本类型及其包装类,再加上 Void、String、Date、BigDecimal 和 BigInteger。
(2)数组类型
包括基本类型数组(PRIMITIVE_ARRAY)和对象数组(OBJECT_ARRAY)
(3)复合数据类型
⚫ Java 元组类型(TUPLE):这是 Flink 内置的元组类型
⚫ Scala 样例类及 Scala 元组:不支持空字段
⚫ 行类型(ROW):可以认为是具有任意个字段的元组,并支持空字段
⚫ POJO:Flink 自定义的类似于 Java bean 模式的类
(4)辅助类型 Option、Either、List、Map 等
(5)泛型类型(GENERIC)
28:什么是富函数?
“富函数类”也是 DataStream API 提供的一个函数类的接口,所有的 Flink 函数类都有其
Rich 版本。富函数类一般是以抽象类的形式出现的
与常规函数类的不同主要在于,富函数类可以获取运行环境的上下文,并拥有一些生命周
期方法,所以可以实现更复杂的功能(open初始化工作、close清理类工作)
29:flink的物理分区?(Physical Partitioning)
Flink 对于经过转换操作之后的 DataStream,提供了一系列的底层操作算子,能够帮我们
实现数据流的手动重分区。为了同 keyBy()相区别,我们把这些操作统称为“物理分区”操作。
常见的物理分区策略有随机分区(shuffle)、轮询分区(Round-Robin) 、重缩放(rescale)
和广播(broadcast) ,还有一种特殊的分区策略— —全局分区(global),并且 Flink 还支持用户自定义分区策略(Custom)
30:什么是窗口?
就是将无限数据切割成有限的“数据块”进行处理,这
就是所谓的“窗口”(Window)。在 Flink 中, 窗口就是用来处理无界流的核心。
31:flink 时间语义?
流式数据处理的过程有两个非常重要的时间点:一个是数据产生的时间,我们把它叫作“事件时间”(Event Time);另一个是数据真正被处理的时刻,叫作“处理时间”(Processing Time)。 我们所定义的窗口操作,到底是以那种时间作为衡量标准,就是所谓的“时间语义”
32:什么是乱序?原因?
由于分布式系统中网络传输延迟的不确定性,导致顺序发生改变,这就是所谓的“乱序数据”
33:什么是水位线
在 Flink 中,这种用来衡量事件时间(Event Time)进展的标记,就被称作“水位线(Watermark)。
Flink 中的水位线,其实是流处理中对低延迟和结果正确性的一个权衡机制,而且把
控制的权力交给了程序员,我们可以在代码中定义水位线的生成策略。
34:窗口的分类?具体实现可以分为?
1. 按照驱动类型分类
按照时间段去截取数据,这种窗口就叫作“时间窗口”
按照固定的个数,来截取一段数据集,这种窗口叫作“计数窗口
2. 按照窗口分配数据的规则分类
根据分配数据的规则,窗口的具体实现可以分为 4 类:滚动窗口(Tumbling Window)、
滑动窗口(Sliding Window)、会话窗口(Session Window),以及全局窗口(Global Window)。
35:什么是窗口函数?
定义了要对窗口中收集的数据做的计算操作
36:窗口函数分类?
1.增量聚合函数(incremental aggregation functions)
来一条数据就立即进行计算不立即输出结果,而是要等到
窗口结束时间。等到窗口到了结束时间需要输出计算结果的时候,我们只需要拿出之前聚合的 状态直接输出,这无疑就大大提高了程序运行的效率和实时性。
典型的增量聚合函数有两个:ReduceFunction 和 AggregateFunction。
2.全窗口函数(Full Window Functions)
先收集窗口中的数据,并在内部缓存起来,等到窗口要输出结果的时候再取出数据进行计算
全窗口函数也有两种:WindowFunction 和 ProcessWindowFunction
37 :时间相关
事件时间 eventTime
wm时间 wmTime=max(eventtime)-t 认为小于wm时间的数据全部到达了
延迟时间 t
窗口时间 windowTime
触发窗口计算 widowTime=wmtime-t
38:水位线特性
⚫ 水位线是插入到数据流中的一个标记,可以认为是一个特殊的数据
⚫ 水位线主要的内容是一个时间戳,用来表示当前事件时间的进展
⚫ 水位线是基于数据的时间戳生成的
⚫ 水位线的时间戳必须单调递增,以确保任务的事件时间时钟一直向前推进
⚫ 水位线可以通过设置延迟,来保证正确处理乱序数据
⚫ 一个水位线 Watermark(t),表示在当前流中事件时间已经达到了时间戳 t, 这代表 t 之
前的所有数据都到齐了,之后流中不会出现时间戳 t’ ≤ t 的数据
39:flink 迟到的数据如何处理?
默认丢弃处理
1:设置水位线延迟时间
2:允许窗口处理迟到数据.allowedLateness
3:将迟到数据放入窗口侧输出流
40:什么是侧输出流?(side output)
相当于输出流的一个分支,这个流单独放置本该丢弃的数据
41:窗口的生命周期
1.窗口的创建 当第一个窗口元素到达时开始创建 窗口分配器指定窗口的类型和基本信息
2. 窗口计算的触发 窗口函数(window functions)和触发器(trigger)。
窗口函数可以分为增量聚合函数和全窗口函数,主要定义了窗口中计算的逻辑;而触发器则是 指定调用窗口函数的条件。
3. 窗口的销毁 当时间达到了结束点,就会直接触发计算输出结果、进而清除状态销毁窗口。
Flink 中只对时间窗口(TimeWindow)有销毁机制;由于计数窗口(CountWindow)是基于全局窗口(GlobalWindw)实现的,而全局窗口不会清除状态,所以就不会被销毁。
42:Flink 提供了 8 个不同的处理函数
转换算子,一般只是针对某种具体操作来定义的,能够拿到的信息比较有限
富函数类提供了获取运行时上下文的方法 getRuntimeContext(),可以拿到状态,还有并行度、任务名称之类的运行时信息。
处理函数提供了一个“定时服务可访问流中的事件 (event)、时间戳(timestamp)、水位线(watermark),甚至可以注册“定时事件”
继承了 AbstractRichFunction 抽象类,所以拥有富函数类的所有特性,同样可以访问状态
(state)和其他运行时信息。此外,处理函数还可以直接将数据输出到侧输出流(side output)
中。所以,处理函数是最为灵活的处理方法,可以实现各种自定义的业务逻辑;同时也是整个 DataStream API 的底层基础。
(1)ProcessFunction
(2)KeyedProcessFunction
(3)CoProcessFunction
(4)ProcessJoinFunction
(5)BroadcastProcessFunction
(6)KeyedBroadcastProcessFunction
(7)ProcessWindowFunction
(8)ProcessAllWindowFunction
43:flink的分流如何实现?
Filter
侧输出流
44:合并流有哪些?区别
联合Union:流中的数据类型必须相同,可以多条流
连接(Connect) :数据类型可以不同,只能两条流
基于时间的合流—双流联结(Join)根据某个字段的值将它们联结
起来“配对”去做处理
45:flink状态分类?区别?
托管状态(Managed State)和原始状态(Raw State)。
托管状态就是 由 Flink 统一管理的,状态的存储访问、故障恢复和重组等一系列问题都由 Flink 实现,我们 只要调接口就可以;
而原始状态则是自定义的,相当于就是开辟了一块内存,需要我们自己管理,实现状态的序列化和故障恢复。
46:托管状态分为两类?
算子状态:作用范围限定为当前的算子任务实例,也就是只对当前并行子任务实例有效
按键分区状态: 任务按照键(key)来访问和维护的状态,以 key 为作用范围进行隔离。
在进行按键分区之后,具有相同键的所有数据,都会分配到同一个并行子任务中
47:按键分区状态(Keyed State)支持的结构类型
1. 值状态(ValueState)
2. 列表状态(ListState)
3. 映射状态(MapState)
4. 归约状态(ReducingState)
5. 聚合状态(AggregatingState)
48.算子状态(Operator State)支持的结构类型
1.列表状态(ListState)
2. 联合列表状态(UnionListState)
3. 广播状态(BroadcastState)
49.什么情况下会调用 initializeState()方法
算子任务进行初始化时,会调用 initializeState()方法。
这又有两种情况:一种是整个应用第一次运行,这时状态会被初始化为一个默认值(default value);另一种是应用重启时,从检 查点(checkpoint)或者保存点(savepoint)中读取之前状态的快照,并赋给本地状态。
50.“检查点”(checkpoint)的保存点(savepoint)的区别?
就是触发的时机。检查点是由 Flink 自动管理的,定期创建,发生故障之后自动读取进行恢复,这是一个“自动存盘”的功能;而保存点不会自动创建,必须由用户明确地手动触发保存操作,所以就是“手动存盘”。因此两者尽管原理一致,但用途 就有所差别了:检查点主要用来做故障恢复,是容错机制的核心;保存点则更加灵活,可以用 来做有计划的手动备份和恢复
51.什么是检查点?
我们可以将之前某个时间点所有的状态保存下来,这份“存档”就是所谓的“检查点”
(checkpoint)。
52.什么是状态后端?作用? 分类? 区别?
在 Flink 中,状态的存储、访问以及维护,都是由一个可插拔的组件决定的,这个组件就
叫作状态后端(state backend)。状态后端主要负责两件事:一是本地的状态管理,二是将检查点(checkpoint)写入远程的持久化存储
Flink 中提供了两类不同的状态后端,一种是“哈希表状态后端”(HashMapStateBackend),另一种是“内嵌 RocksDB 状态后端”(EmbeddedRocksDBStateBackend)。如果没有特别配置,系统默认的状态后端是 HashMapStateBackend。
HashMap 和 RocksDB 两种状态后端最大的区别,就在于本地状态存放在哪里:前者是内
存,后者是 RocksDB。在实际应用中,选择那种状态后端,主要是需要根据业务需求在处理性能和应用的扩展性上做一个选择。
HashMapStateBackend 是内存计算,读写速度非常快;但是,状态的大小会受到集群可用
内存的限制,如果应用的状态随着时间不停地增长,就会耗尽内存资源。
而 RocksDB 是硬盘存储,所以可以根据可用的磁盘空间进行扩展,而且是唯一支持增量
检查点的状态后端,所以它非常适合于超级海量状态的存储。不过由于每个状态的读写都需要做序列化/反序列化,而且可能需要直接从磁盘读取数据,这就会导致性能的降低,平均读写性能要比 HashMapStateBackend 慢一个数量级
53.状态后端的配置?
(1)配置默认的状态后端
在 flink-conf.yaml 中,可以使用 state.backend 来配置默认状态后端。
(2)为每个作业(Per-job)单独配置状态后端
每个作业独立的状态后端,可以在代码中,基于作业的执行环境直接设置
54.从检查点来恢复状态的步骤?
(1)重启应用
(2)读取检查点,重置状态
(3)重放数据
(4)继续处理数据
55.保存点的场景?
版本管理和归档存储
更新 Flink 版本
更新应用程序
调整并行度
暂停应用程序
56.状态一致性
一致性其实就是结果的正确性,遇到故障时恢复状态,恢复以后的重新计算,结果应该也是完全正确的
57.一致性的级别?
最多一次(AT-MOST-ONCE)故障发生之后,计数结果可能丢失
至少一次(AT-LEAST-ONCE)计数结果可能大于正确值,但绝不会小于正确值
精确一次(EXACTLY-ONCE) 系统保证在发生故障后得到的计数结果与正确值一致
58.什么是端到端的状态一致性?
完整的流处理应用,包括数据源、流处理器和外部存储系统三个部分。这个完整应用的一致性,就叫作“端到端(end-to-end)的状态一致性”,它取决于三个组件中最弱的那一环。
59.Source 保证exactly-once一致性的方案?
数据源可重放数据(进行持久化保存),或者说可重置读取数据偏移量,加上 Flink 的 Source 任务将偏移量作为状态保存进检查点,就可以保证数据不丢。这是达到 at-least-once 一致性语义的基本要求,当然也是实现端到端 exactly-once 的基本要求
60.sink 保证 exactly-once 一致性的方案?
⚫ 幂等写入
⚫ 事务写入
61.什么是幂等(idempotent)写入?
所谓“幂等”操作,就是说一个操作可以重复执行很多次,但只导致一次结果更改。也就
是说,后面再重复执行就不会对结果起作用了。
遇到故障进行恢复时,有可能会出现短暂的不一致,因为保存点完成之后到发生故障之间的数据,其实已经写入了一遍,过当数据的重放逐渐超过发生故障的点的时候,最终的结果还是一致的。
62.事务写入又有两种实现方式?
事务有四个基本特性:原子性(Atomicity)、
一致性(Correspondence)、隔离性(Isolation)和持久性(Durability),这就是著名的 ACID。
两种实现方式:预写日志(WAL)和两阶段提交(2PC)
63.预写日志(WAL)的步骤
①先把结果数据作为日志(log)状态保存起来
②进行检查点保存时,也会将这些结果数据一并做持久化存储
③在收到检查点完成的通知时,将所有结果一次性写入外部系统。
64.两阶段提交的步骤?
①当第一条数据到来时,或者收到检查点的分界线时,Sink 任务都会启动一个事务。
②接下来接收到的所有数据,都通过这个事务写入外部系统;这时由于事务没有提交,所
以数据尽管写入了外部系统,但是不可用,是“预提交”的状态。
③当 Sink 任务收到 JobManager 发来检查点完成的通知时,正式提交事务,写入的结果就真正可用了。
65.Flink 和 Kafka 连接时的精确一次保证
(1)Flink 内部
Flink 内部可以通过检查点机制保证状态和处理结果的 exactly-once 语义。
(2)输入端
输入数据源端的 Kafka 可以对数据进行持久化保存,并可以重置偏移量(offset)。
(3)输出端
输出端保证 exactly-once 的最佳实现,当然就是两阶段提交(2PC)。
66.表环境的作用?
(1)注册 Catalog 和表;
(2)执行 SQL 查询;
(3)注册用户自定义函数(UDF);
(4)DataStream 和表之间的转换。
67.什么是catalog
Catalog 就是“目录”,与标准 SQL 中的概念是一致的,主要用来管理所有数据库
(database)和表(table)的元数据(metadata)。默认的 Catalog 叫作 default_catalog。
68.表在环境中ID组成
表在环境中有一个唯一的 ID,由三部分组成:目录(catalog)名,数据库(database)名,以及表名。在默认情况下,目录名为 default_catalog,数据库名为default_database。所以如果我们直接创建一个叫作 MyTable 的表,它的 ID 就是:
default_catalog.default_database.MyTable
69.创建表的方式?
连接器(connector)和虚拟表(virtual tables)两种
70.什么是DDL DML DCL ...
DQL:数据查询语句 DDL:数据定义语句 DCL:数据控制语句 DML:数据操作语句
71.flink sql支持的数据类型?
(1)原子类型 基础数据类型(Int、Double、String)和通用数据类型(也就是不可再拆分
的数据类型)统一称作“原子类型
(2)Tuple 类型
(3)case class 类型 多种数据类型组合成的“复合类型”,最典型的就是简单样例类对象(case class 类型)
(4)Row 类型 Table 中数据的基本组织形式(通用)。Row 类型也是一种复合类型,
72.什么是动态表(Dynamic Tables)?
当流中有新数据到来,初始的表中会插入一行;而基于这个表定义的 SQL 查询,就应该
在之前的基础上更新结果。这样得到的表就会不断地动态变化,被称为“动态表”(Dynamic
Tables)。
73.什么是 持续查询?
动态表可以像静态的批处理表一样进行查询操作。由于数据在不断变化,因此基于它定义
的 SQL 查询也不可能执行一次就得到最终结果。这样一来,我们对动态表的查询也就永远不会停止,一直在随着新数据的到来而继续执行。这样的查询就被称作“持续查询”(Continuous Query)。对动态表定义的查询操作,都是持续查询;而持续查询的结果也会是一个动态表。
74.动态表转换为流的方式?
(1)仅追加(append-only)流
仅通过插入(insert)更改来修改的动态表,可以直接转换为“仅追加”流。这个流中发出的数据,其实就是动态表中新增的每一行。
(3)撤回(retract)流
撤回流是包含两类消息的流,添加(add)消息和撤回(retract)消息
(3)更新插入(upsert)流
更新插入流中只包含两种类型的消息:更新插入(upsert)消息和删除(delete)消息。
75.Flink SQL 目前提供的窗口?
滚动窗口 TUMBLE()、滑动窗口 HOP()和累积窗口(CUMULATE) 三种表值函数(TVF)。
76.什么是CEP?
“复杂事件处理(Complex Event Processing)”的缩写
可以在事件流里,检测到特定的事件组合并进行处理,
77.近邻关系有哪些?
严格近邻(Strict Contiguity) next方法
宽松近邻(Relaxed Contiguity) followedBy方法
非确定性宽松近邻(Non-Deterministic Relaxed Contiguity)followedByAny方法
78.CEP 的 模式?
个体模式 :将一组简单事件组合成复杂事件的“匹配规则”
组合模式 :按一定的顺序把个体模式连接起来,定义一个完整的复杂事件匹配规则了。就叫作“组合模式”(Combining Pattern),为了跟个体模式区分有时也叫作“模式序列”(Pattern Sequence)。
模式组:以一个模式序列作为参数,将模式序列连接组合起来了。“模式组”
(Groups of Patterns)。
79.CEP 的应用场景?
CEP 主要用于实时流数据的分析处理。CEP 可以帮助在复杂的、看似不相关的事件流中
找出那些有意义的事件组合,进而可以接近实时地进行分析判断、输出通知信息或报警。
这在企业项目的风控管理、用户画像和运维监控中,都有非常重要的应用。
80.检测匹配事件的过程中的状态?
初始(没有任何匹配),检测中(部分匹配成功),匹配成功,匹配失败
81.个体模式量词
oneOrMore 匹配事件出现一次或多次
times(times) 匹配事件发生特定次数(times),例如 a.times(3)表示 aaa
times(fromTimes,toTimes) 匹配事件出现的次数范围,
greedy 只能用在循环模式后,使当前循环模式变得“贪心”(greedy),也就是总是尽可能多地去匹配a.times(2, 4).greedy,如果出现了连续 4 个 a,那么会直接把 aaaa 检测出来进行处理,其他任意 2 个 a 是不算匹配事件的。
optional 使当前模式成为可选的,也就是说可以满足这个匹配条件,
匹配事件出现 4 次,或者不出现
pattern.times(4).optional