分布式Snapshot和Flink Checkpointing简介

本文涉及的产品
实时计算 Flink 版,1000CU*H 3个月
简介: 最近在学习Flink的Fault Tolerance,了解到Flink在Chandy Lamport Algorithm的基础上扩展实现了一套分布式Checkpointing机制,这个机制在论文"Lightweight Asynchronous Snapshots for Distributed Dataflows"中进行了详尽的描述。

阿里巴巴实时计算部-昆仑

最近在学习Flink的Fault Tolerance,了解到Flink在Chandy Lamport Algorithm的基础上扩展实现了一套分布式Checkpointing机制,这个机制在论文"Lightweight Asynchronous Snapshots for Distributed Dataflows"中进行了详尽的描述。怀着对Lamport大神的敬仰,我分别下载研读了两篇论文,在这里把一些阅读的收获记录下来,希望能对学习Flink/Blink的同学能有些帮助。

Chandy Lamport Algorithm

我们先来看看Chandy Lamport Algorithm,“Distributed Snapshots: Determining Global States of a Distributed System”,此文应该是分布式SnapShot的开山之作,发布于1985年(很多同学还没有出生-_-),按照Lamport自己的说法,这篇文章是这么来的:

“The distributed snapshot algorithm described here came about when I visited Chandy, who was then at the University of Texas in Austin. He posed the problem to me over dinner, but we had both had too much wine to think about it right then. The next morning, in the shower, I came up with the solution. When I arrived at Chandy's office, he was waiting for me with the same solution.”

所以说,大神的世界我们不懂,一言不合就写一篇论文。我们言归正传,开始介绍论文中描述的算法。

分布式系统模型和状态定义

分布式系统模型

分布式系统是一个包含有限进程和有限消息通道的系统,这些进程和通道可以用一个有向图描述,其中节点表示进程,边表示通道。如下图所示:p、q分别是进程,c, c'则是消息通道。

distributed_system

另外为了问题描述的简洁,对上述模型还做了假设:消息通道只包含有限的buffer、消息保序、通道可靠等

分布式系统状态(State)

所谓的Distributed Snapshot,就是为了保存分布式系统的State,那么首先我们需要定义清楚什么是分布式系统的State。考虑到上述分布式模型的定义,分布式系统State同样是由“进程状态”和“通道状态”组成的。

  1. Event:分布式系统中发生的一个事件,在类似于Flink这样的分布式计算系统中从Source输入的新消息相当于一个事件。在论文中作者给出了数学化的定义,具体参考论文。
  2. 进程状态:包含一个初始状态(initial state),和持续发生的若干Events。初始状态可以理解为Flink中刚启动的计算节点,计算节点每处理一条Event,就转换到一个新的状态。
  3. 通道状态:我们用在通道上传输的消息(Event)来描述一个通道的状态。

在某一个时刻的某分布式系统的所有进程和所有通道状态的组合,就是这个分布式系统的全局状态。基于上述的双进程双通道的最简分布式系统,为了描述算法,作者设计了一个“单令牌状态”转换系统,两个进程通过接收和发出令牌,会在S0、S1两个State之间转换,整个分布式系统则会在如下所示的4种全局状态(Global State)之间转换。

process_state_transition

global_state_transition

Distributed Snapshots

有了系统状态和模型的定义,终于可以开始介绍分布式快照的算法了。对于一个分布式快照算法,我们有如下的两点要求:

  1. 正确性:能够准确的记录每一个进程、通道的状态,同时通过这些局部状态,能够准确表达一个分布式系统的全局状态。这里碰到的挑战是,每个进程、通道没法同时记录自身的状态,因为我们没有一个全局的时钟来保持状态记录的同步。
  2. 并行性:快照操作与分布式系统计算同时运行,但不能影响所有系统的正常功能,对性能、正确性等无影响。

按照上一小节的描述,全局状态是进程和通道状态的组合,在论文中,作者证明了通道状态可以通过记录进程状态来记录和恢复,并提出了下述的分布式snapshot算法:

对于进程p、q,p->q通过通道c连接,通过以下步骤记录global state

// 进程p行为,通过向q发出Marker,发起snapshot
begin
       p record its state;
then
       send one Marker along c after p records its state and before p sends further messages along c
end

//进程q接受Marker后的行为,q记录自身状态,并记录通道c的状态
if q has not recorded its state then
        begin
              q records its state;
              q records the state c as the empty sequence
        end
else q records the state of c as the sequence of messages received along c after q’s state was recorded and before q received the marker along c. 

进程p启动这个算法,记录自身状态,并发出Marker。随着Marker不断的沿着分布式系统的相连通道逐渐传输到所有的进程,所有的进程都会执行算法以记录自身状态和入射通道的状态,待到所有进程执行完该算法,一个分布式Snapshot就完成了记录。Marker相当于是一个信使,它随着消息流流经所有的进程,通知每个进程记录自身状态。且Marker对整个分布式系统的计算过程没有任何影响。只要保证Marker能在有限时间内通过通道传输到进程,每个进程能够在有限时间内完成自身状态的记录,这个算法就能在有限的时间内执行完成。

