Flink 系列第8篇:Flink Checkpoint 全解析(原理+流程+配置+优化)

Flink Barrier与Checkpoint机制深度解析:从原理到Exactly-Once实战 在分布式流处理系统中,容错与状态一致性是保障数据准确性的基石。其核心原理在于通过分布式快照技术,在不停机的情况下捕获应用全局一致性状态。这一技术通过轻量级的控制信号(Barrier)在数据流中传播,精准触发各计算节点的状态持久化,从而在故障时能精准回溯与恢复,确保每条数据对状态的影响只生效一次,实现高效的容错。该机制对金融交易、实时风控等高要求场景至关重要,能有效解决作业恢复慢、状态膨胀及反压等工程难题。本文将以Apache Flink的Barrier与Checkpoint机制为例,深入剖析其如何保障流处理 阅读详情

一、数据处理语义

流处理引擎通常为用户的应用程序提供三种数据处理语义,核心差异在于数据处理的重复度和准确性,具体如下:

  • 最多一次(At-Most-Once):用户的数据只会被处理一次,无论处理成功与否,都不会重试、不会重发。适用于对数据准确性要求极低的场景(如非核心日志统计),优势是处理速度快、无冗余。

  • 至少一次(At-Least-Once):保证数据或事件至少被处理一次。若中间发生错误、数据丢失,会从源头重新发送数据进入处理系统,因此同一事件可能被重复处理。适用于允许少量重复、但不允许数据丢失的场景(如普通消息推送)。

  • 精确一次(Exactly-Once):每一条数据只会被精确处理一次,不多也不少。是最严格的语义,适用于对数据准确性要求极高的场景(如金融交易、计费统计)。

1.1 端到端(End to End)的精确一次

端到端的精确一次,指的是 Flink 应用从 Source 端(数据入口)开始到 Sink 端(数据出口)结束,整个链路的数据都能保证精确一次处理,核心注意点:

  • Flink 自身仅能保证内部处理的精确一次,无法直接保证外部系统(如 Kafka、数据库、文件系统)的“精确一次”语义;

  • 要实现端到端精确一次,需满足两个条件:外部系统必须支持精确一次语义,同时借助 Flink 提供的分布式快照和两阶段提交机制协同实现。

二、分布式快照理论

2.1 定义

分布式快照(Distributed Snapshot)是指在分布式系统中,捕获所有参与进程的本地状态,以及进程之间通道(channel)状态的全局一致状态。

其核心作用是记录分布式系统在某个时间点的全局状态,该状态包含两部分:每个进程的本地状态(如算子的中间计算结果)和通道中的消息状态(如正在传输中的数据)。

类比理解:给正在进行的马拉松比赛拍一张全局全景照片,要求照片能精确反映某个瞬间所有选手的位置和状态,且比赛不能停止、相机快门速度有限——分布式快照就是在不中断系统运行的前提下,捕捉到一致的全局状态。

2.2 Chandy-Lamport算法(经典理论模型)

Chandy-Lamport算法是分布式快照的理论基石,Flink 的 Checkpoint 机制直接受其启发。该算法由 K. Mani Chandy 和 Leslie Lamport 在1985年提出,核心优势是不停止系统运行,就能获取一致的全局快照。

2.2.1 关键概念

  • 标记消息(Marker):特殊的控制消息,用于划分快照边界,标记“属于当前快照的数据”和“属于下一个快照的数据”;

  • 进程状态:每个计算节点(如 Flink 的 TaskManager)的内存状态,对应 Flink 算子的本地状态;

  • 通道状态:节点之间传输中的消息集合,对应 Flink 数据流中未被算子处理的缓冲消息。

2.2.2 原理及步骤

该算法的核心思想是:通过插入标记消息(marker)来划分快照的边界,具体步骤如下:

  1. 初始化:任意一个进程发起快照,首先记录自身的本地状态,然后向所有输出通道发送 Marker 消息;

  2. 传播:当某个进程首次收到 Marker 消息时,执行三个操作:① 记录自身的本地状态;② 标记该输入通道为空(后续该通道的消息将被记录为下一个快照的内容);③ 向所有输出通道发送 Marker 消息;

  3. 终止:当所有进程都收到 Marker 消息并完成本地状态记录后,全局一致的快照捕获完成。

此时得到的全局快照,对应分布式系统的一个一致割集(consistent cut),即快照中每个进程的状态和消息,都反映了某个全局一致的时间点状态。

2.2.3 一致性保证的关键特性

特性说明
因果一致性如果事件 e 在快照中,则 e 的所有因果前驱事件也必须在快照中(确保状态不出现“断连”)
非侵入性无需停止系统运行即可捕获快照,不影响业务正常处理
异步性各节点可独立记录状态,不需要全局时钟同步,降低分布式系统的协调成本

三、Flink Checkpoint 机制

3.1 Checkpoint 简介

Flink 的 Checkpoint(检查点)是基于分布式快照的概念实现的,其核心作用是:

  • 定期为所有算子的状态创建一致性快照,并将快照持久化存储(如分布式文件系统、本地磁盘);

  • 当系统发生故障(如节点宕机、任务失败)时,Flink 可将任务恢复到最近一次成功快照的状态,避免数据丢失和重复计算;

  • 通常所说的“做 Checkpoint”,就是指触发一次分布式快照,将当前所有算子的状态保存下来。

注:本文后续源码及机制分析基于 Flink 1.17 版本。

3.2 核心概念:Barrier(数据栅栏/屏障)

3.2.1 定义

Barrier 是 Flink 实现 Checkpoint 的核心载体,本质是数据流中一种特殊的标记,由 Source 节点定期插入到数据流中。

每个 Barrier 都带有一个唯一的检查点 ID,将数据流划分为两个明确的部分:

  • 属于当前检查点的数据:在 Barrier 之前的数据流;

  • 属于下一个检查点的数据:在 Barrier 之后的数据流。

3.2.2 Barrier 对象源码

// flink-runtime/src/main/java/org/apache/flink/streaming/runtime/io/checkpointing/CheckpointBarrier.java
public class CheckpointBarrier implements CheckpointBarrierHandler.Event {
    private final long id;                    // Checkpoint ID(唯一标识)
    private final long timestamp;             // Barrier 创建时间戳
    private final CheckpointOptions options;  // Checkpoint 配置选项
    private final boolean isExactlyOnceMode;  // 是否启用精确一次语义标志
}

3.2.3 Barrier 携带信息

  • Checkpoint ID:唯一标识当前检查点,用于区分不同的快照;

  • 是否是 Exactly-Once 的标志:标记当前检查点对应的语义类型;

  • 创建时间:记录 Barrier 生成的时间,用于后续快照生命周期管理;

  • Checkpoint 选项:包含检查点的存储路径、超时时间等配置。

