
凌晨备份一跑,网站就开始卡,订单提交转圈、后台刷新半天不出页面——这是很多站长都遇到过的场景。本文教你如何用 Linux 的 ionice 和 nice 两个命令,把备份任务对磁盘和 CPU 的占用降到最低,帮助你在不停业务、不加服务器的前提下解决“备份拖垮业务”的问题。更多服务器配置与优化经验,也可以在站长学院分类下找到。全文包含可直接复制的 rsync、mysqldump 与 crontab 配置示例,以及备份完成后的验证方法。
为什么备份会把业务拖慢
要解决问题,先要知道瓶颈在哪。备份慢和业务卡,本质上是两类资源在打架:
- 磁盘 IO:备份本质是把大量数据从磁盘读出来再写到别处。普通进程默认使用最佳努力(best-effort)IO 调度级别,备份进程大规模顺序读盘时,会抢占数据库和网站程序的随机读写带宽,导致查询响应时间从几毫秒涨到几百毫秒。
- CPU:压缩(gzip、zstd)、加密(openssl、gpg)是备份链路里最吃 CPU 的环节。如果备份进程以默认优先级运行,内核会把它和 PHP-FPM、MySQL 等业务进程平等对待,CPU 核心一紧张,业务请求就开始排队。
一个真实的例子:一台 4 核 8G 的 VPS(虚拟专用服务器)上跑 nightly rsync,备份窗口内网站平均响应时间从 180ms 涨到 1.4s,MySQL 慢查询数量翻了 6 倍。换用 ionice 降级后,同样的备份耗时只增加了约 15%,但业务响应时间几乎不受影响。
判断你的备份是否正在影响业务,可以用这两个命令在备份时段观察:
# 查看哪些进程正在占用 IO
iotop -oP
# 查看各进程的 CPU 占用与 nice 值
top -b -n 1 | head -20
如果 iotop 里备份进程的 IO 占用长期在 80% 以上,基本可以确认瓶颈在磁盘。
ionice:给备份任务降低 IO 优先级
ionice 控制的是进程对磁盘的访问优先级,Linux 把 IO 调度分为 3 个级别:
- Idle(3 级):只有磁盘空闲时才执行 IO,对业务几乎零影响,代价是备份速度最慢。
- Best-effort(2 级):默认级别,按优先权值(0-7,数字越小优先级越高)与其他进程竞争磁盘。
- Real-time(1 级):优先于所有普通 IO,备份任务绝对不要用这个级别,否则等于反过来抢占业务。
对备份任务来说,Idle 级别是最安全的选择。实际用法如下:
# 以 Idle 级别执行 rsync 备份
ionice -c 3 rsync -a /var/www/ /backup/www/
# 以 Best-effort 级别 + 最低优先权值执行
ionice -c 2 -n 7 tar -czf /backup/etc.tar.gz /etc
两者怎么选?如果备份窗口充足(比如凌晨 1 点开始、早上 6 点前完成即可),直接用 -c 3,业务完全无感。如果数据量大、必须尽快备完,可以用 -c 2 -n 7,它仍会参与磁盘竞争,但优先级低于所有正常业务 IO。
需要注意一点:ionice 的效果依赖 IO 调度器。在较新的内核上默认使用 mq-deadline 或 bfq,ionice 都能正常生效;如果你的系统还在用古老的 noop 或 none 调度器(常见于本地 NVMe 直通场景),可以用 cat /sys/block/vda/queue/scheduler 确认,必要时切换到 bfq 才能让 Idle 级别真正发挥作用。

