Apache Flink 进阶(三):Checkpoint 原理解析与应用实践
大家好,今天我将跟大家分享一下 Flink 里面的 Checkpoint,共分为四个部分。首先讲一下 Checkpoint 与 state 的关系,然后介绍什么是 state,第三部分介绍如何在 Flink 中使用state,第四部分则介绍 Checkpoint 的执行机制。
Checkpoint 与 state 的关系
Checkpoint 是从 source 触发到下游所有节点完成的一次全局操作。下图可以有一个对 Checkpoint 的直观感受,红框里面可以看到一共触发了 569K 次 Checkpoint,然后全部都成功完成,没有 fail 的。

state 其实就是 Checkpoint 所做的主要持久化备份的主要数据,看下图的具体数据统计,其 state 也就 9kb 大小 。

什么是 state
我们接下来看什么是 state。先看一个非常经典的 word count 代码,这段代码会去监控本地的 9000 端口的数据并对网络端口输入进行词频统计,我们本地行动 netcat,然后在终端输入 hello world,执行程序会输出什么?

答案很明显,(hello, 1) 和 (word,1)
那么问题来了,如果再次在终端输入 hello world,程序会输入什么?
答案其实也很明显,(hello, 2) 和 (world, 2)。为什么 Flink 知道之前已经处理过一次 hello world,这就是 state 发挥作用了,这里是被称为 keyed state 存储了之前需要统计的数据,所以帮助 Flink 知道 hello 和 world 分别出现过一次。
回顾一下刚才这段 word count 代码。keyby 接口的调用会创建 keyed stream 对 key 进行划分,这是使用 keyed state 的前提。在此之后,sum 方法会调用内置的 StreamGroupedReduce 实现。

什么是 keyed state
对于 keyed state,有两个特点:
- 只能应用于 KeyedStream 的函数与操作中,例如 Keyed UDF, window state
- keyed state 是已经分区/划分好的,每一个 key 只能属于某一个 keyed state
对于如何理解已经分区的概念,我们需要看一下 keyby 的语义,大家可以看到下图左边有三个并发,右边也是三个并发,左边的词进来之后,通过 keyby 会进行相应的分发。例如对于 hello word,hello 这个词通过 hash 运算永远只会到右下方并发的 task 上面去。

什么是operator state
- 又称为 non-keyed state,每一个 operator state 都仅与一个 operator 的实例绑定。
- 常见的 operator state 是 source state,例如记录当前 source 的 offset
再看一段使用 operator state 的 word count 代码:

这里的fromElements会调用FromElementsFunction的类,其中就使用了类型为 list state 的 operator state。根据 state 类型做一个分类如下图:

除了从这种分类的角度,还有一种分类的角度是从 Flink 是否直接接管:
- Managed State:由 Flink 管理的 state,刚才举例的所有 state 均是 managed state
- Raw State:Flink 仅提供 stream 可以进行存储数据,对 Flink 而言 raw state 只是一些 bytes
在实际生产中,都只推荐使用 managed state,本文将围绕该话题进行讨论。
如何在 Flink 中使用 state
下图就前文 word count 的 sum 所使用的StreamGroupedReduce类为例讲解了如何在代码中使用 keyed state:

下图则对 word count 示例中的FromElementsFunction类进行详解并分享如何在代码中使用 operator state:

Checkpoint 的执行机制
在介绍 Checkpoint 的执行机制前,我们需要了解一下 state 的存储,因为 state 是 Checkpoint 进行持久化备份的主要角色。
Statebackend 的分类
下图阐释了目前 Flink 内置的三类 state backend,其中MemoryStateBackend和FsStateBackend在运行时都是存储在 java heap 中的,只有在执行 Checkpoint 时,FsStateBackend才会将数据以文件格式持久化到远程存储上。而RocksDBStateBackend则借用了 RocksDB(内存磁盘混合的 LSM DB)对 state 进行存储。