3.2.4 Barrier 工作原理

Barrier 的核心工作流程是“注入-传播-触发快照”,具体如下:

  1. Flink 的检查点协调者(JobManager 中的组件)定期触发检查点;

  2. Source 节点接收到触发指令后,生成对应 ID 的 Barrier,并将其插入到数据流中;

  3. Barrier 随着数据流向下游所有算子传递,传递过程中触发每个算子执行状态快照;

  4. 当所有算子都完成快照并确认后,当前检查点全局完成。

3.2.5 Barrier 插入时机

Barrier 由 Source 算子定期注入,注入频率由 Checkpoint 的间隔时间决定,核心逻辑在 SourceFunction 接口中,由 JobManager 通过 RPC 触发:

// flink-streaming-java/src/main/java/org/apache/flink/streaming/api/functions/source/SourceFunction.java
// Source算子周期性地注入Barrier
public interface SourceFunction<T> {
    // JobManager通过RPC触发Source创建Barrier
    // CheckpointCoordinator → TaskManager → SourceTask
}

3.2.6 Barrier 的处理

Barrier 在 DAG 图中的传播路径如下(以简单拓扑为例):

 Source1 → Map → KeyBy → Window → Sink
  │         │       │        │      │
Barrier→ Barrier→ Barrier→ Barrier→ Barrier
  │         │       │        │      │
  ↓         ↓       ↓        ↓      ↓
 JobManager收集所有Task的确认

Flink 中由 CheckpointBarrierHandler 负责处理 Barrier,有两种核心实现,对应不同的处理语义:

  • BarrierBuffer:用于 Exactly-Once 语义,会缓存“快流”(先收到 Barrier 的通道)的后续数据,等待“慢流”(未收到 Barrier 的通道),实现多流对齐;

  • BarrierTracker:用于 At-Least-Once 语义,不缓存数据,收到 Barrier 后仅记录,继续处理后续数据,不进行多流对齐。

3.3 协调者(Checkpoint Coordinator)

协调者(Checkpoint Coordinator)是 JobManager 中的核心组件,负责整个 Checkpoint 过程的发起、协调和确认,核心职责如下:

  1. 发起快照:定期(如每 10 秒)向所有 Source 任务发送指令,通知其“开始做快照 N,请注入 Barrier N”;

  2. 收集确认:等待所有任务(最终需所有 Sink 任务)报告“快照 N 已完成”,接收各任务返回的快照句柄(指向持久化状态的指针);

  3. 最终确认:收到所有任务的确认后,将本次快照标记为全局完成,并(可选)通知各任务清理旧的快照(避免存储冗余)。

四、Flink Checkpoint 工作流程

Flink Checkpoint 的工作流程核心差异在于“语义类型”,分别对应 Exactly-Once 和 At-Least-Once 两种场景,以下详细拆解。

4.1 Exactly-Once 语义

Exactly-Once 语义的核心处理关键点:多流对齐,快流等慢流,快流缓存数据——通过多流对齐确保所有通道的 Barrier 都到达后,再触发快照,避免数据重复或丢失。

4.1.1 场景假设

假设 Flink 作业拓扑结构如下(双流输入,模拟真实业务中的多源数据处理):

SourceA−> Union−>Map−>KeyBy−>Reduce−>SinkSourceB−>/SourceA -> \ Union -> Map -> KeyBy -> Reduce -> Sink SourceB -> /SourceA−> Union−>Map−>KeyBy−>Reduce−>SinkSourceB−>/

数据流时间线及分配(模拟两通道数据异步到达):

 时间轴:    t1    t2    t3    t4               t5    t6    t7              t8
数据流:    [ea1] [eb1] [ea2] [BarrierA(id=1)] [eb2] [ea3] [BarrierB(id=1)] [eb3]
输入通道:    A     B     A       A             B     A        B             B

4.1.2 算子行为分析

各算子在 Exactly-Once 语义下的核心行为的如下:

  1. SourceA 和 SourceB:分别产生数据,在 Checkpoint 触发时,注入对应 ID 的 Barrier;

  2. Union 算子:合并两个通道的数据流,将数据和 Barrier 一并转发给下游 Map 算子;

  3. Map 算子:接收数据和 Barrier,处理数据并触发快照(核心对齐逻辑);

  4. KeyBy 算子:仅负责数据分区,将数据按 key 发送到下游 Reduce 算子,自身不维护状态,不做快照,仅转发 Barrier;

  5. Reduce 算子:有状态算子,收到 Barrier 后进行多流对齐,完成自身状态快照;

  6. Sink 算子:有状态算子,收到 Barrier 后完成快照,若需端到端精确一次,还需执行两阶段提交的预提交操作。

4.1.3 Map 算子处理时间线分析

Map 算子作为有状态算子,其 Barrier 处理和快照触发逻辑最具代表性,具体时间线如下:

  1. t1:收到 ea1 → 处理 ea1,输出 transformed(ea1),发送给 KeyBy 算子;

  2. t2:收到 eb1 → 处理 eb1,输出 transformed(eb1),发送给 KeyBy 算子;

  3. t3:收到 ea2 → 处理 ea2,输出 transformed(ea2),发送给 KeyBy 算子;

  4. t4:收到 barrierA(id=1) → ① 开始对齐检查点1,等待来自通道 B 的 Barrier(id=1);② 暂停处理来自通道 A 的后续数据(ea3 会被缓冲);③ 未收到所有输入通道 Barrier 前,不向下游转发 Barrier;

  5. t5:收到 eb2 → 处理 eb2,输出 transformed(eb2),发送给 KeyBy 算子(eb2 是 BarrierB 之前的数据,正常处理);

  6. t6:收到 ea3 → 被缓存,不处理(通道 A 的 Barrier 已到达,后续数据需缓存等待对齐);

  7. t7:收到 barrierB(id=1) → ① 所有输入通道 Barrier 到达,对齐完成;② 向下游 KeyBy 算子转发 Barrier(id=1)(表示所有属于快照1的数据已处理完毕);③ 处理缓存的数据(ea3),恢复后续数据处理;

  8. t8:收到 eb3 → 处理 eb3,输出 transformed(eb3),发送给 KeyBy 算子(Barrier 已转发,后续数据正常处理)。

4.1.4 KeyBy 算子处理分析

KeyBy 算子的核心作用是数据分区,其 Barrier 处理逻辑简单:

  • 自身不维护状态,因此不做状态快照;

  • 将 Barrier 广播到所有下游任务(与数据分区不同:数据按 key 分组发送,Barrier 需广播,确保所有下游任务都能触发快照)。

4.1.5 Reduce 算子处理分析

