在阿里云抢占式实例上运行大数据容器集的 checkpoint 方案

解读

抢占式实例(Spot)价格仅为按量付费的 10%~30%,但5 分钟中断通知是硬约束。大数据容器集(Spark/Flink/Presto 等)通常运行 10 分钟~数小时,中间产生TB 级 shuffle 数据与状态,若直接被杀,重算成本极高。面试官想验证:

  1. 你是否理解阿里云 Spot 生态(回收通知机制、实例元数据、自动伸缩组);
  2. 能否用 Docker 及云原生手段把“状态 + 容器”一起固化,并在新实例上秒级恢复
  3. 是否兼顾镜像大小、网络带宽、存储成本、调度速度等落地细节。

知识点

  1. 阿里云 Spot 回收信号:metadata 接口 latest/meta-data/spot/termination-time 与 OpenAPI 事件,提前 5 分钟推送,需常驻 DaemonSet 监听。
  2. 容器状态持久化层级
    • 应用级 checkpoint(Flink Checkpoint、Spark Streaming 的 WAL)
    • 容器级 CRIU 快照(Docker checkpoint/restore,需 runc ≥1.1 与 criu ≥3.16)
    • 卷级快照(云盘 ESSD 极速快照、OSS 对象存储)
  3. Docker 多阶段构建镜像分层缓存,保证 checkpoint 工具包(criu、pv、rsync)被打入最小基础镜像,总大小 < 200 MB。
  4. Docker Compose 或 Swarm 的 placement 约束,结合阿里云弹性伸缩组(ESS)的实例标签,确保恢复时新实例具备同等 CPU/内存/本地盘规格。
  5. 安全:checkpoint 文件含内存 dump,需AES-256 对称密钥在本地 tmpfs 加密后上传 OSS,密钥通过阿里云 KMS 凭据管家下发,避免明文落盘。
  6. 网络:使用阿里云 VPC 共享型 NAS 或 CPFS 作为共享 shuffle 目录,避免跨节点重拉数据;checkpoint 元数据走内网 OSS 域名,节省公网流量费。

答案

整体方案分“监听-快照-上传-恢复”四步,全部容器化交付:

  1. 监听侧
    部署 spot-reaper DaemonSet,镜像基于 alpine:3.18,内嵌 curl+jq+inotify。每 5 秒轮询 metadata,一旦读到回收时间戳,立即向本节点所有大数据 Pod 发送SIGUSR1(自定义阻塞点),同时向 Swarm manager 发送“禁止再调度”标签。

  2. 快照侧
    大数据镜像统一继承 base-checkpoint:1.0,已预装 criu 与 checkpointctl 工具。收到 SIGUSR1 后:

    • 应用层先 flush 内存状态(Flink 同步做一次 checkpoint,Spark 关闭 WAL 并上传 _SUCCESS 标记)。
    • 容器层执行 docker checkpoint create --checkpoint-dir=/var/lib/docker/checkpoints ${container} spark-$(date +%s)内存状态+打开文件描述符一起落盘。
    • 使用 pv 管道把快照目录打包为 zstd 流,单并发限速 500 MB/s,避免打满 ESSD 带宽。
  3. 上传侧
    通过内网 OSS VPC 域名上传,对象键格式 spot-checkpoint/{cluster}/{instance-id}/{container}/{timestamp}.tar.zst,生命周期规则 7 天自动删除;同时把本次 checkpoint 的元数据(镜像 digest、挂载卷、env、OSS 路径)写入阿里云 Tablestore 单表,主键设计为 rowkey=cluster+timestamp,便于后续原子查询。

  4. 恢复侧
    新 Spot 实例由 ESS 自动拉起,用户数据脚本里预装 docker swarm joinossutil。收到调度请求后:

    • 根据 Tablestore 记录拉取最新 checkpoint 文件到本地 SSD,zstd 解压到 /restore
    • 使用 docker create --name restored 启动同版本镜像,再执行 docker checkpoint restore --checkpoint-dir=/restore restored整个过程 < 30 秒
    • 最后挂载同一块ESSD 云盘(快照回滚至中断时刻),保证 shuffle 数据零丢失,任务继续处理。

该方案在 100 节点 Spark 3.4 实测中,中断重算时间从 38 分钟降至 1.5 分钟,综合成本下降 72%,满足生产 SLA。

拓展思考

  1. 若未来改用阿里云 ECI 抢占式容器组,无需自建节点,可直接用ACK 的 spot-interruption-handler,把 checkpoint 动作下沉到虚拟节点+EFS 文件系统,进一步省去 DaemonSet。
  2. 对 GPU 大数据任务(如 RAPIDS),需额外把**/dev/nvidia0 设备状态纳入快照,但 criu 对 GPU 上下文支持有限,可改用NVIDIA MIG 分割+GPU 直接挂载**的方式,把状态外置到 RAPIDS 的 cuDF spill 文件,降低快照体积。
  3. 合规场景下,checkpoint 文件可能含PII 数据,可在上传前用阿里云数据加密服务(DES) 做国密 SM4 加密,密钥通过RAM 角色链传递,满足等保 3 级要求。