最新发布《数智时代的AI人才粮仓模型解读白皮书(2024版)》,立即领取! 了解详情
写点什么

让时间倒流的保存点:用 Apache Flink 的保存点技术重新处理数据流

  • 2017-01-09
  • 本文字数:3927 字

    阅读完需:约 13 分钟

本文翻译自 Savepoints: Turning Back Time, Reprocessing Data Streams with Savepoints in Apache Flink ,原作者为Fabian Hueske(@fhueske)和Mike Winters(@wints)。翻译已获得原网站授权。

这篇文章是系列文章的第一篇,数据工匠团队会在这里为大家展示一些 Apache Flink 的核心功能。

流处理通常被大家与“动态数据”关联起来,相应的系统差不多会在数据被创造出来的那一刻就立刻对其进行处理或响应。像延迟、吞吐量、水印和处理迟到的数据等等都是大家讨论得最多的流处理话题,通常是关注现在,而不是过去。

可在实际项目中,却有许多种场景需要你的流处理程序把以前处理过的数据再重新处理一遍。这里有些例子:

  • 为你的程序部署一个新版本,可能是有新功能、修复了问题、或者采用了更好的机器学习模型;
  • 使用相同的源数据流对应用程序的不同版本进行 A/B 测试,两边都从同一个点开始测试,这样就不会牺牲之前的状态;
  • 评估或开展将应用程序迁移到更新版本的处理框架上,或是一个不同的集群上;

Apache Flink 的保存点(Savepoint)功能可以支持上面的所有场景,并且也是让 Flink 与其它分布式开源流处理器不同的一个显著区别点。

在本文中,我们会讲述如何使用保存点功能来重新处理数据,并一定程度地深入底层,讲述这个功能在 Flink 中是怎么实现的。

“重新处理”到底是什么意思?

为了保证大家对重新处理数据的理解是一致的,我们先讨论一个你可能需要重新处理数据的业务例子。想像一个社交媒体公司,她除了基本的发贴功能之外,还发布了一种付费的、或者说是推广发贴的功能。

公司的用户可以访问一个简单的、基于 Flink 实现的仪表板,显示他们的所有文章(不管是普通的还是付费的)被大家查看、点击等等的次数。几个星期之后,从用户的反馈中就可以清晰地看到,这个仪表板如果能把普通的发贴数据和付费的发贴数据区别开来,那就会更好用。

要实现这个功能,就有必要返回到付费发贴功能最初发布的那个时刻,然后从那个时刻开始,把所有数据全都重新处理一遍。这一次要把付费贴和普通贴的展示和交互全都拆开来。如果要把从公司创立伊始产生的数据全都重新处理一遍,这就实在有点强人所难,所以能够从付费发贴的功能发布的时候开始重新处理,同时还保留之前的计算结果,这个功能就很有必要了。

所以当我们用到“重新处理”这个词时,我们的意思就是回到一个系统以前的、一致的状态(按开发者的定义,不一定非要是流的最早状态),然后从那个状态开始再处理一遍,可能也要在更改了你的 Flink 程序之后。

读者们可以看到的好消息就是:Flink 为大家免费提供了上述重新处理功能,相应的功能就叫保存点。我们说"免费",意思是只要你的程序是容错的,并且可以从错误中恢复,那你就可以在 Flink 中创建一个保存点并重新处理数据,花费的额外准备工作量几乎为零。

简单说说保存点到底是什么

简而言之,一个 Flink 程序的保存点就是关于以下两点的全局一致的镜像:

  • 所有数据源的位置;
  • 所有并行操作者的状态;

“全局一致”意味着所有并行的操作者的状态都在所有输入的相同的明确定义的位置处被记录下来了。

如果在过去的某个时刻,你为某个应用程序记下了保存点,那你就可以从那个保存点的位置开始启动一个新程序。新的程序将使用那个保存点位置保存下来的操作者的状态进行初始化,并且会从记录的保存点里各个数据源的相应位置开始,重新处理全部数据。

因为 Flink 的保存点之间是相互完全独立的,所以对每个程序你都可以有多个保存点,这样你就可以根据这些不同的保存点的信息,回到不同的位置,启动多次、甚至不同的程序(如下图所示)。这个功能对于派生你的流处理程序,或者为它们打不同的版本,是非常有用的。

我们应该注意,在从某个保存点开始重新处理数据时,对事件的时间处理是非常重要的。重新处理基本上就意味着从过去到现在进行快速回放,也就是说,是全速地从某些存储系统中读出数据,直到赶上了当前的状态,然后再继续实时地处理新到达的数据。

因为程序对于时间的处理或者插入时间都是要依赖当前的本地时间的,那么如果在根据保存点启动程序时不使用事件的时间,而使用别的时间,对程序的逻辑而言就很可能导致错误的结果。

听起来不错,那我该做什么?

