分片是把执行切成几股
主机数很多时,单次执行受并发度、单机耗时和最慢主机限制。分片思路是把清单按某种维度切成若干片,让多个执行进程(或多次执行)各自负责一片并行推进。它与滚动批次不同:批次是同一进程内按顺序推进,分片是多个进程同时在不同子集上工作,因此对幂等性与资源互斥的要求更高。
基本信息
| 分片维度 | 按分组、按机架或机房、按业务单元、按主机名规律 |
|---|---|
| 执行方式 | 多个执行进程各自指定清单与范围,或调度平台并发作业 |
| 范围控制 | 命令行限制范围与清单选择是两个不同层次的切分手段 |
| 前提条件 | 各片之间不共享需要串行化的资源,任务必须幂等 |
| 共享步骤 | 全局只应执行一次的动作必须显式串行化 |
| 失败处理 | 各片独立失败与重试,需要汇总结果再决定整体结论 |
典型使用场景
- 上千台主机的基线收敛:按机房分片并行,缩短整体窗口
- 多业务线共用一套角色:按业务单元分片,互不干扰
- 大规模重启类操作:分片错峰,避免同时冲击后端依赖
- 受限窗口内完成变更:窗口很短时只能靠并行多片压缩总时长
- 分层发布:平台组件先跑一片,业务组件后跑另一片
- 失败收敛:分片执行后按各片结果汇总,只重跑失败部分
切分与重试方式
切分与重试方式
# 方式一:按分组各跑一次(两个进程并行,各自限定范围)
ansible-playbook -i inventory/prod site.yml --limit idc_a
ansible-playbook -i inventory/prod site.yml --limit idc_b
# 方式二:同一次执行内提高并发度,用滚动批次控制同时变更的比例
# ansible-playbook -i inventory/prod site.yml -f 50
# play 里 serial: "20%" 使同一时刻只有两成主机在变更
# 方式三:只重跑失败的主机(重试文件只登记失败主机)
ansible-playbook -i inventory/prod site.yml --limit @site.retry
# 注意:剧本里的“只执行一次”类任务在分片下会每片各执行一次,
# 例如数据库迁移、集群级变更,必须单独设计为串行步骤。
# 分片前的检查清单:
# - 该任务是否幂等,重复执行是否安全
# - 两个分片是否会同时改同一个共享资源
# - 失败后能否只重跑其中一片并发手段对照
| 手段 | 粒度 | 适用与限制 |
|---|---|---|
| 提高并发度 | 单进程内同时推进主机数 | 最简单;受控制节点资源与目标机负载限制 |
| 滚动批次 | 同一进程内分批顺序推进 | 控制影响面,但不缩短总时长 |
| 清单分片多进程 | 多个执行进程并行 | 总时长最短;要求幂等与资源互斥 |
| 按分组分批执行 | 人工串行两段 | 适合有明确先后的组件 |
| 只重跑失败主机 | 按失败清单重试 | 收敛快;需确认跳过的成功部分状态一致 |
分片最容易忽略的是“全局只应发生一次”的动作:数据库迁移、集群级配置、共享锁的创建等。这类步骤在分片下会按片重复执行,必须提到分片之外单独跑一次,或加上分布式锁与幂等判断。
分片并行会同时冲击共享后端:注册中心、配置中心、存储、鉴权服务。主机数翻倍不等于后端能承受翻倍的并发注册与拉取,分片前应按后端承载能力设定各片的并发度与错峰间隔。
怎么判断分片是否值得
先测出单进程执行一段时间的实际瓶颈:是并发度不够、还是有少数慢主机拖尾。前者提高并发度即可,后者才需要分片。分片带来的额外成本是结果汇总、失败重试与共享资源的串行化设计,收益不够明显时不必引入。