Reduce 算子是有状态算子,其处理逻辑与 Map 算子一致:

  • 收到 Barrier 后,先进行多流对齐(等待所有输入通道的 Barrier 到达);

  • 对齐完成后,触发自身状态快照(记录每个 key 的聚合结果、Key Group 划分信息等);

  • 向 downstream 转发 Barrier,恢复数据处理。

4.1.6 Sink 算子处理分析

Sink 算子是数据流的出口,其处理逻辑直接影响端到端语义:

  • 收到 Barrier 后,先进行多流对齐,完成自身状态快照;

  • 若需实现端到端 Exactly-Once,需在快照时执行两阶段提交的第一阶段(预提交),将数据写入临时位置(不可见);

  • 等待 JobManager 确认全局快照完成后,执行第二阶段(提交),将数据写入最终位置(可见)。

4.1.7 算子快照内容分析

不同算子的快照内容不同,核心是“记录 Barrier 之前的所有状态”,具体如下:

  • Source 算子:记录当前读取的位置(如 Kafka 的 offset)。例如,SourceA 快照记录读到 ea2 之后的位置,SourceB 记录读到 eb2 之后的位置;

  • Map 算子:若有状态(如计数器),快照内容为 Barrier 之前所有数据处理后的状态(如 count=4,对应 ea1、eb1、ea2、eb2);无状态则不记录额外内容;

  • Reduce 算子:记录每个 key 的聚合状态、Key Group 划分信息、序列化的状态数据等(基于 Barrier 之前的所有数据);

  • Sink 算子:记录已写入外部系统的状态(如 Kafka 事务 ID、临时文件路径),若为两阶段提交,还会记录预提交的事务状态。

4.1.8 全局一致快照

全局一致快照是 Checkpoint 的最终成果,由 JobManager 统一收集和管理,核心内容包括:

  • Checkpoint ID:唯一标识当前快照;

  • 所有算子的状态句柄:包括算子 ID、状态大小、状态数据位置(文件路径 + 偏移量)、对应 Checkpoint ID;

  • 元数据:快照创建时间戳、Checkpoint 配置(如间隔、超时时间)等。

以检查点1为例,其全局一致性状态需满足:所有算子的快照都基于 BarrierA 和 BarrierB 之前的所有数据(ea1、eb1、ea2、eb2),确保恢复后的数据处理逻辑一致。

4.1.9 故障恢复

当系统发生故障时,Flink 从 Checkpoint 恢复的流程如下:

  1. JobManager 获取最近一次完成的 Checkpoint 状态(全局快照);

  2. 将每个算子的状态句柄分发给对应的 TaskManager,算子从持久化存储中读取状态数据并恢复:

    • Source 算子:重置到快照中记录的 offset(如 SourceA 从 ea3 开始重放,SourceB 从 eb3 开始重放);

    • Map 算子:恢复状态(如 count=4);

    • Reduce 算子:恢复每个 key 的聚合状态;

    • Sink 算子:恢复预提交的事务状态,等待后续提交或回滚。

  3. 所有算子恢复完成后,Source 算子开始重放 Barrier 之后的数据,作业恢复正常运行。

4.2 At-Least-Once 语义

At-Least-Once 语义的核心关键点:会进行 Barrier 对齐,但不会在等待对齐时缓存数据——因此可能出现“Barrier 之后的数据被提前处理”的情况,故障恢复时会重复处理部分数据。

4.2.1 场景假设

拓扑结构和数据流与 Exactly-Once 语义一致,仅算子处理逻辑不同。

4.2.2 算子行为分析

与 Exactly-Once 语义的核心差异在 Map 算子(有状态算子),其他算子行为基本一致:

  1. SourceA、SourceB、Union、KeyBy、Reduce、Sink 算子的核心职责不变;

  2. Map 算子:收到第一个 Barrier 时,不触发快照、不缓存数据,继续处理后续所有数据,直到所有输入通道的 Barrier 都到达后,才触发快照。

4.2.3 Map 算子处理时间线分析

  1. t1-t3:与 Exactly-Once 一致,处理 ea1、eb1、ea2 并转发;

  2. t4:收到 barrierA(id=1) → 记录 Barrier 到达,但不触发快照,继续处理后续数据;

  3. t5:收到 eb2 → 正常处理并转发;

  4. t6:收到 ea3 → 正常处理并转发(不缓存,与 Exactly-Once 核心差异);

  5. t7:收到 barrierB(id=1) → 所有 Barrier 到达,触发快照;

  6. t8:收到 eb3 → 正常处理并转发。

关键问题:快照触发时,ea3 已被处理并转发,若此时发生故障,恢复后 SourceA 会从 ea3 开始重放,导致 ea3 被重复处理——这也是 At-Least-Once 语义“允许重复”的核心原因。

4.2.4 全局快照内容分析

检查点1的全局状态与 Exactly-Once 存在差异,核心是“包含部分 Barrier 之后的数据”:

  • SourceA 状态:读取到 ea2(包含);

  • SourceB 状态:读取到 eb2(包含);

  • Map 状态:已处理 ea1、eb1、ea2、eb2、ea3,状态计数为 5;

  • Reduce 状态:聚合了上述 5 条数据的结果;

  • Sink 状态:已写入上述 5 条数据的处理结果。

4.2.5 故障恢复

恢复流程与 Exactly-Once 基本一致,但存在数据重复处理:

  • 故障前已处理:ea1、eb1、ea2、eb2、ea3;

  • 恢复后,SourceA 从 ea3 开始重放,SourceB 从 eb3 开始重放;

  • ea3 会被重复处理,因此最终 Sink 端会出现 ea3 的重复数据。

4.3 Exactly-Once 和 At-Least-Once 的区别

两者的核心区别在于:数据是否在 Barrier 对齐期间被缓存,具体对比如下:

  • 相同点:两者都会等待所有输入通道的 Barrier 到达后,才触发快照;

  • 不同点:

    • Exactly-Once(使用 BarrierBuffer):收到第一个 Barrier 后,缓存该通道后续数据,对齐完成后释放缓存,无重复数据;

    • At-Least-Once(使用 BarrierTracker):收到 Barrier 后仅记录,不缓存数据,继续处理所有数据,可能出现重复处理。

五、两阶段提交协议与 Exactly-Once 语义

Flink 内部的 Checkpoint 仅能保证“内部处理的精确一次”,要实现端到端的 Exactly-Once,必须结合两阶段提交协议(2PC),确保外部系统的写入操作也能满足原子性。

5.1 两阶段提交协议(2PC)概述

两阶段提交协议(Two Phase Commit,简称 2PC)是一种分布式一致性协议,核心作用是确保分布式系统中所有参与者(如 Flink 算子、外部数据库)对事务的提交或中止达成一致决定,避免出现“部分提交、部分未提交”的不一致状态。

