SDE-2 · Technical Round 2 LLD / System Design

Rippling 分布式任务调度:百万任务、租约与 Worker 宕机

用持久状态、到期分片扫描、租约领取与幂等副作用实现不漏调度,并明确重复执行边界。

题目重点:用持久状态、到期分片扫描、租约领取与幂等副作用实现不漏调度,并明确重复执行边界。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 示例以数据库存 `task_id,run_at,state,lease_owner,lease_until,attempt,version,payload_ref` 为事实源,按 UTC 时间调度;至少一次执行可接受,外部副作用需幂等。
  • ‘数百万任务’是题目明确数量级,运行到期峰值/执行时长未披露,吞吐须另估。

解题路线

  1. 创建任务先持久化 scheduled 状态,再确认给调用方;按 run_at 分片/索引扫描到期任务,调度器不依赖单机内存定时器。
  2. 多个 worker 用条件更新把 scheduled 或过期 leased 任务领取为 leased,并设置 lease_until、owner 和递增版本;失联后另一 worker 只能在租约过期后重领。
  3. 执行完成用 owner/version 条件提交 succeeded;外部 API 先使用 task_id+operation 作为幂等键。超时/失败分可重试与永久失败,退避后重新 scheduled,超过上限进 dead-letter。
  4. 容量按到期峰值 R、平均执行时长 T、并发上限 C≈R×T 估;分片避免单索引热点,监控到期滞后、租约过期率、重试量与 DLQ。

手动走一遍

12:00 到期任务被 worker A 租到 12:01;A 完成外部付款但确认写库前宕机。12:01 后 B 重领,调用相同幂等键,外部只认一次,再写成功。若外部不支持幂等,系统无法仅靠队列承诺副作用恰好一次。

规模与取舍

到期索引查取每批约 O(log N+b),N 为待调度任务数、b 为批量;存储 O(N+执行历史)。可扩展性受到期峰值、分片热点及外部副作用吞吐限制,不能由总任务数单独推出机器数。

易错点与追问

容易失分的边界

  • 把入内存定时器视为可靠持久调度。
  • worker 宕机后无租约回收路径。
  • 把消息只投递一次误认为外部效果只发生一次。
  • 心跳延长租约却不检查 owner/version,导致旧 worker 覆盖新结果。
  • 数百万任务全部按秒全表扫描。

继续深挖

  • A 在租约过期后醒来,怎样防迟到写?
  • 到期时间极度集中的热点如何削峰?
  • cron 重复任务下一次运行怎样生成且防重复?
  • 取消任务与 worker 同时领取如何竞态控制?
✓已复制微信号!