NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

Apache Flink 进阶(三):Checkpoint 原理剖析与应用实践

  • 2019-09-25
  • 本文字数:2711 字

    阅读完需:约 9 分钟

Apache Flink进阶(三):Checkpoint原理剖析与应用实践

本文将分享 Flink 中 Checkpoint 的应用实践,包括四个部分,分别是 Checkpoint 与 state 的关系、什么是 state、如何在 Flink 中使用 state 和 Checkpoint 的执行机制。如果你对于 Apache Flink 了解不多,可以先阅读Apache Flink 零基础入门系列文章。

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,其中MemoryStateBackendFsStateBackend在运行时都是存储在 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。


a. 第一步,Checkpoint Coordinator 向所有 source 节点 trigger Checkpoint;。



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



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



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



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



f. 最后,当 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 的区别

作业恢复时,二者均可以使用,主要区别如下:


SavepointExternalized Checkpoint
用户通过命令触发,由用户管理其创建与删除Checkpoint 完成时,在用户给定的外部持久化存储保存
标准化格式存储,允许作业升级或者配置变更当作业 FAILED(或者CANCELED)时,外部存储的 Checkpoint 会保留下来
用户在恢复时需要提供用于恢复作业状态的 savepoint 路径用户在恢复时需要提供用于恢复的作业状态的 Checkpoint 路径


相关文章:


Apache Flink进阶(二):时间属性深度解析


Apache Flink进阶(一):Runtime 核心机制剖析


Apache Flink 零基础入门系列文章


2019-09-25 09:1011840

评论 1 条评论

发布
用户头像
对于小白的我,还是有一丢丢看不懂
2020-12-16 10:05
回复
没有更多了
发现更多内容

聊聊 C 语言和 ABAP 这两门编程语言的关系

Jerry Wang

c++ 编程语言 C语言 abap 3月月更

昇腾CANN论文上榜CVPR,全景图像生成算法交互性再增强!

华为云开发者联盟

CVPR CANN 图像生成 昇腾AI处理器 图像布局

5G 和 Wi-Fi 市场与技术的一些思考系列之二

李伟-晨泳

Jetpack Compose之 在Compose中使用Navigation导航

黄林晴

android Compose JetPack

《软件开发的201个原则》思考:4. 高质量软件是可以实现的

非晓为骁

个人成长 软件工程 软件开发

RocketMQ的tag还有这个“坑”!

中间件兴趣圈

RocketMQ tag 消息过滤

公有云RDS太贵?基于ECS构建的多云RDS服务可降低近半成本

沃趣科技

数据库 公有云 RDS 云数据库RDS for MySQL 云数据库Redis

DPU芯片头部企业云豹智能加入龙蜥社区,共同推动新一代数据中心基础设施蓬勃发展

OpenAnolis小助手

云计算 开源 芯片 龙蜥社区

小程序电商微服务设计

唐尤华

架构实战营

Rust的Cow类型

Shine

rust cow

大数据培训十大Hive调优技巧

@零度

大数据 hive调优

你了解部署流水线吗?

华为云开发者联盟

自动化 软件开发 devcloud 部署流水线 流水线

FAQ(常见问题)页面的编写技巧

小炮

企业 常见问题 客户服务

java培训Redis高频面试考点

@零度

Java redis

春招进行时!当代大学生求职行为大赏

易观分析

求职 招聘 春招

一文搞定 Flutter 底部弹窗实现

岛上码农

flutter 跨平台 ios开发 Android开发 3月月更

Redis:在windows环境安装Redis

喀拉峻

redis

HertzBeat赫兹节拍 v1.0.beta.6 发布,Linux监控来啦

TanCloud探云

开源 APM 监控 告警

深入浅出 Vue3 核心知识点

百瓶技术

Vue 前端 VUE 3.0 源码 vue3.0

云效DevOps全家桶评测征集令重磅来袭!免费使用云效全套功能

阿里云云效

云计算 阿里云 DevOps 云原生

Redis集群架构剖析(3):集群处理redis-cli指令

非晓为骁

redis 架构 分布式 redis cluster

presto是如何保证作业内存不会发生冲突和溢出

华为云开发者联盟

内存 presto 内存计算引擎 System Pool general Pool

如何在新公司快速落地

Hockor

最好的 6 个 React Table 组件详细亲测推荐

蒋川

React

焕然一新的 Vue 3 中文文档来了

CRMEB

玩转OpenMLDB社区,四张角色卡待解锁

第四范式开发者社区

人工智能 数据库 开源 贡献者 特征平台

☕️从Java8到Java17的新特性(一):Java8 的新特性

看山

Java java8

WebAssembly技术_JS调用C函数示例_传递参数、方法导出

DS小龙哥

webassembly 3月月更

如何消除代码山中那一大坨参数列表

华为云开发者联盟

代码 软件设计 参数 全局变量 参数列表

IOS技术分享| ARCallPlus 开源项目(一)

anyRTC开发者

ios 移动开发 语音通话 视频通话 呼叫邀请

使用APICloud AVM多端框架开发仿微信通讯录功能

YonBuilder低代码开发平台

前端开发 APP开发 APICloud 多端开发 avm.js

Apache Flink进阶(三):Checkpoint原理剖析与应用实践_语言 & 开发_唐云(茶干)_InfoQ精选文章