Flink
第一章 概述
1.1 流处理技术的演变
在 开 源世 界 里 ,Apache Storm 项 目 是流 处 理 的 先 锋 。Storm 最 早 由 Nathan Marz
和 创 业 公 司 BackType 的 一 个 团 队 开 发 , 后 来 才 被 Apache 基 金 会 接 纳 。Storm 提 供
了 低 延 迟 的 流 处 理 , 但 是 它 为 实 时 性 付 出 了 一 些 代 价 :很 难 实 现 高 吞 吐 , 并 且 其 正
确 性 没能 达 到 通 常 所需 的 水 平 ,换 句 话说 ,它 并 不 能 保 证 exactly-once,即 便 是它 能
够 保 证的 正 确 性 级 别, 其 开 销 也 相当 大 。
在 低 延 迟 和 高 吞 吐 的 流 处 理 系 统 中 维 持 良 好 的 容 错 性 是 非 常 困 难 的 , 但 是 为 了
得 到 有 保 障 的 准 确 状 态 , 人 们 想 到 了 一 种 替 代 方 法 : 将 连 续 时 间 中 的 流 数 据 分 割 成
一 系 列 微 小 的 批 量 作 业 。 如 果 分 割 得 足 够 小 ( 即 所 谓 的 微 批 处 理 作 业 ) , 计 算 就 几
乎 可 以 实 现 真 正 的 流 处 理 。 因 为 存 在 延 迟 , 所 以 不 可 能 做 到 完 全 实 时 , 但 是 每 个 简
单 的 应 用 程 序 都 可 以 实 现 仅 有 几 秒 甚 至 几 亚 秒 的 延 迟 。 这 就 是 在 Spark 批 处 理 引 擎
上 运 行的 Spark Streaming 所 使 用的 方 法 。
更 重 要 的 是 , 使 用 微 批 处 理 方 法 , 可 以 实 现 exactly-once 语 义 , 从 而 保 障 状 态
的 一 致 性 。 如 果 一 个 微 批 处 理 失 败 了 , 它 可 以 重 新 运 行 , 这 比 连 续 的 流 处 理 方 法 更
容 易 。Storm Trident 是 对 Storm 的 延 伸 , 它 的 底 层 流 处 理 引 擎 就 是 基 于 微 批 处 理
方 法 来 进 行 计 算 的 , 从 而 实 现 了 exactly-once 语 义 , 但 是 在 延 迟 性 方 面 付 出 了 很 大
的 代 价 。
对 于 Storm Trident 以 及 Spark Streaming 等 微 批处 理 策 略 ,只 能 根据 批 量 作 业 时
间 的 倍 数 进 行 分 割 , 无 法 根 据 实 际 情 况 分 割 事 件 数 据 , 并 且 , 对 于 一 些 对 延 迟 比 较
敏 感 的 作 业 , 往 往 需 要 开 发 者 在 写 业 务 代 码 时 花 费 大 量 精 力 来 提 升 性 能 。 这 些 灵 活
性 和 表现 力 方 面 的 缺陷 , 使 得 这 些微 批 处 理 策 略开 发 速 度 变 慢, 运 维 成 本 变高 。
于 是,Flink 出 现 了,这 一 技术 框 架 可 以 避免 上 述 弊 端,并 且 拥有 所 需 的 诸 多功
能 , 还能 按 照 连 续 事件 高 效 地 处 理数 据 ,Flink 的 部 分特 性 如 下 图 所示 :
图 Flink 的部分特性
1.2 初识 Flink
Flink 起 源 于 Stratosphere 项 目,Stratosphere 是 在 2010~2014 年 由 3 所 地 处柏 林
的 大 学 和 欧 洲 的 一 些 其 他 的 大 学 共 同 进 行 的 研 究 项 目 ,2014 年 4 月 Stratosphere 的
代 码 被 复 制 并 捐 赠 给 了 Apache 软 件 基 金 会 , 参 加 这 个 孵 化 项 目 的 初 始 成 员 是
Stratosphere 系 统 的 核 心 开 发 人 员 ,2014 年 12 月 ,Flink 一 跃 成 为 Apache 软 件 基 金
会 的 顶级 项 目 。
在 德 语中 ,Flink 一 词 表示 快 速 和 灵 巧 ,项 目 采用 一 只 松 鼠 的彩 色 图 案 作 为 logo,
这 不 仅是 因 为 松 鼠 具有 快 速 和 灵 巧的 特 点 ,还 因 为柏 林 的 松 鼠 有一 种 迷 人 的 红棕 色 ,
而 Flink 的 松 鼠 logo 拥 有 可 爱 的 尾 巴 , 尾 巴 的 颜 色 与 Apache 软 件 基 金 会 的 logo 颜
色 相 呼应 , 也 就 是 说, 这 是 一 只 Apache 风 格 的松 鼠 。
图 Flink Logo
Flink 主 页 在其 顶 部 展 示 了该 项 目 的 理 念:“Apache Flink 是 为 分 布 式 、高 性 能 、
随 时 可 用 以 及 准 确 的 流 处 理 应 用 程 序 打 造 的 开 源 流 处 理 框 架 ” 。
Apache Flink 是 一 个 框 架 和 分 布 式 处 理 引 擎 , 用 于 对 无 界 和 有 界 数 据 流 进 行 有
状 态 计算 。Flink 被 设 计在 所 有 常 见 的集 群 环 境 中 运行 ,以 内 存执 行 速 度 和 任意 规 模
来 执 行计 算 。
1.3 批处理与流处理
批 处 理 的 特 点 是 有 界 、 持 久 、 大 量 , 批 处 理 非 常 适 合 需 要 访 问 全 套 记 录 才 能 完
成 的 计 算 工 作 , 一 般 用 于 离 线 统 计 。 流 处 理 的 特 点 是 无 界 、 实 时 , 流 处 理 方 式 无 需
针 对 整 个 数 据 集 执 行 操 作 , 而 是 对 通 过 系 统 传 输 的 每 个 数 据 项 执 行 操 作 , 一 般 用 于
实 时 统计 。
在 Spark 生 态 体 系 中 , 对 于 批 处 理 和 流 处 理 采 用 了 不 同 的 技 术 框 架 , 批 处 理 由
SparkSQL 实 现 , 流 处 理 由 Spark Streaming 实 现 , 这 也 是 大 部 分 框 架 采 用 的 策 略 ,
使 用 独立 的 处 理 器 实现 批 处 理 和 流处 理 , 而 Flink 可 以 同时 实 现 批 处 理和 流 处 理 。
Flink 是如何同时实现批处理与流处理的呢?答案是,Flink 将批处理(即处理有限的静
态数据)视作一种特殊的流处理。
Flink 的核心计算架构是下图中的 Flink Runtime 执行引擎,它是一个分布式系统,能够
接受数据流程序并在一台或多台机器上以容错方式执行。
Flink Runtime 执行引擎可以作为 YARN(Yet Another Resource Negotiator)的应用程序
在集群上运行,也可以在 Mesos 集群上运行,还可以在单机上运行(这对于调试 Flink 应用
程序来说非常有用)。
图 Flink 计算架构
上 图 为 Flink 技 术 栈的 核 心 组 成 部分 ,值 得 一提 的 是 ,Flink 分 别 提 供 了 面 向 流
式 处 理 的 接 口(DataStream API)和 面 向 批 处 理 的 接 口(DataSet API)。因 此 ,Flink
既 可 以 完 成 流 处 理 , 也 可 以 完 成 批 处 理 。 Flink 支 持 的 拓 展 库 涉 及 机 器 学 习
(FlinkML) 、 复 杂 事 件 处 理 (CEP) 、 以 及 图 计 算 (Gelly) , 还 有 分 别 针 对 流 处
理 和 批处 理 的 Table API。
能 被 Flink Runtime 执 行 引擎 接 受 的 程 序很 强 大 ,但 是 这样 的 程 序 有 着冗 长 的 代
码 ,编 写 起来 也 很 费 力 ,基 于 这个 原 因 ,Flink 提 供 了封 装 在 Runtime 执 行 引擎 之 上
的 API , 以 帮 助 用 户 方 便 地 生 成 流 式 计 算 程 序 。 Flink 提 供 了 用 于 流 处 理 的
DataStream API 和 用 于 批 处 理 的 DataSet API。 值 得注 意 的 是 , 尽管 Flink Runtime
执 行 引擎 是 基 于 流 处理 的 ,但 是 DataSet API 先 于 DataStream API 被 开 发出 来 ,这 是
因 为 工业 界 对 无 限 流处 理 的 需 求 在 Flink 诞 生 之初 并 不 大 。
DataStream API 可 以 流 畅 地 分 析 无 限 数 据 流 , 并 且 可 以 用 Java 或 者 Scala 来 实
现 。开 发 人员 需 要 基 于 一个 叫 DataStream 的 数 据结 构 来 开 发 ,这 个 数据 结 构 用 于 表
示 永 不停 止 的 分 布 式数 据 流 。
Flink 的 分 布式 特 点 体 现 在它 能 够 在 成 百上 千 台 机 器 上运 行 ,它 将 大型 的 计 算 任
务 分 成许 多 小 的 部 分,每 个 机器 执 行 一 部 分。Flink 能 够 自动 地 确 保 发 生机 器 故 障 或
者 其 他 错 误 时 计 算 能 够 持 续 进 行 , 或 者 在 修 复 bug 或 进 行 版 本 升 级 后 有 计 划 地 再 执
行 一 次。这 种 能力 使 得 开 发 人员 不 需 要 担 心运 行 失 败。Flink 本 质 上使 用 容 错 性 数据
流 , 这使 得 开 发 人 员可 以 分 析 持 续生 成 且 永 远 不结 束 的 数 据 (即 流 处 理 ) 。
第二章 Flink 基本架构
2.5 JobManager 与 TaskManager
Flink 运 行 时包 含 了 两 种 类型 的 处 理 器 :
JobManager 处 理 器 :也 称 之为 Master,用 于 协调 分 布 式 执 行,它 们 用来 调 度 task,
协 调 检查 点 ,协 调 失败 时 恢 复 等。Flink 运 行 时至 少 存 在 一 个 master 处 理 器,如 果 配
置 高 可 用 模 式 则 会 存 在 多 个 master 处 理 器 , 它 们 其 中 有 一 个 是 leader, 而 其 他 的 都
是 standby。
TaskManager 处 理 器 : 也 称 之 为 Worker , 用 于 执 行 一 个 dataflow 的 task(或 者
特 殊 的 subtask)、数 据 缓冲 和 data stream 的 交 换,Flink 运 行 时至 少 会 存 在 一个 worker
处 理 器。
图 JobManager 与 TaskManager
Master 和 Worker 处 理 器 可 以 直 接 在 物 理 机 上 启 动 , 或 者 通 过 像 YARN 这 样 的
资 源 调度 框 架 。
Worker 连 接 到 Master, 告 知自 身 的 可 用 性进 而 获 得 任 务分 配 。
2.1 无界数据流与有界数据流
Flink 用 于 处理 有 界 和 无 界数 据 :
无 界 数 据 流 : 无 界 数 据 流 有 一 个 开 始 但 是 没 有 结 束 , 它 们 不 会 在 生 成 时 终止 并
提 供 数据 ,必 须 连续 处 理 无 界 流 ,也 就 是说 必 须 在 获 取后 立 即 处 理 event。对 于 无界
数 据 流 我 们 无 法 等 待 所 有 数 据 都 到 达 , 因 为 输 入 是 无 界 的 , 并 且 在 任 何 时 间 点 都 不
会 完 成。处 理 无界 数 据 通 常 要求 以 特 定 顺 序(例 如 事件 发 生 的 顺 序 )获 取 event,以
便 能 够推 断 结 果 完 整性 。
有 界 数 据 流 : 有 界 数 据 流 有 明 确 定 义 的 开 始 和 结 束 , 可 以 在 执 行 任 何 计 算之 前
通 过 获 取 所 有 数 据 来 处 理 有 界 流 , 处 理 有 界 流 不 需 要 有 序 获 取 , 因 为 可 以 始 终 对 有
界 数 据集 进 行 排 序 ,有 界 流 的 处 理也 称 为 批 处 理。
图 无界数据流与有解数据流
Apache Flink 是 一 个 面 向 分 布 式 数 据 流 处 理 和 批 量 数 据 处 理 的 开 源 计 算 平 台,
它 能 够 基 于 同 一 个 Flink 运 行 时(Flink Runtime), 提 供 支 持 流 处 理 和 批 处 理 两 种 类
型 应 用 的 功 能 。 现 有 的 开 源 计 算 方 案 , 会 把 流 处 理 和 批 处 理 作 为 两 种 不 同 的 应 用 类
型 , 因 为 它 们 要 实 现 的 目 标 是 完 全 不 相 同 的 : 流 处 理 一 般 需 要 支 持 低 延 迟 、
Exactly-once 保 证 , 而 批 处 理 需 要 支 持 高 吞 吐 、 高 效 处 理 , 所 以 在 实 现 的 时 候 通 常
是 分 别 给 出 两 套 实 现 方 法 , 或 者 通 过 一 个 独 立 的 开 源 框 架 来 实 现 其 中 每 一 种 处 理 方
案 。 例 如 , 实 现 批 处 理 的 开 源 方 案 有 MapReduce、Tez、Crunch、Spark, 实 现 流 处
理 的 开源 方 案 有 Samza、Storm。
Flink 在 实 现流 处 理 和 批 处理 时 ,与 传 统的 一 些 方 案 完全 不 同 ,它 从 另一 个 视 角
看 待 流处 理 和 批 处 理,将 二 者统 一 起 来 :Flink 是 完 全 支 持 流 处 理 ,也 就 是 说 作 为 流
处 理 看 待 时 输 入 数 据 流 是 无 界 的 ; 批 处 理 被 作 为 一 种 特 殊 的 流 处 理 , 只 是 它 的 输 入
数 据 流 被 定 义 为 有 界 的 。基 于 同一 个 Flink 运 行 时(Flink Runtime),分 别 提供 了 流 处
理 和 批 处 理 API, 而 这 两 种 API 也 是 实 现 上 层 面 向 流 处 理 、 批 处 理 类 型 应 用 框 架 的
基 础 。
2.2 数据流编程模型
Flink 提 供 了不 同 级 别 的 抽象 , 以 开 发 流或 批 处 理 作 业, 如 下图 所 示 :
图 Flink 抽象级别
最 底 层 级 的 抽 象 仅 仅 提 供 了 有 状 态 流 , 它 将 通 过 过 程 函 数 (Process Function)
被 嵌 入到 DataStream API 中 。底 层 过程 函 数(Process Function) 与 DataStream API
相 集 成 , 使 其 可 以 对 某 些 特 定 的 操 作 进 行 底 层 的 抽 象 , 它 允 许 用 户 可 以 自 由 地 处 理
来 自 一 个 或 多 个 数 据 流 的 事 件 , 并 使 用 一 致 的 容 错 的 状 态 。 除 此 之 外 , 用 户 可 以 注
册 事 件时 间 并 处 理 时间 回 调 , 从 而使 程 序 可 以 处理 复 杂 的 计 算。
实 际 上,大 多 数 应 用 并 不 需 要 上 述 的 底 层 抽 象,而 是 针 对 核 心 API(Core APIs)
进 行 编 程 , 比 如 DataStream API( 有 界 或 无 界 流 数 据 ) 以 及 DataSet API( 有 界 数
据 集 ) 。 这 些 API 为 数 据处 理 提 供 了 通用 的 构 建 模 块, 比 如 由 用 户定 义 的 多 种 形式
的 转 换(transformations),连 接(joins),聚 合(aggregations),窗 口 操作(windows)
等 等 。DataSet API 为 有 界 数 据 集 提 供 了 额 外 的 支 持 , 例 如 循 环 与 迭 代 。 这 些 API
处 理 的数 据 类 型 以 类(classes) 的 形式 由 各 自 的 编程 语 言 所 表 示。
Table API 是 以 表为 中 心 的 声 明式 编 程 ,其 中 表可 能 会 动 态 变化( 在 表 达流 数 据
时 )。Table API 遵 循(扩 展 的 )关 系 模型 :表 有 二维 数 据 结 构(schema)( 类 似 于
关 系 数据 库 中 的 表 ),同 时 API 提 供 可比 较 的 操 作 ,例如 select、project、join、group-by、
aggregate 等 。Table API 程 序 声明 式 地 定 义 了什 么 逻 辑 操 作应 该 执 行 ,而 不 是准 确 地
确 定 这 些 操 作 代 码 的 看 上 去 如 何 。 尽 管 Table API 可 以 通 过 多 种 类 型 的 用 户 自 定
义 函 数 (UDF) 进 行 扩 展 , 其 仍 不 如 核 心 API 更 具 表 达 能 力 , 但 是 使 用 起 来 却 更 加
简 洁(代 码 量更 少 )。除 此 之外 ,Table API 程 序 在执 行 之 前 会 经过 内 置 优 化 器进 行
优 化 。
你 可 以 在 表 与 DataStream/DataSet 之 间 无 缝 切 换 , 以 允 许 程 序 将 Table API
与 DataStream 以 及 DataSet 混 合 使 用 。
Flink 提 供 的 最 高 层 级 的 抽 象 是 SQL 。 这 一 层 抽 象 在 语 法 与 表 达 能 力 上 与
Table API 类 似 ,但 是 是以 SQL 查 询 表达 式 的 形 式 表现 程 序 。SQL 抽 象 与 Table API
交 互 密切 , 同 时 SQL 查 询 可以 直 接 在 Table API 定 义 的表 上 执 行 。
第三章 Flink 集群搭建
Flink 可 以 选择 的 部 署 方 式有 :
Local、Standalone(资 源 利用 率 低 )、Yarn、Mesos、Docker、Kubernetes、AWS。
我 们 主要 对 Standalone 模 式 和 Yarn 模 式 下的 Flink 集 群 部署 进 行 分 析 。
3.1Standalone 模式安装
我 们 对 standalone 模 式 的 Flink 集 群 进行 安 装 ,准 备 三台 虚 拟 机,其 中 一台 作 为
JobManager ( hadoop-senior01 ) , 另 外 两 台 作 为 TaskManager ( hadoop-senior02 、
hadoop-senior03) 。
1. 在 官 网下 载 1.6.1 版 本 Flink(https://archive.apache.org/dist/flink/flink-1.6.1/) 。
2. 将 安 装包 上 传 到 要 按照 JobManager 的 节 点(hadoop-senior01) 。
3. 进 入 Linux 系 统 对安 装 包 进 行 解压 :
4. 修 改 安装 目 录 下 conf 文 件 夹内 的 flink-conf.yaml 配 置 文件 , 指 定 JobManager:
5. 修 改 安装 目 录 下 conf 文 件 夹内 的 slave 配 置 文件 , 指 定 TaskManager:
6. 将 配 置好 的 Flink 目 录 分发 给 其 他 的 两台 节 点 :
7. 在 hadoop-senior01 节 点 启动 集 群 :
8. 通 过 jps 查 看 进程 信 息 :
9. 访 问 集群 web 界 面 (8081 端 口 ):
3.2Yarn 模式安装
1 在 官 网下 载 1.6.1 版 本 Flink(https://archive.apache.org/dist/flink/flink-1.6.1/) 。
2 将 安 装包 上 传 到 要 按照 JobManager 的 节 点(hadoop-senior01) 。
3 进 入 Linux 系 统 对安 装 包 进 行 解压 :
4 修 改 安装 目 录 下 conf 文 件 夹内 的 flink-conf.yaml 配 置 文件 , 指 定 JobManager:
5 修 改 安装 目 录 下 conf 文 件 夹内 的 slave 配 置 文件 , 指 定 TaskManager:
6 将 配 置好 的 Flink 目 录 分发 给 其 他 的 两台 节 点 :
7. 明 确 虚拟 机 中 已 经 设置 好 了 环 境 变量 HADOOP_HOME。
8. 启 动 Hadoop 集 群 (HDFS 和 Yarn) 。
9. 在 hadoop-senior01 节 点 提 交 Yarn-Session , 使 用 安 装 目 录 下 bin 目 录 中 的
yarn-session.sh 脚 本 进行 提 交 :
/opt/modules/flink-1.6.1/bin/yarn-session.sh -n 2 -s 6 -jm 1024 -tm 1024 -nm test -d
其 中 :
-n(--container):TaskManager 的 数 量。
-s(--slots): 每 个 TaskManager 的 slot 数 量 ,默 认 一个 slot 一 个 core,默 认 每 个
taskmanager 的 slot 的 个 数为 1, 有 时可 以 多 一 些 taskmanager, 做 冗余 。
-jm:JobManager 的 内 存( 单 位 MB)。
-tm: 每 个 taskmanager 的 内 存( 单 位 MB)。
-nm:yarn 的 appName(现 在 yarn 的 ui 上 的 名字)。
-d: 后 台执 行 。
10. 启 动 后查 看 Yarn 的 Web 页 面 ,可 以 看 到 刚 才提 交 的 会 话 :