在 Flink 中,2PC 用于确保:Checkpoint 完成时,所有算子对外部系统的写入操作要么全部提交,要么全部回滚,从而实现端到端的 Exactly-Once 语义。

5.1.1 协议的两个阶段

阶段1:准备阶段(投票阶段)
  1. 协调者(Flink 的 JobManager)询问所有参与者(如 Sink 算子)是否可以提交事务;

  2. 参与者执行事务操作(如将数据写入临时位置),但不正式提交;

  3. 参与者向协调者回复“同意提交”或“拒绝提交”(若执行失败则拒绝)。

阶段2:提交阶段(执行阶段)
  1. 若所有参与者都回复“同意提交”,协调者向所有参与者发送“正式提交”指令;

  2. 参与者收到指令后,正式提交事务(如将临时数据移动到最终位置);

  3. 参与者向协调者回复“提交完成”,事务结束。

补充:若有任意一个参与者回复“拒绝提交”,协调者会向所有参与者发送“中止”指令,所有参与者回滚已执行的操作,事务中止。

5.1.2 2PC 的 ACID 数据保证

  • 原子性(Atomicity):所有参与者要么都提交事务,要么都回滚,不存在部分提交的情况(2PC 最核心的保证);

  • 一致性(Consistency):事务执行后,分布式系统从一个一致状态转换到另一个一致状态(如数据不丢失、不重复);

  • 隔离性(Isolation):2PC 本身不直接保证隔离性,需依赖底层系统(如数据库、Kafka)的隔离机制;

  • 持久性(Durability):事务一旦提交,更改会永久保存,即使系统发生故障也不会丢失。

5.2 2PC 在 Flink 中的实现

Flink 中将两阶段提交的逻辑封装到了 TwoPhaseCommitSinkFunction 抽象类中,开发者只需实现该类中的 4 个核心方法,即可实现端到端的 Exactly-Once 语义,具体方法如下:

  • beginTransaction:开启事务前,在外部系统的临时目录/临时空间创建资源(如临时文件、临时事务),后续数据写入该临时资源;

  • preCommit:预提交阶段,刷写缓冲区数据,关闭临时资源(不可再写入),并启动下一个检查点的新事务;

  • commit:正式提交阶段,将预提交的临时资源原子性移动到最终位置(如将临时文件重命名为正式文件),数据对外可见;

  • abort:中止阶段,删除临时资源,回滚已执行的操作。

注:2PC 需搭配支持事务的 Source 和 Sink(如 Kafka 0.11+ 版本),才能实现完整的端到端 Exactly-Once。

5.2.1 典型 Sink 的 2PC 实现示例

1. 文件 Sink
// flink-connectors/flink-connector-files/src/main/java/org/apache/flink/connector/file/sink/
public class FileSink<IN> implements TwoPhaseCommittingSink<IN, FileSinkCommittable> {
    
    // 阶段1:预提交(对应snapshotState)
    public List<FileSinkCommittable> prepareCommit() {
        // 1. 刷新所有缓冲区数据,确保数据写入临时文件
        // 2. 将临时文件从".in-progress"重命名为".pending"(不可再写入)
        // 3. 返回待提交的信息(不实际提交,数据仍不可见)
        return Collections.singletonList(new FileSinkCommittable(...));
    }
    
    // 阶段2:提交(对应notifyCheckpointComplete)
    public void commit(List<FileSinkCommittable> committables) {
        // 将".pending"后缀的临时文件,原子性重命名为最终文件名
        // 此时数据对用户可见,事务正式完成
        for (FileSinkCommittable committable : committables) {
            File pendingFile = new File(committable.getPendingPath());
            File finalFile = new File(committable.getFinalPath());
            pendingFile.renameTo(finalFile);
        }
    }
}
2. Kafka Sink
// flink-connectors/flink-connector-kafka/src/main/java/org/apache/flink/connector/kafka/sink/
public class KafkaWriter<IN> {
    
    private KafkaProducer<byte[], byte[]> producer;
    
    public List<KafkaCommittable> prepareCommit(boolean flush) {
        // 阶段1:预提交
        // 1. 刷新生产者缓冲区,确保数据写入Kafka事务
        producer.flush();
        
        // 2. 开启新事务,为下一个检查点做准备
        String newTransactionId = generateTransactionId(nextCheckpointId);
        producer.beginTransaction();
        
        // 3. 返回当前事务的可提交信息(此时事务未正式提交,数据不可见)
        return Collections.singletonList(
            new KafkaCommittable(producer, transactionId)
        );
    }
    
    public void commit(List<KafkaCommittable> committables) {
        // 阶段2:提交
        // 正式提交Kafka事务,数据对消费者可见
        for (KafkaCommittable committable : committables) {
            committable.getProducer().commitTransaction();
        }
    }
}
3. 数据库 Sink(如 JDBC)
public class JdbcSink<IN> {
    
    private Connection connection;
    private String transactionId;
    
    public List<JdbcCommittable> prepareCommit(boolean flush) {
        // 阶段1:预提交
        // 1. 执行所有INSERT/UPDATE语句(数据写入数据库,但未提交)
        // 2. 不执行connection.commit(),事务处于未提交状态
        // 3. 返回事务ID和连接信息,用于后续提交
        return Collections.singletonList(
            new JdbcCommittable(connection, transactionId)
        );
    }
    
    public void commit(List<JdbcCommittable> committables) {
        // 阶段2:提交
        // 正式提交数据库事务,数据永久生效
        for (JdbcCommittable committable : committables) {
            Connection conn = committable.getConnection();
            try {
                conn.commit();  // 正式提交事务
            } catch (SQLException e) {
                conn.rollback();  // 提交失败则回滚
                throw new RuntimeException("Commit failed", e);
            }
        }
    }
}

5.3 Exactly-Once 语义与两阶段提交的协同

5.3.1 Sink 算子内部结构

Flink 中执行 Sink 逻辑的核心算子是 StreamSinkOperator,其内部包含三个核心组件,用于协同实现 2PC:

// flink-streaming-java/src/main/java/org/apache/flink/streaming/api/operators/sink/
// StreamSinkOperator是执行Sink逻辑的算子
public class StreamSinkOperator<InputT> extends AbstractStreamOperator<Object>
    implements OneInputStreamOperator<InputT, Object> {
    
    private transient SinkWriter<InputT> sinkWriter;  // 负责数据写入(临时资源)
    private transient Committer<?> committer;          // 负责事务提交
    private transient ListState<byte[]> committerState;  // 存储待提交事务信息
    
    // 处理元素的核心方法
    public void processElement(StreamRecord<InputT> element) throws Exception {
        // 直接将数据写入SinkWriter(临时资源,未正式提交)
        sinkWriter.write(element.getValue(), context);
    }
}