对于HeapKeyedStateBackend,有两种实现:
- 支持异步 Checkpoint(默认):存储格式 CopyOnWriteStateMap
- 仅支持同步 Checkpoint:存储格式 NestedStateMap
特别在 MemoryStateBackend 内使用HeapKeyedStateBackend时,Checkpoint 序列化数据阶段默认有最大 5 MB数据的限制
对于RocksDBKeyedStateBackend,每个 state 都存储在一个单独的 column family 内,其中 keyGroup,Key 和 Namespace 进行序列化存储在 DB 作为 key。

Checkpoint 执行机制详解
本小节将对 Checkpoint 的执行流程逐步拆解进行讲解,下图左侧是 Checkpoint Coordinator,是整个 Checkpoint 的发起者,中间是由两个 source,一个 sink 组成的 Flink 作业,最右侧的是持久化存储,在大部分用户场景中对应 HDFS。
1、第一步,Checkpoint Coordinator 向所有 source 节点 trigger Checkpoint;。

2、第二步,source 节点向下游广播 barrier,这个 barrier 就是实现 Chandy-Lamport 分布式快照算法的核心,下游的 task 只有收到所有 input 的 barrier 才会执行相应的 Checkpoint。

3、第三步,当 task 完成 state 备份后,会将备份数据的地址(state handle)通知给 Checkpoint coordinator。

4、第四步,下游的 sink 节点收集齐上游两个 input 的 barrier 之后,会执行本地快照,这里特地展示了 RocksDB incremental Checkpoint 的流程,首先 RocksDB 会全量刷数据到磁盘上(红色大三角表示),然后 Flink 框架会从中选择没有上传的文件进行持久化备份(紫色小三角)。

5、同样的,sink 节点在完成自己的 Checkpoint 之后,会将 state handle 返回通知 Coordinator。

6、最后,当 Checkpoint coordinator 收集齐所有 task 的 state handle,就认为这一次的 Checkpoint 全局完成了,向持久化存储中再备份一个 Checkpoint meta 文件。

Checkpoint 的 EXACTLY_ONCE 语义
为了实现 EXACTLY ONCE 语义,Flink 通过一个 input buffer 将在对齐阶段收到的数据缓存起来,等对齐完成之后再进行处理。而对于 AT LEAST ONCE 语义,无需缓存收集到的数据,会对后续直接处理,所以导致 restore 时,数据可能会被多次处理。下图是官网文档里面就 Checkpoint align 的示意图:

