3. 断点续传核心概念
行情采集系统一旦进入生产环境,网络抖动、交易所限流、进程重启、磁盘写满都会成为常态。断点续传不是“可选优化”,而是保证行情数据不丢、不重、可追溯的基础能力。本节先把七个核心概念讲清楚:断点、续传、幂等、偏移量、水位线、检查点、数据一致性。它们不是孤立术语,而是一套彼此咬合的机制。
一、核心原理:七个概念如何咬合
可以把行情采集链路想象成一条“带刻度的传送带”。数据从交易所流出,经过采集器、缓冲队列、落库三个环节。要让这条链路在故障后能接着跑,必须回答三个问题:跑到哪了、从哪继续、重复了怎么办。
- 断点:采集过程中因异常中断时,最后一条被确认处理完成的数据位置。它是“故障发生瞬间的进度快照”。
- 续传:系统重启或恢复后,从断点之后继续拉取或消费数据的行为。续传的关键是“起点正确”,而不是“跑得快”。
- 偏移量(Offset):数据流中的位置编号。Kafka 用 offset 标识分区内消息序号,文件采集用字节偏移,数据库补录用自增 ID 或时间戳。偏移量是断点的物理载体。
- 水位线(Watermark):表示“某时间点之前的数据已全部到达”的边界。行情场景中常用于判断乱序数据是否还有迟到可能,决定何时可以安全落库或触发计算。
- 检查点(Checkpoint):将当前处理进度、状态、偏移量持久化的动作或产物。检查点是断点能够跨进程、跨机器恢复的前提。
- 幂等(Idempotent):同一操作执行一次和执行多次,对最终结果影响相同。续传必然带来重复投递,幂等是“重复不写坏数据”的保证。
- 数据一致性:采集端、缓冲端、存储端对“哪些数据已处理”的认知一致。一致性不是绝对精确,而是业务可接受范围内的不丢不重或可去重。
一句话串联:偏移量标记位置,检查点固化位置形成断点,水位线判断数据完整性,续传从断点继续,幂等消化重复,最终达成数据一致性。
二、方法流程:一次标准续传的完整动作
以 Kafka 消费行情快照为例,标准续传流程如下:
- 采集器启动,从检查点存储(如 Redis、ZooKeeper、数据库)读取上次提交的 offset。
- 若检查点不存在,按业务策略选择 earliest 或 latest 作为初始偏移量。
- 向 Kafka 发起 poll,从该 offset 开始拉取消息。
- 处理消息并写入下游存储,写入操作必须带幂等键(如 symbol + exchange + timestamp)。
- 处理成功后,异步或同步提交新 offset 到检查点存储。
- 若处理失败,不提交 offset,下次续传会重新拉取该批消息,由幂等逻辑去重。
# 查看消费者组当前提交的偏移量
kafka-consumer-groups.sh --bootstrap-server broker:9092 \
--group market-quote-collector --describe
# 输出示例
TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
market.quote 0 1284567 1284600 33
market.quote 1 998231 998231 0
其中 CURRENT-OFFSET 就是检查点中记录的断点,LAG 表示尚未消费的消息数。续传时从 CURRENT-OFFSET 继续即可。
三、案例/场景:水位线与乱序行情的配合
行情数据天然存在乱序:交易所推送的逐笔成交可能因网络路径不同而晚到。假设水位线设置为“当前最大事件时间减 5 秒”,则水位线之前的数据被认为已到齐,可以安全落库;水位线之后的数据进入等待区,若迟到则触发补录。
| 概念 | 在行情采集中的具体载体 | 典型参数/示例 | 失效后果 |
|---|---|---|---|
| 偏移量 | Kafka offset、文件字节位置、数据库自增 ID | offset=1284567 | 重复消费或漏消费 |
| 检查点 | Redis 中的 group-offset、Flink checkpoint | 每 5 秒提交一次 | 重启后无法定位断点 |
| 水位线 | 事件时间窗口边界 | maxEventTime - 5s | 乱序数据被误判为完整 |
| 幂等键 | symbol + exchange + timestamp + seq | 唯一索引或 Redis SETNX | 重复写入导致数据膨胀 |
| 数据一致性 | 端到端校验任务 | 对账 count/checksum | 业务方看到错误行情 |
四、误区/复盘:三个常见错误
误区一:把“提交 offset”当成“数据已落库”。 若先提交 offset 再写库,写库失败时数据就永久丢失。正确顺序是先写库成功,再提交 offset;或使用事务/两阶段提交。
误区二:认为续传一定从“断点”开始。 断点是“最后确认完成”的位置,不是“最后拉取”的位置。若检查点提交滞后,续传会重复消费一段数据,这正是幂等存在的意义。
复盘建议: 每次故障恢复后,记录三个数字——重复条数、丢失条数、补录耗时。重复条数反映幂等设计质量,丢失条数反映检查点与落库的先后顺序,补录耗时反映水位线与补录通道的效率。长期跟踪这三个指标,比单纯追求“不中断”更有工程价值。