5.3.2 Sink 算子与两阶段提交的协同流程

Sink 算子在 Barrier 对齐后,会与 Checkpoint 协同执行两阶段提交,核心分为两个步骤,分别对应 Checkpoint 的两个关键时机:

  1. 步骤1:Checkpoint 快照时,执行 2PC 第一阶段(预提交)

    • 对应 Sink 算子的 snapshotState() 方法;

    • 执行 sinkWriter.prepareCommit(),完成预提交(刷写缓冲区、关闭临时资源);

    • 将预提交信息(如临时文件路径、事务 ID)保存到 committerState(算子状态),相当于“投票同意提交”;

    • 此时数据仍在外部系统的临时位置,对用户不可见。

  2. 步骤2:全局快照完成后,执行 2PC 第二阶段(正式提交)

    • JobManager 确认所有算子都完成快照后,向所有 Sink 算子发送 notifyCheckpointComplete() 通知;

    • Sink 算子收到通知后,从 committerState 中读取预提交信息;

    • 执行 committer.commit(),完成正式提交(临时资源转正式资源);

    • 数据对外可见,事务完成。

5.3.3 协同流程源码示例

// flink-streaming-java/src/main/java/org/apache/flink/streaming/api/operators/sink/
public class StreamSinkOperator<InputT> extends AbstractStreamOperator<Object> {
    
    // ========== 阶段1: 在快照中预提交(2PC 准备阶段) ==========
    @Override
    public void snapshotState(StateSnapshotContext context) throws Exception {
        // 1. 执行预提交操作,获取待提交信息
        List<Committable> committables = sinkWriter.prepareCommit(false);
        
        // 2. 将预提交信息序列化后,保存到算子状态(相当于"投票")
        pendingCommits.add(serializeCommittables(committables));
        
        // 3. 此时数据处于预提交状态:文件在临时目录、Kafka事务未提交、数据库事务未提交
    }
    
    // ========== 阶段2: 在通知中完成提交(2PC 提交阶段) ==========
    @Override
    public void notifyCheckpointComplete(long checkpointId) throws Exception {
        // 1. 仅当全局快照完成后,才执行正式提交
        // 2. 从算子状态中读取当前检查点的预提交信息
        List<Committable> committables = getPendingCommits(checkpointId);
        
        // 3. 执行正式提交,数据对外可见
        committer.commit(committables);
    }
}

5.3.4 示例:双流输入的 Sink 算子 2PC 执行流程

基于前文的双流拓扑(SourceA、SourceB → Union → Sink),结合数据流时间线,Sink 算子的 2PC 执行流程如下:

  1. t1-t3:Sink 处理 ea1、eb1、ea2,将数据写入临时位置(不可见);

  2. t4:收到 BarrierA,开始 Barrier 对齐,继续处理后续数据;

  3. t5:处理 eb2,写入临时位置;

  4. t6:收到 ea3,因 Barrier 未对齐,缓存 ea3(不写入);

  5. t7:收到 BarrierB,对齐完成,触发 Checkpoint 快照:

    • 调用 snapshotState(),执行 prepareCommit(),预提交 ea1、eb1、ea2、eb2;

    • 预提交信息保存到 committerState;

    • 释放缓存的 ea3,继续处理并写入临时位置。

  6. t7 之后:JobManager 确认所有算子快照完成,发送 notifyCheckpointComplete(1);

  7. Sink 算子收到通知,执行commit(),将预提交的数据(ea1、eb1、ea2、eb2)移动到最终位置,对外可见。

六、At-Least-Once 语义下的 Sink 算子行为

6.1 核心特点:无需两阶段提交

At-Least-Once 语义允许数据重复处理,因此无需复杂的两阶段提交机制,Sink 算子的行为更简单:

  • 数据直接写入外部系统,无需临时资源,写入后立即对外可见;

  • 无需实现 TwoPhaseCommittingSink 接口,没有 prepareCommit 和 commit 的分离;

  • 快照仅记录当前的写入位置(如文件偏移量、Kafka offset),用于故障恢复时重放数据。

6.2 Sink 算子的快照实现

// 在AT-LEAST-ONCE下,Sink的快照通常很简单
public class SimpleSinkOperator<IN> extends AbstractStreamOperator<Object> {
    
    @Override
    public void snapshotState(StateSnapshotContext context) throws Exception {
        // 1. 刷新缓冲区,确保所有已处理的数据都写入外部系统(立即可见)
        // 2. 记录当前的写入位置(如文件路径+偏移量、Kafka offset)
        // 3. 无预提交阶段,数据已直接可见
        state.update(currentWritePosition);
    }
}

6.3 示例:At-Least-Once 语义下的 Sink 时间线

基于前文的数据流(ea1、eb1、ea2、barrierA、eb2、ea3、barrierB、eb3),Sink 算子的时间线如下:

  1. t1: 收到ea1(通道0) → 立即写入外部系统(可见);

  2. t2: 收到eb1(通道1) → 立即写入外部系统(可见);

  3. t3: 收到ea2(通道0) → 立即写入外部系统(可见);

  4. t4: 收到barrierA(通道0) → 记录通道0收到Barrier,不中断数据处理,继续监听其他通道;

  5. t5: 收到eb2(通道1) → 立即写入外部系统(可见);

  6. t6: 收到ea3(通道0) → 立即写入外部系统(可见);
    // 注意:在EXACTLY-ONCE下ea3会被缓冲,但At-Least-Once语义下直接处理,无缓存逻辑;

  7. t7: 收到barrierB(通道1) → 所有输入通道Barrier全部到齐,触发检查点1快照;
    → 调用Sink算子的snapshotState()方法;
    → 记录当前写入位置(如ea3、eb2的写入偏移量/ID),完成快照;

  8. t8: 收到eb3(通道1) → 立即写入外部系统(可见)。

七、Checkpoint 参数配置

默认情况下,Flink 的 Checkpoint 机制处于关闭状态,需在程序中手动开启并配置相关参数,以适配不同业务场景的需求。核心配置代码及说明如下:

// 1. 开启检查点机制,并指定检查点之间的时间间隔(单位:毫秒)
// 示例:每1000毫秒触发一次检查点
env.enableCheckpointing(1000); 

// 2. 可选配置:设置检查点语义(默认 Exactly-Once,可切换为 At-Least-Once)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);

// 3. 可选配置:设置两个检查点之间的最小时间间隔(避免检查点密集执行,单位:毫秒)
// 示例:两次检查点之间至少间隔500毫秒
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);