以上就是这个算法的最主要内容,算法本身不是很复杂,但是Chandy和Lamport两位大神在论文中展现的对问题分析和思考的过程真的很值得玩味,定义问题->定义分布式模型->推导算法->分析特例->证明算法的完备性,层层推进,环环相扣,缺一不可,算法的数学之美展露无遗!

关于Chandy-Lamport Algorithm的主要介绍就到这里,论文中还有一些关于某些特殊情况的证明,大家有兴趣可以参考论文。

Flink Checkpointing的实现原理

Flink 分布式Checkpointing是通过Asynchronous Barrier Snapshots的算法实现的,该算法借鉴了Chandy-Lamport算法的主要思想,同时做了一些改进,这些改进在论文"Lightweight Asynchronous Snapshots for Distributed Dataflows"中进行了详尽的描述,结合这篇论文,我们来看看具体的实现。

Flink流式计算模型

Flink流式计算模型中包含Source Operator、Transformation Operators、Sink Operator等三种不同类型的节点如下图所示,分别负责数据的输入、处理、和输出,对应计算拓扑的起点、中间节点和终点。计算模型的介绍不是我们的重点,细节请参考官方文档-Concepts
Flink_module

Asynchronous Barrier Snapshots

这个算法基本上是Chandy-Lamport算法的变体,只在执行上有一些差别。论文中分别针对有向无环和有向有环的两种计算拓扑图,提出了两种不同的算法,其中后者是在前者的基础上进行了修改,在实际的使用中,绝大部分的系统都是有向无环图,因此我们只会针对前者进行介绍。

在ABS算法中用Barrier代替了C-L算法中的Marker,针对DAG的ABS算法执行流程如下所示:

  1. Barrier周期性的被注入到所有的Source中,Source节点看到Barrier后,会立即记录自己的状态,然后将Barrier发送到Transformation Operator。

  2. 当Transformation Operator从某个input channel收到Barrier后,它会立刻Block住这条通道,直到所有的input channel都收到Barrier,此时该Operator就会记录自身状态,并向自己的所有output channel广播Barrier。

  3. Sink接受Barrier的操作流程与Transformation Oper一样。当所有的Barrier都到达Sink之后,并且所有的Sink也完成了Checkpoint,这一轮Snapshot就完成了。

下面这个图展示了一个ABS算法的执行过程:
ABS_DAG_Algo

下面是针对DAG拓扑图的算法伪代码:

// 初始化Operator
upon event (Init | input channels, output
channels, fun, init state) 
do
    state := init_state; 
    blocked_inputs := {};
    inputs := input_channels;
    out_puts := out_put channels; 
    udf := fun;

// 收到Barrier的行为
upon event (receive | input, (barrier)) 
do
//将当前input通道加入blocked 集合,并block该通道,此通道的消息处理暂停
    if input != Nil then 
        blocked inputs := blocked inputs ∪ {input};
        trigger (block | input);
//如果所有的通道都已经被block,说明所有的barrier都已经收到
    if blocked inputs = inputs then 
        blocked inputs := {}; 
        broadcast (send | outputs, (barrier)); //向所有的outputs发出Barrier
        trigger (snapshot | state); //记录本节点当前状态
        for each inputs as input //解除所有通道的block,继续处理消息
            trigger (unblock | input);

在这个算法中Block Input实际上是有负面效果的,一旦某个input channel发生延迟,Barrier迟迟未到,这会导致Transformation Operator上的其它通道全部堵塞,系统吞吐大幅下降。但是这么做的一个最大的好处就是能够实现Exactly Once。我们来看看Flink文档中的描述:

When the alignment is skipped, an operator keeps processing all inputs, even after some checkpoint barriers for checkpoint n arrived. That way, the operator also processes elements that belong to checkpoint n+1 before the state snapshot for checkpoint n was taken. On a restore, these records will occur as duplicates, because they are both included in the state snapshot of checkpoint n, and will be replayed as part of the data after checkpoint n.

不过Flink还是提供了选项,可以关闭Exactly once并仅保留at least once,以提供最大限度的吞吐能力。

本文仅从原理角度介绍了分布式Snapshot的基本原理以及Flink中的实现,从这篇文章出发,我们还需要阅读相关的源代码以及在实际的开发中去学习和理解。另外本文是基于我自己的理解写就,难免有疏漏和错误,如果大家发现问题,可以留言或者直接联系我,我们一起讨论。

