任务分片与负载均衡
分片把一批任务切成互不重叠的子集交给不同执行者,负载均衡关注的是各执行者拿到的实际工作量是否接近。分片键的选择直接决定均匀性:按数量区间切分最直观,但隐含假设各任务耗时相近;按哈希取模实现简单,可是键的基数过低会造成严重倾斜;一致性哈希在节点增减时迁移量最小。分片数与并行度是两个独立参数:分片数决定最小并行粒度,并行度决定同时运行多少个分片。
基本信息
| 分片键 | 数值区间、ID 哈希、主机名、时间或业务键 |
|---|---|
| 均匀性影响因素 | 键的基数、数据分布是否偏斜(热键) |
| 再平衡 | 节点增减时的迁移成本与重复执行风险 |
| 关键要求 | 分片任务必须幂等,便于迁移后重跑 |
典型使用场景
- 数十万条记录需要并行处理,单机耗时不可接受
- 按业务键保证同一对象始终只被一个执行者处理
- 执行者数量动态变化时需要重新分配工作
- 需要可控的并行粒度以便限速与逐批观察
- 需要把耗时长的对象与短对象混合,避免槽位空闲
分片实现示例
分片实现示例
# 按哈希取模:同一键始终落到同一分片
shard=$(( $(printf '%s' "$key" | cksum | cut -d' ' -f1) % 16 ))
[ "$shard" -eq "$my_shard" ] && process "$key" # 仅处理属于自己分片的对象
# 按数量切分:先取总数再按区间划分
per=$(( $(wc -l < ids.txt) / 8 + 1 ))
sed -n "$(( (my_shard-1)*per + 1 )),$(( my_shard*per ))p" ids.txt | process
# 分片数与并行度解耦:分片数 64,同时运行的分片数由并发参数控制分片方式对比
| 分片方式 | 均匀性 | 再平衡成本 |
|---|---|---|
| 按数量区间 | 高,但假设任务耗时相近 | 低 |
| 哈希取模 | 取决于键基数,键少易倾斜 | 高,节点数变化导致大量迁移 |
| 一致性哈希 | 中到高 | 低,只迁移相邻区间 |
| 按业务键显式指定 | 取决于业务分布 | 中,需要业务规则配合 |
| 抢占式领取 | 高,按实际处理速度 | 无,任务即队列 |
分片数一般取执行者数量的若干倍,用来平滑个体速度差异:分片数过少会让慢的执行者拖住整个作业,过多则增加调度与状态管理开销。
再平衡期间容易出现同一分片被新旧执行者同时处理,尤其是任务尚未完成就被迁移的情况。要么等分片上的任务自然结束后再迁移,要么保证分片任务幂等并能安全重跑。