订阅更新

数据任务怎么断点续传?游标保存了,为什么还是丢数或重复?

面试问 290 约 3 分钟读完 1 次阅读

本文目录
  1. 面试怎么回答
  2. 先把“处理完成”拆成三步
  3. 两种先后顺序,各有一类风险
  4. 多个并发分页,不能取最大完成位置
  5. 一个典型场景:最后一页只写了一半
  6. 读取范围不稳定,游标再准也会漂移

面试怎么回答

我会让游标表示连续已提交的数据边界,并明确它记录最后完成位置还是下一条待读位置。游标与结果能在同一事务里提交最好,跨系统则允许结果先提交、游标后推进,再依靠幂等承受重放。还要固定读取范围和确定性排序,处理同时间记录、部分页失败及并发完成乱序。恢复验收应主动在写入和保存游标之间制造失败,检查缺口、重复与最终结果。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

任务跑到第80页失败了,重启从第81页开始,看起来已经实现断点续传。可第80页到底是“请求成功”,还是“下游全部提交成功”?如果这个问题答不上来,断点只是一个数字,并不是可靠的恢复证据。

可恢复断点必须代表连续已提交的数据边界;先存游标会漏,后存游标会重,必须与提交和幂等一起设计。

先把“处理完成”拆成三步

获取到一页数据、完成转换、下游持久化成功,是三件不同的事。接口返回成功后立刻存下一页游标,不能证明这一页已经进入目标系统。

还要明确游标语义:保存的是最后一条已完成记录,还是下一条待处理记录?恢复时用大于还是大于等于,必须与这个定义匹配。

批次日志可以记录读取范围、结果数量、提交标识和游标,但日志本身也需要可靠保存。只有一条“处理成功”的文本,不足以判断部分数据是否已经落地。

两种先后顺序,各有一类风险

先保存游标,再提交结果,中间失败会跳过尚未完成的数据,造成缺口。后提交游标,如果结果已经成功而游标未更新,重启会再次处理同一范围。

跨系统难以原子提交时,通常更容易接受后者:允许可控重放,再用幂等写入或批次去重确保业务结果不会重复。

但“使用UPSERT”也不是完整答案。如果每次重放都是在旧值上加金额,或者顺带发送通知、调用扣款接口,重复执行仍有副作用。必须逐个定义幂等作用范围。

多个并发分页,不能取最大完成位置

假设第10页先完成,第9页仍在重试。如果把游标推进到10,恢复从11开始,第9页就可能永久缺失。

应该维护连续完成前沿,或者保存各分片独立状态及缺口集合。只有确认前面的范围都已经提交,才能推进共享的连续断点。

对于彼此独立的分片,可以每片保存游标,不必强行使用一个全局数字;但最终批次完成标记要等所有必需分片通过验收。

一个典型场景:最后一页只写了一半

比如一页100条记录分两批写目标库,第一批成功后第二批失败,任务却因分页请求成功而把游标提前存了。

最初怀疑接口分页丢数,重拉原页却能拿到完整100条。真正的问题是游标代表读取进度,不代表提交进度。旧测试只模拟整页请求失败,没有覆盖页内部分写入。

修复可以让整页结果与断点在同一目标事务内提交;如果做不到,就保留安全重放能力,并把部分成功记录的重复写入纳入幂等约束。

测试应分别在提交前、提交后但游标前、游标更新后以及并发页乱序完成时中断,再核对业务键覆盖,而不只是确认重启能继续打印日志。

读取范围不稳定,游标再准也会漂移

用页码加OFFSET扫描不断变化的源表,前面的插入或删除可能使后续页位置移动。恢复到原页码,不一定对应原来的业务记录。

可以依据源系统能力,采用快照、稳定分页令牌或确定性键集游标。用更新时间增量时,同一时间可能有多条记录,通常还需要唯一键作为第二排序条件。

同时固定本批高水位或范围上界,避免一边跑一边不断追逐新增数据。源端更正、删除和迟到变更如何纳入下一批,需要额外规则;一个游标不能自动捕获所有修改。

如果选择重叠回扫窗口,必须知道它只是覆盖某个迟到范围,不等于任意久远变更都不会漏。超过窗口的修订要有回补入口和对账发现机制。

这道题最值得讲清楚的是:断点不是“程序到了哪里”,而是“哪一段业务结果已经可靠完成,重复执行又会发生什么”。

刷题进度保存在当前浏览器