// 4. 可选配置:设置检查点执行超时时间(超时未完成则取消该次检查点,单位:毫秒)
// 示例:检查点执行超时时间为60000毫秒(1分钟)
env.getCheckpointConfig().setCheckpointTimeout(60000);

// 5. 可选配置:设置最大并发执行的检查点数量
// 示例:最多允许1个检查点并发执行(避免资源竞争)
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);

// 6. 可选配置:将检查点持久化到外部存储(避免集群重启后状态丢失)
// ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION:取消作业时保留检查点
// ExternalizedCheckpointCleanup.DELETE_ON_CANCELLATION:取消作业时删除检查点
env.getCheckpointConfig().enableExternalizedCheckpoints(
    ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);

// 7. 可选配置:恢复优先级(有更近的保存点时,优先回退到检查点)
env.getCheckpointConfig().setPreferCheckpointForRecovery(true);

八、Checkpoint 优化方案

8.1 异步存储(Asynchronous Snapshotting)

异步存储是指在触发状态快照时,不阻塞主线程的数据处理,将状态持久化的操作放到后台异步执行,核心目的是减少检查点对业务处理性能的影响。

8.1.1 工作原理

  • RocksDB状态后端的异步快照:
    ① 检查点触发时,RocksDB会创建一个数据库的一致视图(避免快照过程中数据被修改);
    ② 后台线程异步将RocksDB的SST文件复制到检查点存储目录;
    ③ 主线程无需等待存储完成,继续处理新的数据、写入新的MemTable,不影响吞吐和延迟。

  • 内存状态后端的异步快照:
    采用“写时复制”(Copy-On-Write)技术,快照时复制当前内存状态的副本,主线程继续修改原内存状态,副本异步写入持久化存储,避免阻塞。

8.1.2 核心优点

  • 高吞吐:数据处理不中断,主线程始终专注于业务计算;

  • 低延迟:Barrier传播、数据处理不受状态存储操作的影响;

  • 高资源利用率:CPU计算与I/O存储操作并行执行,充分利用集群资源。

8.2 增量存储(Incremental Checkpointing)

增量存储是指每次检查点仅保存自上一次检查点以来发生变化的状态部分,而非全量状态,适用于状态量大(如TB级)的场景,可大幅优化存储和传输开销。

8.2.1 核心对比(与完整存储)

假设一个作业有100GB的状态,完整存储与增量存储的差异如下:

  • 完整存储:每次检查点需保存100GB状态,网络传输100GB,存储占用为“检查点数量 × 100GB”,资源消耗巨大;

  • 增量存储:仅保存变化的状态(如10GB),网络传输和存储占用大幅降低,适合长期运行、状态持续增长的作业。

8.2.2 优点与挑战

  • 优点:
    ① 存储空间大幅减少(通常减少50%-90%);
    ② 检查点执行速度更快,复制和传输的数据量更少;
    ③ 对大型状态友好,可支撑TB级状态的高效快照。

  • 挑战:
    ① 依赖链管理:每个增量检查点依赖上一次的检查点(全量或增量),形成依赖链;
    ② 清理策略:需智能清理过期检查点,同时保留依赖链,避免恢复失败;
    ③ 恢复复杂度:恢复时需整合所有相关的增量检查点和基础全量检查点,重建完整状态。

8.2.3 工作原理(以RocksDB为例)

RocksDB采用LSM树(日志结构合并树)存储数据,天然适合增量存储:

检查点触发时,仅复制自上一次检查点以来新增或修改的SST文件,未变化的SST文件直接复用,无需重复存储和传输,大幅提升效率。

九、保存点机制(Savepoints)

保存点(Savepoints)是Checkpoint机制的特殊实现,核心作用是支持作业的计划维护(如集群升级、作业重构),通过手动触发的方式将状态持久化到指定路径,避免维护过程中状态丢失。

9.1 核心特性

  • 手动触发:需通过命令行或API手动触发,而非自动定期执行;

  • 持久化存储:状态保存到指定的外部存储路径,不会被Flink自动清理;

  • 标准化格式:状态格式统一,支持跨版本、跨作业的恢复(如作业拓扑微调后仍可恢复)。

9.2 常用命令示例

触发保存点并指定存储路径(Flink命令行):

# 语法:bin/flink savepoint <jobId> [<targetDirectory>]
# 示例:触发ID为abc123的作业的保存点,存储到/hdfs/flink/savepoints目录
bin/flink savepoint abc123 /hdfs/flink/savepoints

更多命令(如从保存点恢复作业、删除保存点)可参考Flink官方文档。

十、Checkpoint 与 Savepoint 对比

两者均用于状态持久化和故障恢复,但核心用途、触发方式等存在显著差异,具体对比如下:

特性Checkpoint(检查点)Savepoint(保存点)
核心目的容错恢复,应对系统故障(如节点宕机)计划维护、版本升级、作业重构
触发方式自动、定期(由配置的间隔时间控制)手动、按需(通过命令行/API触发)
生命周期临时状态,可被Flink自动清理(如超过保留数量)持久状态,直到手动删除
性能影响经过优化,对业务性能影响小可能影响性能(全量快照,无增量优化)
状态格式可能为Flink内部格式,不保证跨版本兼容统一标准化格式,支持跨版本、跨作业兼容
恢复灵活性仅支持同一作业的恢复(拓扑不变)可恢复为不同作业(拓扑微调后仍可恢复)
深入解析Flink Barrier与Checkpoint:原理、调优与生产实践 在分布式流处理系统中,容错机制是保障数据一致性与作业可靠性的核心基础。其原理通常基于分布式快照技术,通过在数据流中插入特殊标记(Barrier)来定义全局一致性点,协调所有并行任务同步冻结状态,从而实现故障后的精确恢复。这项技术的核心价值在于为实时计算提供了端到端的Exactly-Once语义保障,是构建高可靠数据流水线的关键技术。在实际应用场景中,理解Barrier的对齐机制、状态快照的持久化流程以及相关的性能调优参数,对于解决生产环境中的背压、Checkpoint超时、状态恢复异常等问题至关重要。本文聚 阅读详情

相关推荐

Flink Unaligned Checkpoint 原理与实战指南

Flink 的 Checkpoint 是保障流处理 Exactly-Once 语义的核心机制,而传统 aligned checkpoint 在高背压、网络抖动或 GC 暂停场景下易因全局对齐阻塞导致超时失败。Unaligned Checkpoint(UC)通过解耦 barrier 传播与状态快照、引入 in-flight 数据快照、分治式缓冲区管理等设计,在不牺牲一致性的前提下显著提升容错鲁棒性与恢复性能。其技术价值体现在降低 checkpoint 耗时、减少失败率、支持异构数据源混合拓扑等工程痛点,广泛应

