分布式执行与中心调度
分布式执行把任务的实际运行分散到多个代理节点,中心只负责决策:谁来做、做什么、什么时候做。两种基本形态是推送式分配(中心指定代理)与拉取式领取(代理按自身容量主动取任务,天然形成负载均衡)。核心矛盾出现在网络分区与节点故障时:中心认为任务在执行而代理已经失联,或代理已完成而上报丢失,都会造成重复执行或永久滞留。应对方式是引入租约与超时重派,并要求任务幂等;同时中心自身也是单点,需要状态持久化与高可用。
基本信息
| 基本形态 | 推送式分配(中心决定目标)与拉取式领取(代理按容量取任务) |
|---|---|
| 状态存放 | 中心持久化任务状态与租约;代理只保留执行上下文 |
| 失联处理 | 租约到期后重派,重派前提是任务幂等 |
| 中心侧风险 | 单点故障、状态存储可靠性、与代理的时钟偏差 |
典型使用场景
- 数百台机器的批量任务由中心统一编排与统计
- 需要按节点容量动态伸缩执行端数量
- 跨机房执行时优先就近选择执行节点
- 网络分区情况下仍需保证任务不重复不丢失
- 需要中心统一视图以便审计与统计成功率
拉取式执行循环
拉取式执行循环
while true; do
task=$(curl -sS "https://hub.example.com/v1/tasks/lease?agent=$(hostname)")
if [ -z "$task" ] || [ "$task" = "null" ]; then
sleep 5; continue # 无任务时退避,避免空转打压力中心
fi
run_task "$task" && \
curl -sS -X POST "https://hub.example.com/v1/tasks/$(printf '%s' "$task" | jq -r .id)/ack"
done
# 租约通常包含 task_id、lease_expire、attempt,代理需在到期前完成并上报推送与拉取对比
| 维度 | 推送式分配 | 拉取式领取 |
|---|---|---|
| 负载均衡 | 中心预估,容易失衡 | 代理按容量领取,自然均衡 |
| 网络分区 | 中心不知代理状态,可能重复派发 | 代理取不到任务,任务滞留但不重复 |
| 中心负载 | 需逐台连接代理,连接数高 | 代理主动轮询,中心只需响应 |
| 凭据边界 | 中心掌握全部目标凭据 | 代理只持有自己的凭据,边界更清晰 |
| 适用规模 | 中小规模、目标固定 | 大规模与执行端动态伸缩 |
中心与代理的时钟偏差会直接影响租约判定。租约有效期应由中心单向计算,或使用相对时长而非绝对时间点,避免时钟漂移导致任务被过早或过晚重派。
中心调度器本身也是单点:它重启期间任务停止推进,若状态只存在内存中还会全部丢失。任务状态必须持久化,调度器需要具备重启恢复与重复派发去重的能力。