为什么任务要错峰
批量机器上的定时任务如果都配在同一个整点,会同时向数据库、存储或接口发起请求,形成瞬时尖峰,把下游打满。错峰思路有两种:在任务内部随机延迟一段时间再执行,或者把触发时刻按机器编号打散到不同分钟。前者改动小,后者更彻底,也不占用额外的进程。
基本信息
| 适用平台 | Linux(cron、anacron、systemd timer 各有对应手段) |
|---|---|
| 任务侧手段 | 在脚本开头随机休眠一段时间 |
| 配置侧手段 | anacron 提供随机延迟参数,timer 有专门的抖动参数 |
| 选择依据 | 任务耗时短用时刻打散;必须整点附近启动才用随机延迟 |
典型使用场景
- 几十台机器同时上报数据,改为错峰后显著降低数据库压力
- 整点集中做日志归档导致磁盘写入尖峰,延迟一部分机器
- 批量拉取接口数据,避免同一时刻触发对端限流
- 备份任务与业务高峰重叠,通过随机化把负载摊开
- 排查「每天几点几分必然变慢」这类规律性性能问题
cron 随机延迟
cron 随机延迟
# 0 到 29 分钟内随机延迟后执行(脚本用 bash 解释)
0 3 * * * sleep $((RANDOM % 1800)); /opt/app/sync.sh
# 更稳妥的写法:脚本内部随机休眠,cron 只负责触发
0 3 * * * /opt/app/sync.sh # 脚本开头 sleep $((RANDOM % 1800))
# 按机器编号把触发分钟打散
15 3 * * * /opt/app/sync.sh # 第一批机器
25 3 * * * /opt/app/sync.sh # 第二批机器anacron 与 timer 侧
anacron 与 timer 侧
# anacrontab 中的随机延迟(分钟)
RANDOM_DELAY=45
# systemd timer 的随机抖动(秒)
[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=300错峰手段对照
| 手段 | 实现位置 | 特点 |
|---|---|---|
| 随机休眠 | 任务命令前或脚本开头 | 改动最小,但仍占用一个进程等待 |
| 分钟数打散 | cron 时间字段 | 不占用进程,适合时长较短的任务 |
| 配置随机延迟 | anacron 配置 | 按天任务常用 |
| 随机抖动参数 | systemd timer | 与精度参数配合使用 |
| 分布式调度 | 调度平台 | 规模再上一个量级时的正规方案 |
随机休眠会占着一个进程等待,机器上任务很多时不如直接把触发分钟数打散;两种方式也可以叠加使用。
实施建议
- 先在少数机器上验证错峰效果,再全量下发
- 把最大值控制在业务可接受的延迟范围内,避免任务拖到下一个窗口
- 记录每台机器的随机取值范围,便于复盘时对齐时间线
- 监控任务的完成时间分布,确认尖峰确实被摊平
- 对时序敏感的任务不要加随机延迟
随机数变量的与解释器相关:使用前确认脚本由支持它的解释器执行,否则会得到意外的命令或空值。