写点什么

实时大数据 Flink 知识结构 (超全整理,附知识脑图)

用户头像
探测器
关注
发布于: 刚刚
实时大数据Flink知识结构(超全整理,附知识脑图)


实时大数据 Flink 知识结构图

· Flink 基本概念

o 概念

官方定义:Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. Flink has been designed to run in all common cluster environments perform computations at in-memory speed and at any scale.

翻译一下就是:Apache Flink 是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。Flink 被设计在所有常见的集群环境中运行,以内存执行速度和任意规模来执行计算。

o 流数据

o 在自然环境中,数据的产生原本就是流式的。但是当你分析数据时,可以围绕 有界流(bounded)或 无界流(unbounded)两种模型来组织处理数据,当然,选择不同的模型,程序的执行和处理方式也都会不同。

o 离线计算的代表 spark 和 flink 的对比:

o 在 spark 中,一切都是由批次组成的,离线数据是一个大批次,而实时数据是由一个一个无限的小批次组成的。

o 而在 flink 中,一切都是由流组成的,离线数据是有界限的流,实时数据是一个没有界限的流。

§ 有界流

§ 数据有时间的界限,比如我们长说某天的数据、某月的数据。

§ 批处理是有界数据流处理的范例。在这种模式下,你可以选择在计算结果输出之前输入整个数据集,这也就意味着你可以对整个数据集的数据进行排序、统计或汇总计算后再输出结果。

§ 无界流

§ 数据没有时间的界限,所处理的数据是持续不断的输入的。因此程序必须持续不断地对到达的数据进行处理。

o 数据处理流程

o 在 Flink 中,应用程序由用户自定义算子转换而来的流式 dataflows 所组成。这些流式 dataflows 形成了有向图,以一个或多个源(source)开始,并以一个或多个汇(sink)结束。

o Flink 应用程序可以消费来自消息队列或分布式日志这类流式数据源(例如 Apache Kafka 或 Kinesis)的实时数据,也可以从各种的数据源中消费有界的历史数据。同样,Flink 应用程序生成的结果流也可以发送到各种数据汇中。


o 并行处理

o Flink 程序本质上是分布式并行程序。在程序执行期间,一个流有一个或多个流分区(Stream Partition),每个算子有一个或多个算子子任务(Operator Subtask)。每个子任务彼此独立,并在不同的线程中运行,或在不同的计算机或容器中运行。

o 算子子任务数就是其对应算子的并行度。

o 状态

o Flink 中的算子可以是有状态的,它用于处理保存一个算子运算时产生的中间结果。这意味着如何处理一个事件可能取决于该事件之前所有事件数据的累积结果。

§ 累计运算

§ 实现容错

§ 通过状态快照和流重放两种方式的组合,Flink 能够提供可容错的,精确一次计算的语义。这些状态快照在执行时会获取并存储分布式 pipeline 中整体的状态,它会将数据源中消费数据的偏移量记录下来,并将整个 job graph 中算子获取到该数据(记录的偏移量对应的数据)时的状态记录并存储下来。当发生故障时,Flink 作业会恢复上次存储的状态,重置数据源从状态中记录的上次消费的偏移量开始重新进行消费处理。而且状态快照在执行时会异步获取状态并存储,并不会阻塞正在进行的数据处理逻辑。

· 时间与窗口

o 时间类型


§ 事件时间

§ 指的是数据本身携带的时间。这个时间是在事件产生时的时间。

§ 摄取时间

§ 指的是数据进入 Flink 的时间;

§ 处理时间

§ 指的是执行具体操作时的机器时间

o 窗口

o 流处理中,聚合操作是依赖窗口的,例如每 10 分钟聚合一次。

§ 有界限窗口

§ 流是没有界限的,在流数据中无法统计所有的元素。所以当需要对数据进行聚合处理时,可以对流数据按照时间或者计数切分,切分后的数据被就成了一个不可变的数据集,这时候再统计这份不可变的数据集就像处理一份批数据一样方便了。

· 滚动窗口

· 按照固定的记录数或者时间切分窗口,窗口之间不会重叠。

o 时间驱动

o 例如每 30 分钟聚合一次

o 计数驱动

o 例如每 1 万条记录聚合一次

· 滑动窗口

· 按照时间和计数窗口大小和滑动的步长切分窗口。窗口之间可能存在重叠,也可能没有交集。

o 时间驱动

o 计数驱动

· 会话窗口

· 超过指定的时间如果没有收到新的元素,窗口就结束。

§ 无界限窗口-Over 窗口