相关实践学习
基于Hologres+Flink搭建GitHub实时数据大屏
通过使用Flink、Hologres构建实时数仓,并通过Hologres对接BI分析工具(以DataV为例),实现海量数据实时分析.
实时计算 Flink 实战课程
如何使用实时计算 Flink 搞定数据处理难题?实时计算 Flink 极客训练营产品、技术专家齐上阵,从开源 Flink功能介绍到实时计算 Flink 优势详解,现场实操,5天即可上手! 欢迎开通实时计算 Flink 版: https://cn.aliyun.com/product/bigdata/sc Flink Forward Asia 介绍: Flink Forward 是由 Apache 官方授权,Apache Flink Community China 支持的会议,通过参会不仅可以了解到 Flink 社区的最新动态和发展计划,还可以了解到国内外一线大厂围绕 Flink 生态的生产实践经验,是 Flink 开发者和使用者不可错过的盛会。 去年经过品牌升级后的 Flink Forward Asia 吸引了超过2000人线下参与,一举成为国内最大的 Apache 顶级项目会议。结合2020年的特殊情况,Flink Forward Asia 2020 将在12月26日以线上峰会的形式与大家见面。
相关文章
|
4月前
|
消息中间件 运维 Kafka
直播预告|Kafka+Flink双引擎实战:手把手带你搭建分布式实时分析平台!
在数字化转型中,企业亟需从海量数据中快速提取价值并转化为业务增长动力。5月15日19:00-21:00,阿里云三位技术专家将讲解Kafka与Flink的强强联合方案,帮助企业零门槛构建分布式实时分析平台。此组合广泛应用于实时风控、用户行为追踪等场景,具备高吞吐、弹性扩缩容及亚秒级响应优势。直播适合初学者、开发者和数据工程师,参与还有机会领取定制好礼!扫描海报二维码或点击链接预约直播:[https://developer.aliyun.com/live/255088](https://developer.aliyun.com/live/255088)
324 35
直播预告|Kafka+Flink双引擎实战:手把手带你搭建分布式实时分析平台!
|
4月前
|
消息中间件 运维 Kafka
直播预告|Kafka+Flink 双引擎实战:手把手带你搭建分布式实时分析平台!
直播预告|Kafka+Flink 双引擎实战:手把手带你搭建分布式实时分析平台!
155 11
|
11月前
|
存储 缓存 算法
分布式锁服务深度解析:以Apache Flink的Checkpointing机制为例
【10月更文挑战第7天】在分布式系统中,多个进程或节点可能需要同时访问和操作共享资源。为了确保数据的一致性和系统的稳定性,我们需要一种机制来协调这些进程或节点的访问,避免并发冲突和竞态条件。分布式锁服务正是为此而生的一种解决方案。它通过在网络环境中实现锁机制,确保同一时间只有一个进程或节点能够访问和操作共享资源。
391 3
|
11月前
|
SQL 关系型数据库 分布式数据库
Citus 简介,将 Postgres 转换为分布式数据库
【10月更文挑战第4天】Citus 简介,将 Postgres 转换为分布式数据库
288 4
|
11月前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
265 4
|
11月前
|
存储 SQL 消息中间件
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
149 0
|
存储 Java 流计算
Flink 分布式快照,神秘机制背后究竟隐藏着怎样的惊人奥秘?快来一探究竟!
【8月更文挑战第26天】Flink是一款开源框架,支持有状态流处理与批处理任务。其核心功能之一为分布式快照,通过“检查点(Checkpoint)”机制确保系统能在故障发生时从最近的一致性状态恢复,实现可靠容错。Flink通过JobManager触发检查点,各节点暂停接收新数据并保存当前状态至稳定存储(如HDFS)。采用“异步屏障快照(Asynchronous Barrier Snapshotting)”技术,插入特殊标记“屏障(Barrier)”随数据流传播,在不影响整体流程的同时高效完成状态保存。例如可在Flink中设置每1000毫秒进行一次检查点并指定存储位置。
303 0
|
26天前
|
存储 负载均衡 NoSQL
【赵渝强老师】Redis Cluster分布式集群
Redis Cluster是Redis的分布式存储解决方案,通过哈希槽(slot)实现数据分片,支持水平扩展,具备高可用性和负载均衡能力,适用于大规模数据场景。
135 2
|
2月前
|
存储 缓存 NoSQL
Redis核心数据结构与分布式锁实现详解
Redis 是高性能键值数据库,支持多种数据结构,如字符串、列表、集合、哈希、有序集合等,广泛用于缓存、消息队列和实时数据处理。本文详解其核心数据结构及分布式锁实现,帮助开发者提升系统性能与并发控制能力。
|
6月前
|
数据采集 存储 数据可视化
分布式爬虫框架Scrapy-Redis实战指南
本文介绍如何使用Scrapy-Redis构建分布式爬虫系统,采集携程平台上热门城市的酒店价格与评价信息。通过代理IP、Cookie和User-Agent设置规避反爬策略,实现高效数据抓取。结合价格动态趋势分析,助力酒店业优化市场策略、提升服务质量。技术架构涵盖Scrapy-Redis核心调度、代理中间件及数据解析存储,提供完整的技术路线图与代码示例。
573 0
分布式爬虫框架Scrapy-Redis实战指南

相关产品

  • 实时计算 Flink版