本文《尼恩 大数据 面试宝典》 是 《尼恩Java面试宝典》姊妹篇。
这里特别说明一下:《尼恩Java面试宝典》41个专题 PDF 自首次发布以来, 已经汇集了 好几千题,大量的大厂面试干货、正货 ,足足4800多页,帮助很多小伙伴进了大厂,拿了高薪。
《尼恩Java面试宝典》面试题集合, 已经变成Java 学习和面试的必读书籍。
于是,尼恩架构团队 趁热打铁,推出 《尼恩 大数据 面试宝典》,已经发布了几个专题:
《尼恩大数据面试宝典专题1:史上最全Hadoop面试题》
《尼恩大数据面试宝典专题2:绝密100个Spark面试题,熟背100遍,猛拿高薪》
《尼恩大数据面试宝典专题3:史上最全Hive面试题,不断迭代,持续升级》
《尼恩大数据面试宝典专题4:史上最全Flink面试题,不断迭代,持续升级》(本文)
《尼恩 大数据 面试宝典》 后面会不断升级,不断 迭代, 变成大数据领域 学习和面试的必读书籍,帮助大家成长为 三栖合一架构师,进了大厂,拿了高薪。
《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到公号【技术自由圈】取
一作:Mark, 资深大数据架构师、Java架构师,近20年Java、大数据架构和开发经验。资深架构导师,成功指导了多个中级Java、高级Java转型架构师岗位。
二作:尼恩,41岁资深老架构师, IT领域资深作家、著名博主。《Java 高并发核心编程 加强版 卷1、卷2、卷3》创世作者。 《K8S学习圣经》《Docker学习圣经》《Go学习圣经》等11个PDF 圣经的作者。 也是一个 资深架构导师、架构转化 导师, 成功指导了多个中级Java、高级Java转型架构师岗位, 最高的学员年薪拿到近100W。
Flink 是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。并且 Flink 提供了数据分布、容错机制以及资源管理等核心功能。Flink提供了诸多高抽象层的API以便用户编写分布式任务:
此外,Flink 还针对特定的应用领域提供了领域库,例如: Flink ML,Flink 的机器学习库,提供了机器学习Pipelines API并实现了多种机器学习算法。 Gelly,Flink 的图计算库,提供了图计算的相关API及多种图计算算法实现。
Flink的主要特点包括:
Flink 适用于以下应用场景:
Flink 是一个通用的大数据处理框架,可以适用于各种大规模数据处理和分析的场景,尤其适用于需要实时处理和分析的场景。
其实就一句话,就是 Source->Transformation*->Sink
Flink 编程模型是一种用于处理流式数据的编程模型,它包括三个核心概念:Source、Transformation 和 Sink。数据流从 Source 开始,经过多个 Transformation 操作,最终到达 Sink 结束。在这个过程中,数据可以被处理、过滤、转换、聚合等操作,以实现数据的实时处理和分析。
具体来说,Flink 编程模型中,开发者需要首先指定数据的 Source,即数据的来源,可以是文件、网络数据流、数据库等。然后,通过一系列 Transformation 操作对数据进行处理,例如过滤、映射、聚合、窗口等操作。这些 Transformation 操作可以组合使用,以实现复杂的数据处理和分析。最后,将处理后的数据发送到 Sink 端,即数据的去向,可以是文件、网络数据流、数据库等。
Flink 编程模型支持事件时间语义,即数据处理按照事件发生的时间进行排序和处理。同时,Flink 还支持窗口操作、状态管理和事件处理等功能,以实现更复杂的数据处理和分析场景。
Flink程序在运行时主要有TaskManager,JobManager,Client三种角色。
当 Flink 集群启动后,⾸先会启动⼀个 JobManger 和⼀个或多个的 TaskManager。由 Client 提交任务给 JobManager,JobManager 再调度任务到各个 TaskManager 去执⾏,然后 TaskManager 将⼼跳和统计信息汇报给 JobManager。TaskManager 之间以流的形式进⾏数据的传输。上述三者均为独⽴的 JVM 进程。
Flink的集群部署模式包括:
集群规模通常与公司的业务需求、数据量、计算资源等因素密切相关。
在实际应用中,Flink 集群的规模可能会从几台到几十台甚至上百台节点不等。集群规模的大小取决于业务需求和数据处理能力。大型互联网公司可能需要处理更多的数据和请求,因此他们的 Flink 集群规模可能会更大。
在部署方式上,大部分公司采用 YARN 模式进行部署。YARN 提供了一种分布式资源管理的方式,可以更好地调度和管理集群中的资源。根据公司的需求和资源配置,YARN 可以选择不同的部署模式,如单 job 模式或批量模式。这些部署模式的选择会影响到集群的规模和性能。
总之,Flink 集群规模的大小会根据公司的实际需求和资源配置而有所不同,需要根据具体情况进行评估和优化。
Flink 集群优化是提高 Flink 集群性能的关键步骤。
以下是一些 Flink 集群优化的建议:
总结起来,Flink 集群优化需要综合考虑多个方面,包括内存管理、任务调度、网络配置、状态管理和高级优化功能等。通过调整这些参数和配置,可以显著提高 Flink 集群的性能和效率。
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,两个备用 Job Manager,然后结合 ZooKeeper 的使用,来达到高可用;对于yarn模式,yarn在Job Mananger故障会自动进行重启,所以只需要一个,我们配置的最大重启次数是10次。
Flink 程序由多个任务(Source、Transformation、Sink)组成。任务被分成多个并行实例来执行,每个并行实例处理任务的输入数据的子集。任务的并行实例的数量称之为并行度。
我们在实际生产环境中可以从四个不同层面设置并行度:
需要注意的优先级:算子层面>环境层面>客户端层面>系统层面(实际业务中通常设置和kafka分区数一样或者kafka分区倍数的并行度)。
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。
Flink 的 Checkpoint 是 Flink 的核心组件之一,它用于记录应用程序在特定时刻的状态,以便在应用程序失败时进行恢复。Checkpoint 通常存储在 Flink 的存储系统中,可以是内存、文件系统或 RocksDB。
1. 内存
Flink 的内存状态是存储在 Java 内存中的。当应用程序运行时,Flink 会将状态数据存储在内存中,并定期将这些状态数据持久化到外部存储系统中。如果应用程序在运行时出现故障,Flink 可以从内存状态中恢复应用程序的状态。
2. 文件系统
Flink 也可以将状态数据存储在文件系统中。当应用程序运行时,Flink 会将状态数据写入分布式文件系统,如 HDFS 或 NFS。如果应用程序在运行时出现故障,Flink 可以从文件系统中恢复应用程序的状态。
3. RocksDB
Flink 还可以将状态数据存储在 RocksDB 中。RocksDB 是一种高性能、高可靠性的键值存储数据库,它支持高效的数据压缩和快速查找。当应用程序运行时,Flink 会将状态数据写入 RocksDB 数据库,并定期将这些状态数据持久化到外部存储系统中。如果应用程序在运行时出现故障,Flink 可以从 RocksDB 中恢复应用程序的状态。
总之,Flink 的 Checkpoint 可以存储在内存、文件系统或 RocksDB 中,具体存储位置由用户配置决定。Flink 提供了一些 API 来管理 Checkpoint,如 checkpointCoordinator.checkpoint() 方法和 checkpointCoordinator.restoreFromCheckpoint() 方法。使用这些 API,用户可以手动触发 Checkpoint,也可以在应用程序失败时自动恢复状态。
Flink 和 Spark 都是主流的大数据处理框架,它们都支持 Checkpoint 机制以保证实时数据的可靠性和容错性。然而,Flink 和 Spark 的 Checkpoint 机制在实现方式和功能上有一些不同之处。
1. 实现方式
Flink 的 Checkpoint 机制采用了轻量级的分布式快照技术,实现了每个算子的快照以及流动中的数据的快照。这种快照技术可以快速地保存和恢复状态数据,从而减少了故障恢复的时间。而 Spark 的 Checkpoint 机制主要是针对 Driver 的故障恢复做了数据和元数据的 Checkpoint,没有实现算子的快照。
2. 故障恢复
Flink 的 Checkpoint 机制可以支持任意节点的故障恢复,包括算子和 Driver。当一个节点出现故障时,Flink 会自动切换到其他可用节点,并从最近的 Checkpoint 开始恢复状态数据。而 Spark 的 Checkpoint 机制只能恢复 Driver 的故障,对于算子的故障则需要重新启动整个应用程序。
3. 数据一致性
Flink 的 Checkpoint 机制可以保证数据一致性,即同一个 Checkpoint 下的所有算子都处于同一个状态。这是因为 Flink 使用了分布式快照技术,确保每个算子都保存了相同的状态数据。而 Spark 的 Checkpoint 机制并不能保证数据一致性,因为在 Spark 中,每个算子都可能保存了不同的状态数据。
4. 性能影响
Flink 的 Checkpoint 机制采用了轻量级的分布式快照技术,因此其性能影响相对较小。Spark 的 Checkpoint 机制需要将整个应用程序的状态数据都保存到外部存储系统中,因此其性能影响相对较大。
总的来说,Flink 的 Checkpoint 机制相对于 Spark 的 Checkpoint 机制更为复杂和强大,可以支持任意节点的故障恢复,并保证数据一致性。此外,Flink 的 Checkpoint 机制采用了轻量级的分布式快照技术,因此其性能影响相对较小。这些优势使得 Flink 在实时数据处理方面具有更好的可靠性和容错性。
Flink 是一个流处理框架,提供了丰富的算子用于数据的处理和转换。以下是一些常见的算子:
除了上述算子之外,Flink 还提供了很多其他算子,例如 Union、HashJoin、Sort、Limit 等,以实现更复杂的数据处理和分析场景。
Flink的流式处理可以通过以下方式处理延迟:
事件时间处理:Flink支持事件时间处理,可以处理乱序事件,根据事件时间对数据进行排序和处理,从而解决延迟问题。
窗口操作:Flink的窗口操作可以根据事件时间或处理时间对数据流进行划分和处理,可以根据需要设定窗口大小和滑动间隔来控制延迟的处理。
Flink支持两种划分窗口的方式,按照time和count,session也是一种时间。
答案:Flink支持与多种第三方工具和框架的集成,包括:
Flink支持多种数据源和数据接收器,包括:
Flink内置了一些基本数据源和接收器,它们始终可用。该预定义的数据源包括文件、目录和Socket,并可以加载集合和迭代器的数据。该预定义的数据接收器支持写入文件,输出信息和异常 。
Flink支持多种批处理操作,包括:
Flink 可以无缝地在流处理和批处理之间切换,这主要归功于其基于事件时间的窗口处理机制和灵活的作业调度策略。Flink 提供了两种作业类型:批处理作业和流处理作业。
1. 批处理作业:
批处理作业将数据作为有界数据集进行处理,类似于传统的批处理作业。在批处理模式下,Flink 会将数据按照批次进行划分,然后对每个批次进行离线处理。批处理作业通常用于处理历史数据或者定期生成统计报告等场景。
要运行批处理作业,用户需要将数据作为批量文件上传到 Flink 的分布式文件系统(如 HDFS 或本地文件系统),然后通过 Flink 作业的方式进行处理。在批处理作业中,用户可以指定数据的截止时间(截止时间之前的数据会被处理),以及作业的并发度等参数。
2. 流处理作业:
流处理作业将数据作为无界数据流进行处理,实时处理数据并生成实时结果。在流处理模式下,Flink 会实时地接收数据,并将其分配给不同的 Task 以进行处理。流处理作业通常用于实时数据处理、实时分析和实时监控等场景。
要运行流处理作业,用户需要将数据源(如 Kafka、Flume 等)与 Flink 集群配置好,然后通过 Flink 作业的方式进行处理。在流处理作业中,用户可以指定数据处理的时间窗口、触发器等参数,以实现实时数据处理的需求。
在 Flink 中,批处理作业和流处理作业之间的切换可以通过修改作业的配置文件实现。例如,修改 batch.file.path
和 streaming.file.path
参数,以指定批处理作业和流处理作业的输入数据路径。此外,用户还可以通过 Flink Web UI 查看和管理作业的状态,以确保作业的正确运行。
Flink 相对于 Spark 的优势主要体现在以下几个方面:
综上所述,Flink 相对于 Spark 在低延迟、高吞吐量、流式数据应用场景支持、处理乱序数据和保证状态一致性等方面具有优势,因此被越来越多的公司和开发者所采用。
Flink 是一个分布式流处理框架,它实现了容错机制以确保在节点故障时,数据不会丢失并且可以进行故障恢复。Flink 的容错机制主要依靠两个强大的机制:Checkpoint 和 State。
在 Flink 中,Checkpoint 和 State 是相互依存的。Checkpoint 用于备份 State,并确保在节点故障时,可以恢复程序的状态。而 State 则用于存储计算过程中的中间状态,并支持 Exactly-Once 语义。Flink 通过这两个机制的结合,实现了强大的容错和故障恢复能力,使得 Flink 在分布式流处理中具有高度的可靠性和可用性。
Flink 在网络数据交换方面做到了高效,主要归功于以下几个方面:
综上所述,Flink 在网络数据交换方面实现了高效,主要通过分布式数据交换、TaskManager 负责数据交互、批次封装、网络拥塞控制和自适应网络拓扑等机制来实现。这些机制使得 Flink 在处理大规模数据流时具有高吞吐量、高并发度和高可靠性。
当 Flink 程序面对数据高峰期时,一种常用的方法是使用大容量的 Kafka 作为数据源,将数据先放到消息队列中,然后再使用 Flink 进行消费。这种方法可以有效地削峰平谷,减缓数据流量对 Flink 程序的影响,从而提高程序的稳定性和可靠性。
不过,使用 Kafka 作为数据源会影响一点实时性。因为 Kafka 是一个异步的消息队列,数据在队列中需要等待消费者消费,所以会存在一定的延迟。为了解决这个问题,可以采用以下方法:
综上所述,使用 Kafka 作为数据源可以有效地处理数据高峰期,但需要注意 Kafka 和 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之前的记录,因为此时这些记录(及其后续记录)将已经通过整个数据流拓扑,也即是已经被处理结束。
这个问题是一个非常宏观的问题,因为两个框架的不同点非常之多。但是在面试时有非常重要的一点一定要回答出来:Flink 是标准的实时处理引擎,基于事件驱动。而 Spark Streaming 是微批(Micro-Batch)的模型。
下面我们就分几个方面介绍两个框架的主要区别:
Flink 支持三种时间语义:Event Time、Ingestion Time 和 Processing Time。
1. Event Time(事件时间)
Event Time 是事件创建的时间,它通常由事件中的时间戳描述。通常由事件生成器或者传感器生成。在 Flink 中,事件时间可以通过 water-mark 或者定时器来处理。例如,在采集日志数据时,每一条日志都会记录自己的生成时间,Flink 通过时间戳分配器访问事件时间戳。Event Time 是事件产生的时间,与数据处理的时间无关,因此它可以反映事件产生的实时性,但是对于数据处理的延迟和异步性无法体现。
2. Ingestion Time(注入时间)
Ingestion Time 是数据进入 Flink 的时间。它是指数据被 Flink 算子处理的时间,与事件创建的时间无关。Ingestion Time 能够反映数据处理的延迟和异步性,但是无法反映事件产生的实时性。
3. Processing Time(处理时间)
Processing Time 是每一个执行基于时间操作的算子的本地系统时间,与机器相关。它是指算子处理数据的时间,与事件创建的时间和数据进入 Flink 的时间无关。Processing Time 是默认的时间属性,除非明确指定时间语义为 Event Time 或 Ingestion Time。
在实际应用中,选择合适的时间语义可以影响 Flink 处理的数据流的正确性和效率。
例如,如果需要处理实时数据流,那么选择 Event Time 更为合适;
如果需要处理延迟数据流,那么选择 Ingestion Time 更为合适;
如果需要处理离线数据集,那么选择 Processing Time 更为合适。
同时,Flink 也提供了 WaterMark 机制来处理延迟数据和异步数据,以保证数据处理的正确性和可靠性。
Flink 中的 Watermark 机制是一种衡量 Event Time 进展的机制,可以用于处理乱序事件。在数据流处理过程中,由于网络延迟、背压等多种因素的影响,数据可能会乱序到达。为了正确处理这些乱序事件,Flink 引入了 Watermark 机制,结合窗口 (Window) 来实现。
Watermark 是一个时间戳,用于表示事件时间小于等于该时间戳的数据都已经到达。在 Flink 中,每个 Operator 都会维护一个当前的 Watermark,当一个事件到达时,如果它的时间戳小于等于当前 Watermark,那么该事件就会被认为是到达了,会被放入窗口中进行处理。窗口的执行是由 Watermark 触发的,当 Watermark 达到窗口的结束时间时,窗口就会触发并执行其中的计算逻辑。
为了实现窗口的正确处理,Flink 还引入了事件时间 (Event Time) 概念,每个事件都会携带一个时间戳,表示该事件产生的时间。在数据流处理过程中,Flink 会根据事件时间戳的顺序来处理事件,这样可以保证事件的正确顺序。但是,由于网络延迟、背压等原因,事件可能会乱序到达,这就需要使用 Watermark 机制来处理这些乱序事件。
总结起来,Flink 中的 Watermark 机制是用于处理乱序事件的一种机制,它可以设定延迟触发,用于表示事件时间小于等于该时间戳的数据都已经到达。通过结合窗口机制,Watermark 机制可以实现对乱序事件的正确处理,保证数据流的正确性和完整性。
产生的数据流的速度如果过快,而下游的算子消费不过来的话,会产生背压。背压的监控可以使用Flink Web UI来可视化监控Metrics,一旦报警就能知道。一般情况下可能由于sink这个操作符没有优化好,做一下优化就可以了。
设置watermark的最大延迟时间这个参数,如果设置的过大,可能会造成内存的压力。可以设置最大延迟时间小一些,然后把迟到的元素发送到测输出流中,晚一点更新结果。
还有就是滑动窗口的长度如果过大,而滑动距离很短的话,Flink的性能也会下降的厉害。可以通过分片的方法,将每个元素只存入一个“重叠窗口”,这样就可以减少窗口处理中状态的写入。
Flink在运行时主要由operators和streams两大构件组成。每个operator会消费中间状态的流,并在流上进行转换,然后生成新的流。对于Flink的网络机制一种形象的类比是,Flink使用了高效有界的分布式阻塞队列,就像Java通过的阻塞队列(BlockingQueue)一样。使用BlockingQueue的话,一个较慢的接受者会降低发送者的发送速率,因为一旦队列满了(有界队列)发送者会被阻塞。
在Flink中,这些分布式阻塞队列就是这些逻辑流,而队列容量通过缓冲池(LocalBufferPool)实现的。每个被生产和消费的流都会被分配一个缓冲池。缓冲池管理者一组缓冲(Buffer),缓冲在被消费后可以被回收循环利用。
Flink 的反压(Backpressure)是指当一个 Operator 的输出速度比其下游 Operator 的输入速度慢时,下游 Operator 可能会积累一定数量的数据,导致处理速度变慢,甚至堵塞。为了解决这个问题,Flink 引入了反压机制,以便及时发现并解决数据处理速度不匹配的问题。
Flink 在处理反压问题时,并没有使用复杂的机制,而是采用了一种简单而高效的方法。Flink 在数据传输过程中使用了分布式阻塞队列,从而有效地解决了反压问题。
在 Flink 中,当一个算子的输出速度比下游算子快时,Flink 会使用分布式阻塞队列来缓存输出数据。这样可以避免上游算子过快地生成数据,导致下游算子无法及时处理,从而形成反压。当下游算子需要数据时,它会从队列中取出数据并进行处理。当队列中的数据达到一定阈值时,上游算子会收到通知,从而减缓数据生成速度。这样一来,Flink 就通过分布式阻塞队列实现了反压的缓解。
另外,Flink 通过每个 TaskManager 和 JobManager 之间的通信来实现反压的缓解。当下游处理任务时间太长时,Flink 会检测到这种情况,并认为这是一个反压信号。此时,Flink 会将这个反压信号传递给上游任务的管理器。
具体来说,Flink 的反压策略主要分为以下几个步骤:
可以根据下游任务的处理速度来动态调整上游任务的数据生成速度,以缓解数据积压问题。这种策略在实际应用中可以提高 Flink 任务的处理效率和稳定性。
Flink 的反压监控和发现主要通过以下方式进行:
总之,Flink 通过 Web UI、命令行工具、第三方监控工具以及自定义监控与报警等多种方式,帮助用户实时监控和发现反压问题,从而确保数据处理的高效和稳定。
Flink 中的窗口操作是一种基于时间窗口的数据处理方式,可以用于统计分析、监控、实时计算等应用场景。然而,当数据量过大或者数据发送速度不均匀时,可能会导致窗口中堆积的数据量相差过多,即出现了数据倾斜的情况。
数据倾斜会对 Flink 的性能产生负面影响,因为窗口计算需要对所有数据进行聚合操作,而数据倾斜会导致部分窗口的数据量过大,从而增加计算时间和资源消耗。为了解决数据倾斜问题,可以采用以下几种方法:
综上所述,解决 Flink 中的窗口数据倾斜问题需要根据具体情况进行分析和处理。可以采用预聚合、重新设计窗口聚合的 key、调整窗口参数或者使用 Flink 的 Ttl 操作等方法来避免数据倾斜,从而提高 Flink 的性能和可靠性。
当使用 KeyBy 算子时,如果某个 Key 的数据量过大,会导致数据倾斜,影响计算效率。为了解决这个问题,可以考虑以下方法:
Flink 在使用聚合函数之后出现数据热点的问题,主要是由于某些聚合函数的计算量比较大,导致数据处理速度较慢,从而产生了数据积压和延迟。这种情况下,可以通过以下几种方法来解决数据热点问题:
综上所述,解决 Flink 中的数据热点问题需要根据具体情况进行分析和处理。可以采用增加计算资源、调整聚合函数参数、使用批量处理、采用数据重复消除策略或者调整数据源参数等方法来解决数据热点问题,从而提高 Flink 的性能和可靠性。
如果 Flink 任务延迟高,需要从以下几个方面入手进行优化:
综上所述,要解决 Flink 任务延迟高的问题,需要从资源调优、算子调优、数据优化、任务调度优化和错误处理等方面入手,以提高 Flink 任务的性能和可靠性。
如果下级存储支持事务:
Flink可以通过实现两阶段提交和状态保存来实现端到端的一致性语义。
分为以下几个步骤:
下级存储不支持事务:
端到端的exactly-once对sink的要求比较高,具体的实现主要有幂等写入和事务性写入两种方式。幂等写入的场景依赖于业务逻辑,更常见的是用事务性写入。而事务性写入又有预写日志(WAL)和两阶段提交(2PC)两种方式。
如果外部系统不支持事务,那么可以使用预写日志的方式,把结果数据当成状态保存,然后在收到checkpoint完成的通知时,一次性写入sink系统。
在 Flink 中,状态是指在实时计算过程中,用于存储和处理数据的一种机制。状态可以分为两种基本类型:KeyedState 和 OperatorState。
KeyedState 和 OperatorState 都是 Flink 中的状态类型,它们在实时计算中起到了重要的作用。KeyedState 通常用于处理基于键的数据,例如对某个键进行计数、聚合等操作;而 OperatorState 通常用于处理非基于键的数据,例如对数据进行窗口操作、排序等操作。
在学习 Flink 中的状态时,需要了解状态的基本概念、分类、使用方式以及状态管理的相关概念。同时,需要掌握如何在程序中使用 KeyedState 和 OperatorState,以便在实时计算中处理数据。
Flink 的状态储存是指在 Flink 程序运行过程中,用于存储和管理算子状态的数据结构和存储系统。Flink 提供了多种状态后端,以适应不同的应用场景和需求。这里将详细叙述 Flink 的状态储存,包括 1.13 版本之前的状态后端和 1.13 版本之后的状态后端。
1.13 版本之前:
1.13 版本之后:
Flink 的 CEP(Complex Event Processing,复杂事件处理)机制主要用于处理实时数据流中的复杂事件,以便实时地计算和响应这些事件。与传统的批处理方式不同,CEP 机制可以处理实时数据流中的事件,并根据事件的复杂逻辑进行实时计算和响应。
Flink CEP 是在 Flink 中实现的复杂事件处理(CEP)库。CEP 允许在无休止的事件流中检测事件模式,让我们有机会掌握数据中重要的部分。一个或多个由简单事件构成的事件流通过一定的规则匹配,然后输出用户想得到的数据——满足规则的复杂事件。
Flink 的 CEP 机制主要依赖于两个核心组件:Flink 的流处理框架和 CEP 库。Flink 的流处理框架提供了低延迟、高吞吐量的数据流处理能力,可以处理海量的实时数据。而 CEP 库则提供了处理复杂事件的逻辑,可以实现事件的过滤、聚合、路由等功能。通过这两个组件的结合,Flink 能够实现对实时数据流中复杂事件的实时处理和响应。
Flink 的 CEP 机制具有以下特点:
Flink 的 CEP 机制在实际应用中可以广泛应用于金融、物联网、物流等行业,例如:实时计算股票交易数据、实时监测传感器数据、实时路由物流信息等。了解 Flink 的 CEP 机制有助于更好地应对实时数据流中的复杂事件处理需求。
在 Flink CEP 编程中,当状态没有到达的时候,数据通常会被保存在内存中。这是因为在流式处理中,CEP 需要支持 EventTime,也就需要支持数据的迟到现象,这就需要使用 Watermark 机制来处理。对于未匹配成功的事件序列的处理,和迟到数据是类似的。在 Flink CEP 的处理逻辑中,状态没有满足的和迟到的数据,都会存储在一个 Map 数据结构中。
这种内存存储数据的方式在处理延迟数据时是必要的,但也确实可能会对内存造成一定的损伤。为了降低内存占用,可以采取以下策略:
在 Flink CEP 编程中,当状态没有到达的时候,数据会被保存在内存中。为了降低内存占用,可以采取合理设置状态时间间隔、使用外部状态存储、优化 CEP 算法以及合理设置 Flink 并行度等策略。
Flink 的并行度是指在执行算子时,可以同时处理的数据流分片的数量。通过设置并行度,可以充分利用集群中的多个 TaskSlots(任务槽)来执行多个数据流分片,从而提高计算性能。并行度这个概念很好理解,例如 Kafka Source,它的并行度默认就是它的分区数量。
Flink 的并行度设置可以通过算子内部的参数或者外部的配置进行调整。
下面是一些常见的设置方法:
map_function.parallelism
参数来设置并行度。ParallelismAware
接口来设置并行度。在实现该接口的过程中,需要实现 get_parallelism
方法,该方法返回算子的并行度。flink-config.yaml
)中,可以设置整个任务的并行度。例如,可以使用 parallelism.task.num
参数来设置 TaskSlots 的数量,从而影响算子的并行度。合理地设置并行度可以充分发挥 Flink 的并行计算优势,提高数据处理的性能。
Flink 提供了多种分区策略以满足不同数据处理的需求。以下是详细的叙述:
Flink 提供了多种内置的分区器以满足常见的数据处理需求,同时也支持用户自定义分区器以满足特定需求。
TaskSlot 是 Flink 中用于控制 TaskManager 接收任务的数量的一个概念。它是一个抽象的概念,表示一个 TaskManager 能够处理的任务数量。在 Flink 中,TaskManager 是实际执行程序的工作节点,为了起到资源隔离和并行执行的作用,TaskManager 是一个 JVM 进程。通过 TaskSlot 的概念,可以控制 TaskManager 接收的任务数量,从而更好地利用集群资源。
当有一个 source 需要指定三个并行度时,它就需要使用三个 TaskSlot。这是因为 TaskSlot 的数量决定了 TaskManager 能够处理的任务数量。如果 source 需要三个并行度,那么 TaskManager 就需要三个 TaskSlot 来处理这三个并行度的任务。
还有一个需要主要的优化概念是,当算子的并行度相同,并且没有发生并行度改变、或者没有 shuffle 时,这些算子会合并在一起。这样做的目的是为了减少资源的消耗,提高计算效率。
Solt 是 TaskManager 中的概念,表示 TaskManager 的一个槽(Slot)。并行度是程序中的概念,表示程序并行执行的程度。在 Flink 中,Solt 和并行度有着密切的关系。
具体来说,Solt 是 TaskManager 的资源分配单位,它决定了 TaskManager 能够支持的并行度。一个 TaskManager 有多个 Solt,每个 Solt 可以分配给一个 Task,用于执行程序。因此,TaskManager 的并行度就等于其 Solt 的数量。
程序制定的并行度使用的是槽(Solt),也就是说,程序是通过分配 Solt 来控制并行度的。当程序需要更高的并行度时,它可以向 TaskManager 申请更多的 Solt,以便在同一时间内执行更多的 Task。
因此,Solt 和并行度之间的关系可以总结为:Solt 是 TaskManager 中的概念,它决定了 TaskManager 能够支持的并行度;并行度是程序中的概念,它是通过分配 Solt 来控制的。TaskManager 是提供方,提供 Solt 资源给程序使用;程序是使用方,通过分配 Solt 来控制并行度。
Flink 的资源调度是基于 TaskManager 和 Task slot 的概念进行的。TaskManager 是 Flink 中最小的调度单元,负责管理和调度任务。而 Task slot 则是 TaskManager 中最细粒度的资源,代表了一个固定大小的资源子集。每个 TaskManager 会将其所占有的资源平分给它的 slot。通过调整 task slot 的数量,用户可以定义 task 之间是如何相互隔离的。
每个 TaskManager 有一个 slot,也就意味着每个 task 运行在独立的 JVM 中。这样做的好处是,任务之间的隔离更加明确,一个任务出现问题不会影响到其他任务。同时,独立的 JVM 可以提供更好的资源管理和垃圾回收。
而当 TaskManager 拥有多个 slot 时,多个 task 可以运行在同一个 JVM 中。这样做的好处是,可以共享 TCP 连接(基于多路复用)和心跳消息,从而减少数据的网络传输。此外,同一个 JVM 进程中的 task 还可以共享一些数据结构,从而减少每个 task 的消耗。
在 Flink 中,每个 slot 可以接受单个 task,也可以接受多个连续 task 组成的 pipeline。例如,FlatMap 函数占用一个 taskslot,而 key Agg 函数和 sink 函数共用一个 taskslot。这种灵活的资源调度方式可以根据不同的任务需求进行优化和配置,提高系统的资源利用率和性能。
总之,Flink 的资源调度是通过 TaskManager 和 Task slot 的概念来实现的,通过调整 task slot 的数量和分配方式,可以满足不同任务的需求,提高系统的资源利用率和性能。
如下图所示,FlatMap函数占用一个taskslot,而key Agg函数和sink函数共用一个taskslot:
Flink 中的重启策略用于在程序运行过程中发生故障时,如何重新启动算子以恢复程序的运行。重启策略可以在 flink-conf.yaml 中配置,也可以在应用代码中动态指定。
以下是 Flink 中常见的四种重启策略:
如果没有启用 checkpointing,则使用无重启(no restart)策略。如果启用了 checkpointing,但没有配置重启策略,则使用固定间隔(fixed-delay)策略。在固定间隔策略中,Flink 会等待一个固定的时间间隔后,重新启动失败的算子。这个时间间隔可以通过 flink-conf.yaml 中的 restart.delay 配置项来设置。
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
…
由于字数限制,此处省略
完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩获取
本文《尼恩 大数据 面试宝典》 是 《尼恩Java面试宝典》 姊妹篇。
这里特别说明一下:《尼恩Java面试宝典》41个专题 PDF 自首次发布以来, 已经收集了 好几千题,大量的大厂面试干货、正货 ,足足4800多页,帮助很多小伙伴进了大厂,拿了高薪。 所以,《尼恩Java面试宝典》面试题集合, 已经变成Java 学习和面试的必读书籍。
于是,尼恩架构团队趁热打铁,推出 《尼恩 大数据 面试宝典》,已经发布了三个专题:
《尼恩大数据面试宝典专题1:史上最全Hadoop面试题》
《尼恩大数据面试宝典专题2:绝密100个Spark面试题,熟背100遍,猛拿高薪》
《尼恩大数据面试宝典专题3:史上最全Hive面试题,不断迭代,持续升级》
《尼恩大数据面试宝典专题4:史上最全Flink面试题,不断迭代,持续升级》(本文)
完整的pdf,可以到文末公号【技术自由圈】领取。
并且,《尼恩 大数据 面试宝典》、 《尼恩Java面试宝典》 都会持续迭代、不断更新,以 吸纳最新的面试题
未来职业,如何突围: 成长为 三栖架构师, Java 架构+GO 架构 + 大数据 架构
尼恩即将为大家编写,《大数据 Flink学习圣经》 《大数据 HBASE 学习圣经》