§ Over 窗口依赖的是整个数据流,没有时间或者记录的界限。它按照特定的字段将数据分组,每一个分组的流就是一个窗口,分组后可以统计该窗口内的数据,但是整个数据流并不会被聚合。例如可以在窗口内部执行 sum()、max()等操作,但是每条记录并不会被聚合,仍然保留了最明细的记录。

o 水位线(WaterMark)

§ 概念

§ Flink 所处理的数据可能会在流转过程中因为某些问题造成数据乱序达到(数据源分区、网络延迟、反压、failover)。WaterMark 是一个很好的机制,保证即使部分事件数据延迟到达,也不会影响窗口计算的正确性。

§ 使用方式

§ WATERMARK 定义在事件中具备时间属性的字段上(比如用户点击时间),并且使用偏移量参数来设置等待时间。

§ 1.偏移量,也就是等待时间,也是我们认为的最大乱序时间。

§ 2.某个最新到达的时间戳为 t 的元素将在最早到达的时间戳为 t 的元素之后最多 n 毫秒到达;

§ 3.发出的 watermark = 当前最大时间戳 - 最大乱序时间。

§ 例如以`WATERMARK FOR order_time AS order_time - INTERVAL '4' SECOND`的方式定义一个水印,其中等待偏移量设置为 4 秒,可以理解为:当 Flink 数据流中第一个`2021-09-12 08:00:16`的数据达到的 4 秒后,所有`2021-09-12 08:00:16`以前的数据都被认为已经到达了。

§ 也可以这样理解,当前如果最大的事件时间为`2021-09-12 08:00:20`,那么意味着`2021-09-12 08:00:16`之前的数据都被认为已经到达了,`2021-09-12 08:00:16`就可以认为是分界线,这个时间戳之前的数据可以被处理,这个时间戳之后的数据还需要等待,直到水位线上涨到它所在的记录。

· 状态与容错

o 有状态计算

§ 概念

§ 状态在 Flink 中叫作 State,用来保存中间计算结果或者缓存数据。

§ 根据是否需要保存中间结果,分为无状态计算和有状态计算。

§ 对于流计算而言,事件持续不断地产生,如果每次计算都是相互独立的,不依赖于上下游的事件,则是无状态计算。如果计算需要依赖于之前或者后续的事件,则是有状态计算。

§ 应用案例

· sum 求和

· 去重计算

· 模式检测

o State 管理

o (1)状态数据的存储和访问;

o (2)状态数据的备份和恢复;

o (3)状态数据的划分和动态扩容;

o (4)状态数据的清理。

§ 状态存储(StateBackend)

§ 状态数据需要保存到可靠存储中,这样才能有效实现容错。

§ State 的存储在 Flink 中叫作 StateBackend。

· 持久化到外部存储

· 在计算过程中可被访问

· Backends 方式

o 1)纯内存:MemoryStateBackend,适用于验证、测试,不推荐生产环境。

o 2)内存+文件:FsStateBackend,适用于长周期大规模的数据。

o 3)RocksDB:RocksDBStateBackend,适用于长周期大规模的数据。

§ 状态重分布

§ 在实际的生产环境中,作业预先设置的并行度很多时候并不合理,太多则浪费资源,太少则资源不足,可能导致数据积压延迟变大或者处理时间太长,所以在运维过程中,需要根据作业的运行监控数据调整其并行度。

§ State 位于算子中,改变了并行度,则意味着算子个数改变,State 将重新分配给算子。

§ 状态的清理

§ 状态过大影响性能,State 持有大量数据也许并不必要——清理状态数据。

§ 注意:

§ Flink SQL 是数据分析的高层抽象,在 SQL 的世界里并无 State 的概念,而在流 Join、聚合类的场景中,使用了 State,如果 State 不定时清理,则可能会导致 State 过多,内存溢出,为了稳妥起见,最好为每个 Flink SQL 作业提供 State 清理的策略。如果定时清理 State,则存在可能因为 State 被清理而导致计算结果不完全准确的风险,Flink 的 Table API 和 SQL 接口中提供了参数设置选项(withIdleStateRetentionTime),能够让使用者在精确和资源消耗做折中。

· ● 过期时间:超过多长时间未访问,视为 State 过期,类似于缓存

· ● 过期时间更新策略:创建和写时更新、读取和写时更新

· ● State 的可见性: 未清理可用,超期则不可用

o 容错

o Flink 使用流重放和检查点的组合来实现容错。检查点标记每个输入流中的特定点,以及每个算子的相应状态。流数据流可以从检查点恢复,同时通过恢复操作符的状态并从检查点重放记录来保持一致性(精确一次处理语义)。