需要特别注意的是,Flink 的 Checkpoint 机制只能保证 Flink 的计算过程可以做到 EXACTLY ONCE,端到端的 EXACTLY ONCE 需要 source 和 sink 支持。
Savepoint 与 Checkpoint 的区别
作业恢复时,二者均可以使用,主要区别如下:
| Savepoint | Externalized Checkpoint |
|---|---|
| 用户通过命令触发,由用户管理其创建与删除 | Checkpoint 完成时,在用户给定的外部持久化存储保存 |
| 标准化格式存储,允许作业升级或者配置变更 | 当作业 FAILED(或者CANCELED)时,外部存储的 Checkpoint 会保留下来 |
| 用户在恢复时需要提供用于恢复作业状态的 savepoint 路径 | 用户在恢复时需要提供用于恢复的作业状态的 Checkpoint 路径 |
本文作者:唐云(茶干)
本文为云栖社区原创内容,未经允许不得转载。
Apache Flink 进阶(三):Checkpoint 原理解析与应用实践的更多相关文章
- Apache Flink 进阶(八):详解 Metrics 原理与实战
本文由 Apache Flink Contributor 刘彪分享,本文对两大问题进行了详细的介绍,即什么是 Metrics.如何使用 Metrics,并对 Metrics 监控实战进行解释说明. 什 ...
- Apache Flink 进阶(六):Flink 作业执行深度解析
本文根据 Apache Flink 系列直播课程整理而成,由 Apache Flink Contributor.网易云音乐实时计算平台研发工程师岳猛分享.主要分享内容为 Flink Job 执行作业的 ...
- Apache Flink 进阶(一):Runtime 核心机制剖析
1. 综述 本文主要介绍 Flink Runtime 的作业执行的核心机制.首先介绍 Flink Runtime 的整体架构以及 Job 的基本执行流程,然后介绍在这个过程,Flink 是怎么进行资源 ...
- Apache Flink 进阶入门(二):Time 深度解析
前言 Flink 的 API 大体上可以划分为三个层次:处于最底层的 ProcessFunction.中间一层的 DataStream API 和最上层的 SQL/Table API,这三层中的每一层 ...
- flink-----实时项目---day07-----1.Flink的checkpoint原理分析 2. 自定义两阶段提交sink(MySQL) 3 将数据写入Hbase(使用幂等性结合at least Once实现精确一次性语义) 4 ProtoBuf
1.Flink中exactly once实现原理分析 生产者从kafka拉取数据以及消费者往kafka写数据都需要保证exactly once.目前flink中支持exactly once的sourc ...
- Flink Exactly-once 实现原理解析
关注公众号:大数据技术派,回复"资料",领取1024G资料. 这一课时我们将讲解 Flink "精确一次"的语义实现原理,同时这也是面试的必考点. Flink ...
- Android进阶:七、Retrofit2.0原理解析之最简流程【下】
紧接上文Android进阶:七.Retrofit2.0原理解析之最简流程[上] 一.请求参数整理 我们定义的接口已经被实现,但是我们还是不知道我们注解的请求方式,参数类型等是如何发起网络请求的呢? 这 ...
- Apache Flink:特性、概念、组件栈、架构及原理分析
2016-04-30 22:24:39 Yanjun Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时(Flink Runtim ...
- Kafka设计解析(二十)Apache Flink Kafka consumer
转载自 huxihx,原文链接 Apache Flink Kafka consumer Flink提供了Kafka connector用于消费/生产Apache Kafka topic的数据.Flin ...
随机推荐
- C#获取本月开始日期和结束日期
DateTime dt = DateTime.Now; //本月第一天时间 DateTime dt_First = dt.AddDays( - (dt.Day)); //获得某年某月的天数 int y ...
- P1487 失落的成绩单
P1487 失落的成绩单a[i]=a[i-2]-2.0*a[i-1]+2.0*d;a[2]越大,a[3]越小a[3]越大,a[4]越小所以a[2]越大,a[4]越大,a[3]越小就有了单调性,分奇偶进 ...
- 网络编程之TCP协议怎么使用?
TCP 通信的客户端:向服务器发送连接请求,给服务器发送数据,读取服务器会写的数据 表示客户端的类: java.net.Socket;此类实现客户端套接字.套接字是两台机器间通信的端点 套接字:包含了 ...
- Nginx的动静分离
Nginx的动静分离 在之前我们的负载均衡中,我们再jsp中设置了一个背景,这是一个静态资源,Tomcat处理静态资源的效率并没有Nginx高,我们可以通过动静分离将静态资源和动态资源分割开来,Tom ...
- 【重磅来袭】阿里小程序IDE上线8大功能
时隔两个月,10月10日阿里小程序IDE上线了uni-app 跨平台研发支持.预览和真机调试交互优化.预检测新增代码扫描等8项功能,进一步完善了阿里小程序IDE的功能池,给大家更好的开发体验和环境. ...
- 2018年阿里云NoSQL数据库大事盘点
NoSQL一词最早出现在1998年.2009年Last.fm的Johan Oskarsson发起了一次关于分布式开源数据库的讨论,来自Rackspace的Eric Evans再次提出了NoSQL概念, ...
- mac系统下通过安装包的形式安装mongdb
下载地址 mongoDB mongoDB 图形化管理软件 MongoDB Compass 下载完成后,进行解压,解压后的文件进行重命名 mongodb 然后前往/usr/local,将mongodb文 ...
- 帝国cms批量更新内容页
系统设置->数据更新->批量更新信息页地址 系统设置->数据更新->数据整理: 再更新整站主要页面即可
- 依赖背包优化——ural1018,金明的预算方案
经典题了,网上博客一大堆O(nCC)的做法,其实是可以将复杂度降到O(nC)的 参考依赖背包优化(泛化物品的并) 根据背包九讲,求两个泛化物品的和复杂度是O(CC)的,所以依赖背包暴力求解的复杂度是O ...
- PyQt5显示日期选择框,获取日期保存文件
一.UI显示选择日期,保存到文件 import sys,os from PyQt5 import QtCore from PyQt5.QtGui import * from PyQt5.QtWidge ...