不用做很多!事实上,所有支持故障恢复的程序都是自动支持保存点的。因此,大多数进行有状态计算的程序已经满足了需要的条件。如果没有,可以对它们进行快速更新,让它们具备:

  • 启用检查点功能:在每种情况下,我们都推荐在构建 Flink 程序的同时,把检查点功能打开,事实上在你的 Flink 程序中加上检查点只是需要增加几行代码而已。
  • 可以重置的数据源(即 Apache Kafka、Amazon Kinesis,或者文件系统等):数据源必须能按照你想要重新处理的点开始,重放数据。
  • 所有的状态都通过 Flink 的管理状态接口保存:所有具体的操作者的状态都必须保存在 Flink 的容错状态数据结构中,这让它可以按照某个之前的保存点位置被重置。
  • 配置一个合适的状态后台:Flink 提供了不同的状态后台来将检查点和保存点持久化。默认地,保存点都保存在JobManager 中,但你要为你的程序配置一个适当的后台状态程序,比如 RocksDB 等。

如果你已经在运行一个容错的程序了,那就创建一个保存点,然后从保存点的位置开始重新启动程序,这只需要在 Flink 命令行里敲几个命令就可以了。咱们接下来挨个看看。

第一步:创建一个保存点

首先,获得所有运行中的 Flink 任务的列表:

复制代码
user$ flink list
------------Running/Restarting Jobs------------
10.10.2016 16:20:33 : job_id : Sample Job (RUNNING)

(运行上面的命令时,你的真实任务 ID 会是一个包括字母和数字的字符串。)

然后,用相应的任务 ID 创建一个保存点:

复制代码
user$ flink savepoint job_id

现在你的保存点就已经可用了。

如果你准备马上根据你的保存点来重新启动任务,你通常会想要把现在正在运行的任务先停掉。你已经有了相应任务的 ID,那把它停掉只要几秒钟就够了:

复制代码
user$ flink cancel job_id

第二步:从一个保存点开始启动任务

当你更新完程序之后,就可以从你的保存点开始启动任务了。

复制代码
user$ flink run -d -s hdfs://savepoints/1 directory/your-updated-application.jar

如果你想在一个示例程序中自己重做这些步骤,我们推荐你看看一篇之前的博客文章,我们在那里讲了怎么做这件事。

如果我想升级我的程序,该怎样做?

如果你想从一个保存点开始启动一个修改过的程序,有几件事是要考虑的。我们可以区别下面这两种情况:

  1. 改变一个用户定义的函数的逻辑,比如 MapFunction;
  2. 改变一个程序的架构,也就是增加或减少操作者等;

第一种情况很简单,不需要什么特别的准备。你可以按你的需要去修改函数代码。不过,如果你用一个修改了的架构从保存点开始启动程序,那么为了能够恢复操作者的状态,Flink 必须能够将保存点程序的操作者与使用了新架构的新程序的操作者对应起来。

在这种情况下,你就要手动地将操作者 ID 分配给最初的和更新了的程序。因为如果没有操作者 ID 的话,是没办法修改程序的架构的。所以最佳实践经验就要求一定要分配操作者 ID。

下面的代码段显示了如何为操作者们分配 ID。

复制代码
DataStream stream = env.
// Stateful source (e.g. Kafka) with ID
.addSource(new StatefulSource())
.uid(“source-id”)
.shuffle()
// The stateful mapper with ID
.map(new StatefulMapper())
.uid(“mapper-id”)
// Stateless sink (no specific ID required)
stream.print()

请查阅文档,了解更多关于升级程序和保存点的细节。

关于保存点的最佳实践

要更好的利用上文中描述的Flink 的重新处理功能,你应该经常触发,生成新的保存点。我们建议要根据某些时刻表(比如每天一次,每周一次,等等)自动地生成保存点,而且每当你关闭某个任务或发布程序的新版本时,也最好先生成保存点。

依据你想用Flink 做的事件不同,生成保存点的最佳方法也会不同,但总的来说,在构建你的程序时你应该花些时间考虑如何使用这些保存点。

这些东西是怎么工作的呢?

保存点事实上只是检查点的一个延伸,这就是Flink 的容错机制。如果开启了检查点功能,Flink 就会周期性地为所有的操作者状态生成一个一致的检查点。在文档中详细的描述了检查点的细节,如果你是个Flink 新手,花些时间去读读是非常值得的。

你可能会以为要生成一个一致的检查点,就得暂停数据处理,因为Flink 必须要等着,直到所有没处理完的记录全被处理掉了,然后做个镜像,镜像生成之后再回去继续处理数据。事实并非如此!Flink 是持续处理数据的,即使在生成检查点的时候也是这样。文档中的“Barriers”一节讲了实现这个功能的原理。

两者之间的关键区别:检查点是基于某些规定的时间间隔自动生成的,而保存点是由用户显式地触发生成的,而且不会象检查点那样过了一定的时间之后就会被删掉