§ Exactly-Once

§ 即数据不丢失、不重复。

§ Flink 在运行过程中因为资源、网络等各种问题发生错误是必然的,但是怎么保证发生错误后,让中断的程序跑起来,并且保证中断过程中的数据不丢失不重复呢?

§ 这就引出了检查点和保存点的概念。

§ 检查点(CheckPoint)

§ 检查点是 Flink 实现容错的核心保障,它通过周期性的对算子状态快照的持久化存储,在程序发生错误时,有选择的把程序恢复到某一个(比如最近的)检查点,从该检查点可以开始重新执行计算,进而实现数据的容错。

· 检查点分界线(Checkpoint Barrier)

· 可以理解为,数据流通过 Barrier 被切分成一个一个的数据段。每个数据段就是 checkpoint 持久化存储的实际内容。

· Barrier 对齐

· Barrier 对齐,是当一个算子有多个上游输入的时候,为了达到引擎内严格一次、端到端严格一次两种保证语义而执行的一种操作。

§ 保存点(SavePoint)

§ Savepoint 是依据 Flink checkpointing 机制所创建的流作业执行状态的一致镜像。

§ 它由用户创建,拥有和删除。主要用于手动备份和恢复。

§ 检查点和保存点的差异

§ 从概念上讲, Flink 的 Savepoint 与 Checkpoint 的不同之处类似于传统数据库中的备份与恢复日志之间的差异。 Checkpoint 的主要目的是为意外失败的作业提供恢复机制。 Checkpoint 的生命周期由 Flink 管理,即 Flink 创建,管理和删除 Checkpoint - 无需用户交互。 作为一种恢复和定期触发的方法,Checkpoint 实现有两个设计目标:i)轻量级创建和 ii)尽可能快地恢复。 可能会利用某些特定的属性来达到这个,例如, 工作代码在执行尝试之间不会改变。 在用户终止作业后,通常会删除 Checkpoint(除非明确配置为保留的 Checkpoint)。

§ 与此相反、Savepoint 由用户创建,拥有和删除。 他们的用例是计划的,手动备份和恢复。 例如,升级 Flink 版本,调整用户逻辑,改变并行度,以及进行红蓝部署等。 当然,Savepoint 必须在作业停止后继续存在。 从概念上讲,Savepoint 的生成,恢复成本可能更高一些,Savepoint 更多地关注可移植性和对前面提到的作业更改的支持。

§ 除去这些概念上的差异,Checkpoint 和 Savepoint 的当前实现基本上使用相同的代码并生成相同的格式。

§ 重启策略

· 自动检查点恢复

o 固定间隔,定期恢复(Fixed delay)

o 失败率(Failure rate)

o 无重启,直接失败(No restart)

· 手动检查点恢复

· Flink 架构

· Flink 是一个分布式系统,需要有效分配和管理计算资源才能执行流应用程序。TaskManager

o Client

o Client 不是运行时和程序执行的一部分,而是用于准备数据流并将其发送给 JobManager。

o JobManager

o JobManager 具有许多与协调 Flink 应用程序的分布式执行有关的职责:它决定何时调度下一个 task(或一组 task)、对完成的 task 或执行失败做出反应、协调 checkpoint、并且协调从失败中恢复等等。

§ ResourceManager

§ ResourceManager 负责 Flink 集群中的资源提供、回收、分配 - 它管理 task slots。

§ Dispatcher

§ Dispatcher 提供了一个 REST 接口,用来提交 Flink 应用程序执行,并为每个提交的作业启动一个新的 JobMaster。它还运行 Flink WebUI 用来提供作业执行信息。

§ JobMaster

§ JobMaster 负责管理单个 JobGraph 的执行。Flink 集群中可以同时运行多个作业,每个作业都有自己的 JobMaster。

o TaskManager

o TaskManager(也称为 worker)执行作业流的 task,并且缓存和交换数据流。

§ task slot

§ 每个 worker(TaskManager)都是一个 JVM 进程,可以在单独的线程中执行一个或多个 subtask。为了控制一个 TaskManager 中接受多少个 task,就有了所谓的 task slots(至少一个)。

§ 在 TaskManager 中资源调度的最小单位是 task slot。TaskManager 中 task slot 的数量表示并发处理 task 的数量。

§ 同一个 TM 中具有多个 slot 意味着更多 subtask 共享同一 JVM。同一 JVM 中的 task 共享 TCP 连接(通过多路复用)和心跳信息。它们还可以共享数据集和数据结构,从而减少了每个 task 的开销。