weixin_34343000的博客 229

Flink Checkpoint 详解

阳阳阳的博客 8995

深入解析Flink Checkpoint机制:Aligned与Unaligned模式对比及性能优化

本文深入解析了Flink的两种核心容错机制:Aligned Checkpoint与Unaligned Checkpoint。通过对比其原理、性能开销及适用场景,为不同业务负载(如低延迟ETL与高反压窗口聚合)提供了明确的模式选择策略与配置优化指南,帮助开发者构建更稳定高效的实时计算系统。

s3t4u的博客 849

【Flink 基础篇】Flink 架构(五):检查点 Checkpoint(看完即懂)

本篇博客我们将介绍 Flink 的检查点(checkpoint)及故障恢复机制,看一下它们如何提供精确一次的状态一致性保障。而在下一篇博客中,我们还会讨论 Flink 所独有的保存点(savepoint)机制,它就像一把 “瑞士军刀”,解决了运行流式应用过程中的诸多难题。

Data · Model · Agent · Repeat 4215

flink重温笔记(十一):Flink 高级 API 开发——flink 四大基石之 Checkpoint(详解存储后端)

1- Flink 检查点机制,(协调者)定期在数据流上生成 checkpoint barrier;2- 当某个算子接收到barrier(数据栅栏) 时,会基于当前状态生成一份快照;3- 后将 barrier 传递给下游算子,依次快照并传递下去,直到 sink;4- 出现异常时,根据最近的快照数据,将所有算子恢复到之前状态;5-收到所有算子的报告后,才认为该周期快照成功。flink-conf.yaml 配置文件的 restart-strategy 配置参数决定重启策略。重启策略重启策略值。

m0_60732994的博客 2810

【信息科学与工程学】【物理/化学科学和工程技术】知识体系021 断裂力学03 极端制造与精密加工领域(原子级操控、缺陷物理、界面工程和系统级可靠性)

Flink的Checkpoint机制通过​​ 实现容错,确保Exactly-Once语义。

weixin_49199313的博客 1064

Flink 检查点(Checkpoint)

​ 发生故障之后怎么办?最简单的想法当然是重启机器、重启应用。这里的问题在于,流处理应用中的任务都是有状态的,而为了快速访问这些状态一般会直接放在堆内存里;现在重启应用,内存中的状态已经丢失,就意味着之前的计算全部白费了,需要从头来过。就像编写文档或是玩 RPG 游戏,因为宕机没保存而要重来一遍是一件令人崩溃的事情;所以就有了存档,这样即使遇到宕机也可以读档继续了。​ 在流处理中,我们同样可以用存档读档的思路,把之前的计算结果做个保存,这样重启之后就可以继续处理新数据、而不需要重新计算了。进一步地,我们

qq_42575907的博客 3606

手把手教你用示波器抓取MIPI D-PHY波形:从LP11到HS Burst的完整信号解析

本文详细介绍了使用示波器精准捕获MIPI D-PHY信号的关键技巧,包括探头选择、示波器参数设置、信号状态解析及高级触发配置。通过实战案例和波形分析,帮助工程师快速识别从LP11到HS Burst的各种信号状态,解决常见的信号完整性问题,提升调试效率。

weixin_30471561的博客 559

flink checkpoint 重启_Flink进阶教程:Checkpoint机制原理剖析与参数配置

在Flink状态管理详解:Keyed State和Operator List State深度解析这篇文章中,我们介绍了Flink的状态都是基于本地的,而Flink又是一个部署在多节点的分布式引擎,分布式系统经常出现进程被杀、节点宕机或网络中断等问题,那么本地的状态在遇到故障时如何保证不丢呢?Flink定期保存状态数据到存储上,故障发生后从之前的备份中恢复,整个被称为Checkpoint机制,它为F...

weixin_39542093的博客 579

ROS2与Gazebo协同实现多机器人避障仿真

本文详细介绍了如何利用ROS2与Gazebo协同搭建多机器人避障仿真环境。通过创建SDF机器人模型、编写多机器人启动文件以及集成基础避障算法,构建了一个低成本、高效率的虚拟测试平台,为AGV编队、机器人集群等项目的算法验证与迭代提供了完整解决方案。

weixin_29065659的博客 293

OpenClaw与Ollama本地AI部署指南

AI模型本地化部署是当前企业数字化转型的关键技术,通过开源框架Ollama可以在消费级硬件上运行大语言模型。本文以OpenClaw多智能体系统为例,详解从环境配置到模型优化的全流程实践,特别针对国内开发者遇到的网络问题提供了镜像加速等解决方案。这种私有化部署方案尤其适合金融数据分析、企业知识管理等对数据安全要求高的场景,通过模块化设计实现多智能体协作,同时保持对NVIDIA显卡和普通CPU的兼容性。

weixin_34302561的博客 395

flink checkpoint 恢复_Flink进阶教程:Checkpoint机制原理剖析与参数配置

在Flink状态管理详解:Keyed State和Operator List State深度解析这篇文章中,我们介绍了Flink的状态都是基于本地的,而Flink又是一个部署在多节点的分布式引擎,分布式系统经常出现进程被杀、节点宕机或网络中断等问题,那么本地的状态在遇到故障时如何保证不丢呢?Flink定期保存状态数据到存储上,故障发生后从之前的备份中恢复,整个被称为Checkpoint机制,它为F...

weixin_39735012的博客 626

别再手动测接口了!用Pytest+Requests+Allure搭建你的第一个自动化框架(附完整源码)

本文详细介绍了如何使用Pytest+Requests+Allure搭建Python接口自动化测试框架,涵盖环境准备、核心组件封装、测试用例设计、报告生成及CI/CD集成等关键步骤。通过实战案例和完整源码,帮助开发者快速构建高效的接口自动化测试解决方案,提升测试效率和质量。

weixin_42546508的博客 319

Flink CDC Checkpoint机制解析:保障数据一致性的关键

在实时数据同步场景中,你是否曾面临以下痛点:系统崩溃后数据丢失、上下游数据不一致、重复消费导致业务异常?Flink CDC(Change Data Capture,变更数据捕获)作为实时数据集成的核心工具,其Checkpoint(检查点)机制正是解决这些问题的关键技术。本文将深入解析Flink CDC Checkpoint机制的工作原理、实现细节及最佳实践,帮助你彻底掌握这一保障数据一致性的核心能...

gitblog_00308的博客 1338

Drupal远程代码执行漏洞(CVE-2018-7600)实战复现:从检测到写入WebShell的全过程

