Published on

ckpt、 Savepoint 消失之谜:为什么你的 Flink 总是“冷启动”?

Authors
  • avatar
    Name
    Charles Chen
    Twitter

在 Flink 实时开发的江湖里,最让人心惊胆战的不是任务挂了,而是你明明在 Dinky 界面上点了“停止并触发 Savepoint”,重启后却发现 Latest Restored 那里无情地写着:None

别慌,这不是玄学,而是你的架构配置在跟你玩“躲猫猫”。

一、 消失的路径:谁动了我的 Savepoint?

当你点击 Dinky 的“触发 Savepoint”却收到那行红色的 Config key [state.savepoints.dir] is not set 时,Flink 其实在对你咆哮:“兄弟,存档文件我往哪儿搁啊?”

1. 存档位缺失

Checkpoint(检查点)通常在 flink-conf.yaml 里有默认路径,它是“自动存档”。但 Savepoint(保存点)是“手动存档”,Flink 坚持要求你显式指定路径。

  • 药方: 在 Dinky 的动态参数或集群配置中,加上这行硬通货: state.savepoints.dir: hdfs:///flink/savepoints

2. Dinky 的“记性”问题

Dinky 的“最近一次策略”其实是个数据库联动逻辑。如果你停止任务时没有产生成功的 Savepoint 记录在 Dinky 的 dinky_history 表里,它下次启动时就会因为找不到路径而选择“裸奔”(冷启动)。


二、 幻觉:为什么“冷启动”没从头消费?

很多同学发现:“虽然恢复失败了,但 Kafka 也没从头读啊,数据没翻倍,虚惊一场?”

这就是架构设计中的**“多重保险”机制**。你要分清这两套独立的人马:

  • Flink 状态 (The Source State): 存储在 HDFS 上。如果恢复成功,Flink 会霸气地告诉 Kafka:“我有存档,从这个 Offset 开始!”
  • Kafka 偏移量 (The Broker Offset): 存储在 Kafka 的 __consumer_offsets 里。

真相是: 当 Flink 恢复失败(冷启动)时,它会退而求其次,去问 Kafka 代理:“这个 group.id 上次读到哪了?”。Kafka 告诉它位置后,任务看似接上了。但这只是**“低保”**,它只能保证不漏数,无法保证不重数


三、 灵魂拷问:开启了 Checkpoint,数据就不会重复吗?

核心:“我开了 CK,任务挂了重启,为什么数据库里数据多了?”

1. 默认的“渣男”行为:At-Least-Once

大多数 Sink(如 OceanBase、MySQL、普通 Kafka Sink)默认都是 “边跑边发”。它们不会等 Checkpoint 完成才写数据。

  • 灾难场景: 19:00:00 任务做了最后一次成功 CK(Offset 为 100)。19:00:10 任务写到了 Offset 110,此时突然断电。
  • 重启后果: 因为 110 还没来得及做 CK,Flink 重启后从 100 开始读。100 到 110 之间这 10 条数据,会被再次发送给下游。

2. 真正的救星:幂等性 (Idempotency)

如果你的 OceanBase 表里有主键(Primary Key),Flink SQL 在写入时会自动执行类似 REPLACE INTOUPSERT 的逻辑。

  • 这时候,即便那 10 条数据重发了,数据库也会因为主键冲突而执行覆盖操作。这就是为什么你的简单 ETL 任务看起来很稳。

3. 终极奥义:两阶段提交 (2PC)

如果你处理的是金融级数据,绝对不允许重复,那就得开启 End-to-End Exactly-Once。这需要 Sink 支持事务(比如 Kafka 开启事务模式)。数据先写,但不标记为“已提交”,直到 Checkpoint 成功的指令传来,才正式生效。


四、 架构师手册:完美恢复的 Checklist

想要你的 Dinky 任务像“单机游戏读档”一样精准,请记住以下三条:

  1. 路径必须硬: 确保 state.savepoints.dir 在配置中从未缺席。
  2. 停法要考究: 养成从 Dinky 界面通过“触发 Savepoint”停止任务的习惯,给 Dinky 留存数据库记录的时间。
  3. 下游要幂等: 永远不要信任分布式系统的不挂机承诺。给下游表设好主键,是大数据工程师最后的温柔,也是防止数据重复最简单有效的架构手段。

总结: 状态恢复不是目的,数据准确才是。下一次,看到 Latest Restored 出现路径时,那才是你架构能力的真正起飞。