写点什么

让时间倒流的保存点:用 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:383821
用户头像

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

关注

评论

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

百度大脑UNIT拍了拍你,提醒你报名智能对话训练营

百度大脑

物联网 智能对话

一个朋友学会Java泛型后直接薪资翻倍!

北游学Java

Java 泛型

开发者必看,面试官心中的最佳数据库人才模型是什么样?

华为云开发者联盟

面试 开发者 华为云数据库 数据库人才

精选Hive高频面试题11道,附答案详细解析

五分钟学大数据

大数据 hive 5月日更

这个英语学习APP更适合小白

小天同学

学习 英语 5月日更 APP推荐

HarmonyOS开发者创新大赛预选赛结束,23支队伍脱颖而出闯入决赛

Geek_283163

鸿蒙

华为云PB级数据库GaussDB(for Redis)揭秘第九期:与HBase的对比

华为云开发者联盟

HBase 华为云 开源数据库 NoSQL数据库 数据库GaussDB(for Redis)

工商银行分布式服务 C10K 场景解决方案

阿里巴巴云原生

容器 微服务 云原生 监控 应用服务中间件

挖矿从入门到放弃:Chia

程序员架构进阶

数字货币 28天写作 Chia奇亚挖矿 5月日更

如何更改 Notion 中的字体?

彭宏豪95

效率 Notion 工具 5月日更

自动发布.NET Core Web应用

DisonTangor

DevOps 运维自动化 jenkins dotnet

技术实践丨如何解决异步接口请求快慢不均导致的数据错误问题?

华为云开发者联盟

JavaScript typescript 大前端 浏览器 angular

只会重装系统的运维,不是好运维

运维研习社

Linux 5月日更 系统修复

架构实战营-详细架构设计文档

Simon

架构实战营

【LeetCode】解码异或后的排列Java题解

Albert

算法 LeetCode 5月日更

耗时1年的前端技术框架切换之旅

华为云开发者联盟

大前端 软件工程 React 框架

Golang Chaos Engineering

escray

学习 极客时间 Go 语言 5月日更

SICP 习题2.6之丘奇数

程序员历小冰

函数式编程 SICP 5月日更

大数据实战:网站流量日志数据分析

大数据技术指南

大数据 5月日更

你到底想做什么

ES_her0

5月日更

聊聊 Zabbix 和 Prometheus(一)

耳东@Erdong

Prometheus zabbix 5月日更

Python OOP-5

若尘

oop Python编程 5月日更

恍然大悟丨Java 中 RMI 的使用

Java架构师迁哥

腾讯云大神亲码“redis深度笔记”,从基础到源码,应有尽有

Java 编程 程序员 架构

那些激情燃烧的NFT们

zhoo299

区块链 加密货币 艺术 5月日更 NFT

技术干货|7个 React 性能提升技巧

拍乐云Pano

React

使用docker compose快速部署前后端分离项目案例

皮特王

nginx Docker Vue Docker-compose

打破思维定式(六)

Changing Lin

5月日更

五一假期回乡,跟大家聊聊感触

架构精进之路

心情 杂记 5月日更

阿里云入选 2021 Gartner APM 魔力象限,国内唯一入选云厂商

阿里巴巴云原生

阿里云 容器 微服务 运维 云原生

jmeter命令行执行测试并对测试报表进行初步分析

行者AI

测试 Jmeter

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