nice:给备份任务降低 CPU 优先级
nice 控制的是 CPU 调度优先级,取值范围 -20 到 19,数字越大优先级越低。普通用户只能把进程的 nice 值调高(更谦让),只有 root 才能调到负值。备份任务应该使用较高的 nice 值,把 CPU 主动让给业务进程:
# nice 值 19:最低 CPU 优先级
nice -n 19 gzip /backup/log/large.log
# 压缩算法本身很吃 CPU,配合 ionice 一起用
nice -n 19 ionice -c 3 tar -czf /backup/www-$(date +\%F).tar.gz /var/www/
上面的最后一行就是“备份不拖垮业务”的标准写法:nice 管 CPU,ionice 管 IO,两个命令组合起来,备份进程变成一个“只在系统空闲时干活”的 Background 任务。实测在一台 2 核的虚拟主机级别服务器上,这套组合让备份期间的 CPU idle 从 12% 回升到 55% 以上,网站首屏时间基本回到正常水平。
crontab 中日期格式需要转义,date +\%F 里的反斜杠不能省,否则 cron 日志会报错。
完整实战:crontab 配置与验证
把前面的命令组合成定时任务,下面是一个可以直接用的 crontab 示例:
# 每天凌晨 1:30 执行网站目录备份(低优先级)
30 1 * * * nice -n 19 ionice -c 3 rsync -a --delete /var/www/ /backup/www/
# 每周日凌晨 2:30 执行数据库逻辑备份
30 2 * * 0 nice -n 19 ionice -c 3 mysqldump -u备份用户 -p'密码' --single-transaction --all-databases | gzip > /backup/db-$(date +\%F).sql.gz
两个细节值得单独说明:
- mysqldump 加
--single-transaction:对 InnoDB 表做一致性快照,备份期间不需要锁全表,业务写入不受影响。 - 专用低权限备份账号:只授予
SELECT和LOCK TABLES权限,即使备份脚本泄露也不会波及整个数据库。
配置完成后,怎么验证降级真的生效了?在备份运行时执行:
# 查看备份进程实际的 nice 值和 IO 调度级别(ni 列应为 19,ionice 应显示 idle)
ps -eo pid,ni,cls,cmd | grep -E 'rsync|mysqldump'
cls 列显示 3 就代表 Idle 级别已生效。如果发现 nice 值或 IO 级别不对,多数是 cron 环境里没走完整的命令前缀,检查 crontab 里是否漏写了 nice 或 ionice。如果服务器长期高负载,也可以评估升级到独立服务器,把磁盘 IO 面貌整个换掉。
另外建议保留一份备份完成时间的记录,观察一周:如果用 Idle 级别后备份总时长超过了预留窗口,可以退回到 -c 2 -n 7,在“不影响业务”和“按时备完”之间找一个平衡点。

几个容易踩的坑
第一,ionice 不是万能的。它只约束“块设备层”的 IO,如果备份写到 NFS(网络文件系统)或对象存储挂载点,调度级别对网络传输本身不起作用,这时瓶颈要从带宽(网络传输的数据吞吐能力)角度另行处理。第二,某些云盘和 RAID 卡自带写缓存,Idle 级别的实际效果取决于硬件队列的表现,上线前建议先在业务低峰试运行一晚,对比备份前后的响应时间曲线。这类“响应时间忽高忽低”的问题,与我们之前聊过的网站性能优化思路是一脉相承的,都强调先测量、再动手。第三,别忘了监控备份是否真的完成了——低优先级意味着可能被推迟,任务失败要能及时告警,否则你以为有备份,实际上备份早就没跑成功了。
总结与行动建议
解决备份拖垮业务,核心思路就一句话:把备份进程的 CPU 和 IO 优先级都降下来,让它只在系统空闲时工作。具体行动建议如下:
- 立即检查现有 crontab 中的备份任务,给它们加上
nice -n 19 ionice -c 3前缀。 - 用
ps -eo pid,ni,cls,cmd验证降级生效,并在备份时段对比网站响应时间。 - 数据库备份务必加
--single-transaction,并使用低权限专用账号。 - 如果你需要更省心的方案,也可以考虑使用带独立备份能力的虚拟主机产品,由面板自动完成每日备份,例如 Hostease 的虚拟主机自带定期备份功能,可以把运维精力留给业务本身。
- 备份策略建议每季度复查一次:数据量增长后,原来的 Idle 级别可能跑不完,提前调整比备份超时后补救要稳妥得多。
备份是运维的最后一条防线,值得花半小时把优先级调好——一次配置,长期受益。