本文详细解析了Drupal远程代码执行漏洞(CVE-2018-7600)的实战复现过程,从环境搭建、漏洞检测到WebShell写入的全流程。该高危漏洞影响Drupal 6.x至8.x版本,允许攻击者未经授权执行任意代码。文章提供了多种POC构造方法和高级利用技巧,帮助安全研究人员深入理解漏洞原理并掌握验证技术。

weixin_29322553的博客 275

PRIDE PPP-AR软件实战:从ZTD解算到PWV反演的全流程避坑指南

本文详细解析了使用PRIDE PPP-AR软件进行GNSS数据处理的全流程,重点涵盖从ZTD解算到PWV反演的关键步骤与精度评估。文章深入剖析了软件部署、数据准备、参数配置中的常见“坑点”,并提供了与IGS ZTD及ERA5产品进行交叉验证的实用方法,旨在帮助用户高效、准确地获取高精度大气可降水量产品。

p8q9r0的博客 605

Flink容错机制:Checkpoint和Savepoint深入解析

当数据洪流日夜不息地奔涌,Savepoint 如同精密的“状态时间胶囊”,既守护历史状态的完整性,又为系统演进预留了灵活空间。它与 Checkpoint 的协同作用,构成了 Flink 容错体系的“双螺旋结构”——一个专注于保障系统的生存能力,另一个赋能业务的进化需求。在实时计算的复杂战场上,这种互补设计让开发者既能从容应对意外故障风暴,又能主动规划技术演进路线,真正实现了“既可靠的当下,又可进的未来”的流处理架构理想。

2501_93078354的博客 690

Solidworks二次开发(C# .NET API):从零构建装配体与虚拟零件

本文详细介绍了使用C#进行Solidworks二次开发,从零构建装配体与虚拟零件的完整流程。通过.NET API实现设计自动化,涵盖环境搭建、核心对象模型、虚拟零件创建与外部化保存等关键技术,帮助工程师将重复性建模工作程序化,大幅提升设计效率与标准化水平。

alice7model的博客 607

flink State 和 checkpoint,重启策略 原理详解

目录 前言 State keyed State 1.ValueState 2.ListState 3.MapState 4.ReducingState 5.AggregatingState 6.FoldingState Operator State 存储状态 MemoryStateBackend FsStateBackend RocksDBStateBackend 重启策略 checkpoint checkpoint配置 通过checkp...

weixin_40954192的博客 3370

ABAP CDS HAVING 全解析:聚合之后的精准过滤、最佳实践与可运行示例

摘要: 本文针对具备ABAP与CDS基础的开发者,详解HAVING在ABAP CDS中的核心用法。HAVING专用于过滤GROUP BY后的聚合结果(如SUM、COUNT),与WHERE的分工明确:前者处理聚合值,后者过滤原始记录。通过销售额阈值、质量分析、财务对账三类典型场景,结合性能优化建议(如优先使用WHERE索引过滤),说明实际应用。文中提供经典CDS View与View Entity两种实现代码,并附Open SQL消费示例,帮助开发者快速落地。常见误区(如聚合条件误写至WHERE)与规避方法亦被

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 218

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Flink Checkpoint机制原理剖析与参数配置

在Flink状态管理详解这篇文章中,我们介绍了Flink的状态都是基于本地的,而Flink又是一个部署在多节点的分布式引擎,分布式系统经常出现进程被杀、节点宕机或网络中断等问题,那么本地的状态在遇到故障时如何保证不丢呢?Flink定期保存状态数据到存储上,故障发生后从之前的备份中恢复,整个被称为Checkpoint机制,它为Flink提供了Exactly-Once的投递保障。本文将介绍Flink的Checkpoint机制的原理。本文会使用多个概念:快照(Snapshot)、分布式快照(Distributed

woliuqiangdong的博客 548

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Apache Flink Checkpoint并发控制:优化配置与性能影响分析

Apache Flink作为流处理领域的领军框架,其强大的容错机制Checkpoint机制确保了流处理作业的Exactly-Once语义。在实际生产环境中,Checkpoint的并发控制配置直接影响作业的性能和稳定性。本文将深入解析Flink Checkpoint并发控制的配置策略、性能影响及最佳实践。 ## 🔍 Checkpoint并发控制核心概念 在Apache Flink中,Check

gitblog_00668的博客 923

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Flink Checkpoint 全生命周期深度解析

Flink Checkpoint 机制深度解析 本文基于 Apache Paimon 源码,深入剖析 Flink Checkpoint 机制的全生命周期。主要内容包括: 核心原理:基于 Chandy-Lamport 算法的分布式快照机制,通过 Barrier 实现不阻塞数据流的一致性快照 架构设计: Checkpoint Coordinator 负责协调检查点流程 TaskManager 执行本地状态快照 状态后端提供存储支持(Memory/Fs/RocksDB) 关键流程: Barrier 的产生与传播

zhangkaixuan456的博客 1148

Flink CheckPoint奇技淫巧 | 原理和在生产中的应用

简介 Flink本身为了保证其高可用的特性,以及保证作用的Exactly Once的快速恢复,进而提供了一套强大的Checkpoint机制。 Checkpoint机制是Flink可靠性的基石,可以保证Flink集群在某个算子因为某些原因(如异常退出)出现故障时,能够将整个应用流图的状态恢复到故障之前的某一状态,保 证应用流图状态的一致性。Flink的Checkpoint机制原理来自“Ch...

weixin_30726161的博客 645

Flink Unaligned Checkpoint原理与生产实践

Flink Checkpoint是流处理状态容错的核心机制,其对齐(Aligned)模式依赖Barrier全局同步,易受反压和网络抖动影响,导致端到端延迟飙升与checkpoint超时。Unaligned Checkpoint通过Barrier穿透、in-flight数据快照和异步记账机制,打破同步等待瓶颈,在高吞吐、长反压、多分支拓扑场景下显著提升一致性保障能力与恢复可靠性。该技术深度耦合Flink Runtime底层重构(如FLIP-147缓冲管理、FLIP-159异步协调器),需RocksDB Sta

weixin_34021089的博客 265

flink工作流程

Flink工作流程分为程序提交、图转换、资源分配和任务执行四个阶段:用户代码先转换为StreamGraph,经优化生成JobGraph和ExecutionGraph;JobManager申请资源并调度任务到Slot;TaskManager执行任务时采用事件驱动模型,支持容错恢复。流程包含算子链优化、检查点机制,并支持多种部署模式(会话/单作业/应用模式),满足不同场景需求。核心特点是数据流处理、状态管理和容错保障能力。

知乎:https://www.zhihu.com/column/c_1956128398884729528 1912
上一篇: Flink 系列第7篇:Flink 状态管理全解析(原理+类型+存储+实操)
下一篇: Flink 系列第9篇:Flink 重启策略详解
juniperhan
博客等级 码龄1年 132粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值