§ Solt 的数量通常与每个 TaskManager 节点的可用 CPU 内核数成比例,一般情况下 Slot 的数量就是每个节点的 CPU 的核数。

§ 算子链

§ Flink 将算子的 subtasks 链接成 tasks。每个 task 由一个线程执行。

o 并行度

o 一个任务的并行度设置可以从 4 个层面指定。1.Operator Level(算子层面);

o 2.Execution Environment Level(执行环境层面)

o 3.Client Level(客户端层面);

o 4.System Level(系统层面)。

o 这些并行度的优先级为 Operator Level>Execution Environment Level>Client Level>SystemLevel。

§ Operator Level(算子层面)

§ Operator、Source 和 Sink 目的地的并行度可以通过调用 setParallelism()方法来指定。

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

§ 任务的默认并行度可以通过调用 setParallelism()方法指定,当设置了执行环境层面的并行度时,所有的 Operator、Source 和 Sink 都将默认使用该并行度来执行。

§ Client Level(客户端层面)

§ 并行度还可以在客户端提交 Job 到 Flink 时设定。对于 CLI 客户端,可以通过-p 参数指定并行度。

§ System Level(系统层面)

§ 在系统级可以通过设置 flink-conf.yaml 文件中的 parallelism.default 属性来指定所有执行环境的默认并行度。

· FlinkSQL

o why FlinkSQL

§ 适合数据分析,SQL 在离线体系中已经十分成熟

§ 技术门槛相对较低,不用学习各种底层的 API 也可上手

§ 借助 Calcite 的 SQL 优化器,更易于优化

o Dynamic Table(动态表)

o 动态表是随时间不断变化的流数据的连续查询,类似在数据流上面建了一个视图,它可以让你像查询静态批处理表一样查询流数据。

o 持续查询

o 在动态表上进行查询,被称为持续查询(Continuous Query),因为底层的计算是持续不断的。一个持续查询的结果也是一个动态表,它会根据新流入的数据不断更新结果。

§ 状态大小

§ 连续查询在无界流上计算,通常应该运行数周或数月。因此,连续查询处理的数据总量可能非常大。Flink 提供配置方法,清除空闲状态的数据,进而可以控制状态的大小。

§ 计算中更新

§ 有些查询需要重新计算和更新大量已输出的结果行,即使只添加或更新一条输入记录。显然,这样的查询不适合作为连续查询执行。


o 关联查询(Join)

o 附上官方介绍地址:https://ci.apache.org/projects/flink/flink-docs-release-1.13/zh/docs/dev/table/sql/queries/joins/

§ 常规 Join(Regular Join)

§ 原理与离线环境的 join 相同,这种查询方式会将 join 两端的所有数据都作为待关联的记录,并且是任何一个表有新数据加入,都会和另外表中所有对应数据进行连接。随着状态数据的变大,Flink 任务压力也必然会变大。这种 join 适合小状态或者设置了状态生命周期的查询。

§ 时间窗口 Join(Interval Join):限制特定时间的数据集做关联

§ 只截取特定时间的数据做关联,比如近 1 天,近 1 小时的数据。这就保证了关联到的数据不是无限增长的。

§ 语法参考:

SELECT *FROM Orders o, Shipments sWHERE o.id = s.order_idAND o.order_time BETWEEN s.ship_time - INTERVAL '4' HOUR AND s.ship_time

§ 时态表 Join(Temporal Table Join):关联维度表

§ 其实就是关联维度表,并且可以关联的维度表特定版本。Flink 使用 FOR SYSTEM_TIME AS OF 的 SQL 语法作为关联维度表的特定语法。表示可以关联特定的时间(也可以是最新的)维表全部的数据。

§ 语法参考:

SELECT [column_list]FROM table1 [AS ][LEFT] JOIN table2 FOR SYSTEM_TIME AS OF table1.{ proctime | rowtime } [AS ]ON table1.column-name1 = table2.column-name1

· 流批一体

o 为什么提出流批一体

§ 开发隔离:流批表 schema 不同,计算逻辑不同

§ 重复资源:重复计算,重复存储

§ 流批数据口径不一致

§ 维护不同:不同的平台,不同的计算引擎,两边都需要维护

o 什么是流批一体

§ 存储一体:流批数据共用同一套存储体系,读写保持一致

§ 计算一体:流批任务共用同一套处理逻辑 &代码,目前仍处于设想阶段

§ 产品一体:同一平台管理流和批数据


发布于: 刚刚阅读数: 2
用户头像

探测器

关注

还未添加个人签名 2021.08.24 加入

还未添加个人简介

评论

发布
暂无评论
实时大数据Flink知识结构(超全整理,附知识脑图)