总结

我们讨论了Apache Flink 的保存点和数据重处理功能,因为我们相信这就是Flink 与开源世界中其它流处理器之间的重要区别之一。而且最重要的,在容错的Flink 程序中获得重处理功能几乎是不需要任何代价的,只需要很少的改动。

Flink 社区现在还在积极地工作着,要把保存点功能做得更好,包括在改变并发度的情况下保存状态的解决方案等。有些相应的功能(比如 Flink-3755 )已经发布到主分支上了,而且会被包含到下一个小版本 Flink 1.2.0 中。

所以,当你需要把程序多部署一份,或者上个新版本,或者要做 A/B 测试,或者要让多个程序从同一个点开始处理数据时,你可以这么做了,而且不会丢失那些宝贵的状态数据。

当有真实的需求时,流处理基于实时的特性不应该阻挡你把时间调回过去的动作。

有兴趣了解关于 Apache FLink 的保存点的更多内容吗?数据工匠 CTO Stephan Ewen 做了一个关于这个话题的七分钟白板演练,你可以在 MapR 博客上看到相关内容。

2017-01-09 16:383613
用户头像

发布了 152 篇内容, 共 68.0 次阅读, 收获喜欢 63 次。

关注

评论

发布
暂无评论
发现更多内容

WordPress 编辑用户

海拥(haiyong.site)

WordPress 5月月更

记一次 JMeter 压测 HTTPS 性能问题

阿里巴巴云原生

阿里云 云原生 https Jmeter 压测

微信朋友圈高性能架构设计

极客土豆

最好用的 8 款 React Datepicker 时间日期选择器测评推荐

蒋川

react.js 组件 组件库 低代码平台 Javascript框架

规模化软件开发的必由之路—大规模自动化测试

刘冉

自动化测试

成本节省 50%,10 人团队使用函数计算开发 wolai 在线文档应用

阿里巴巴云原生

阿里云 Serverless 云原生 函数计算

Java Core「2」synchronized 关键字

Samson

学习笔记 5月月更 Java core

Linux环境编译静态库

Loken

音视频 5月月更

架构实战营 - 第 6 期 模块六课后作业

天琪实刚亮

架构实战营

提效客户体验管理:结合 K-Means 聚类和 RFM 模型的客户分群

龙国富

RFM 客户分群 K-Means

聊聊我对质量度量的看法

老张

软件测试 质量保障

跨平台应用开发进阶(十二) :uni-app 实现应用桌面图标角标提示及应用跳转

No Silver Bullet

uni-app 5月月更 桌面角标

Artery —— 单页面应用接口描述语言简介

全象云低代码

前端 低代码 流程 页面 artery

密码学系列之:使用openssl检测网站是否支持ocsp

程序那些事

Java 密码学 程序那些事 5月月更

比特币价格预测两极分化:跌至1万美元还是涨至10万美元?

CECBC

拆分电商系统为微服务

流火

C++最佳实践 | 1. 工具

俞凡

c++ 最佳实践

跨平台应用开发进阶(十一) :uni-app 实现IOS原生APP-云打包集成极光推送(JG-JPUSH)详细教程

No Silver Bullet

uni-app ios 5月月更 云打包 原生APP

《SaaS产品经理从菜鸟到专家》读书笔记

圣迪

产品 产品经理 SaaS tob tob产品

架构实战营模块 6 作业

热猫

【C 语言】指针 Five 之 ["​⚔ 空指针 - NULL、💣 指针使用之前检查有效性、🗡 指针运算 💣 指针+- 整数、💣 指针 - 指针、指针关系运算、💣 标准规定、⚔ 指针和数组、⚔ 二级指针、⚔ 指针数组"]

謓泽

5月月更

Nacos 开源之夏 2022 来了

阿里巴巴云原生

阿里云 开源 微服务 云原生 nacos

为了兼容IE,配置Babel+Webpack

空城机

webpack 5月月更

【ELT.ZIP】OpenHarmony啃论文俱乐部——多层存储分级数据压缩

ELT.ZIP

鸿蒙 数据压缩 ELT.ZIP HCompress

M_5: 设计微博系统中”微博评论“的高性能高可用计算架构。

Jadedev

架构训练营

老板对技术部产出不满意怎么办?

石云升

产品思维 职场经验 管理经验 5月月更

【LeetCode】交换链表中的节点Java题解

Albert

LeetCode 5月月更

1.1 历史长河中的顶层设计

凌晞

阿里巴巴在 Envoy Gateway 的演进历程浅析

阿里巴巴云原生

阿里云 Kubernetes 云原生

Bigdata 作业 第11周

Pyel

单片机开发入门知识介绍

DS小龙哥

5月月更

让时间倒流的保存点:用Apache Flink的保存点技术重新处理数据流_开源_Fabian Hueske_InfoQ精选文章