rsync是千万级小文件迁移唯一可靠方案,因其增量同步、断点续传、路径精准控制及可调优特性,避免了宝塔打包导致的oom、超时中断等问题。

rsync 是唯一靠谱的选择——宝塔「一键迁移」在千万级小文件场景下必然卡死或失败,不是慢的问题,是根本不可用。它会先打包(tar),而千万个小文件打包本身就会耗尽内存、触发 OOM Killer,或因 inode 耗尽直接中断;即使打包成功,上传/下载阶段也极易因单次连接超时、TCP 重传失败导致整个流程归零。
为什么千万级小文件不能走宝塔打包 + 中转
打包环节就过不去:tar 遍历千万个文件会吃光系统缓存、拖垮 stat() 性能,实测 CentOS 7 上 tar -cf /dev/null /www/wwwroot/site/ 在 500 万文件时平均耗时 >22 分钟,期间 load average 常飙到 30+;中转服务器对单次上传有连接时长限制(通常 ≤15 分钟),超时即断;官方中转链路不支持分片或续传,失败后只能重来。
rsync 同步千万小文件的关键参数组合
默认 rsync -avz 在千万级场景下依然可能卡住或效率低下,必须针对性调优:
- 加
--files-from=配合find生成白名单,跳过.git、cache/、logs/等无意义目录,减少遍历量 - 禁用递归统计:加
--no-i-r(rsync ≥3.2.7)或降级用--min-size=1避免对空文件反复检查 - 限速防打爆带宽:
--bwlimit=5000(单位 KB/s),避免挤占 Nginx 或 MySQL 的 IO - 启用部分传输与校验:
--partial --checksum,断点后不重传整块,只比对内容变化 - 路径末尾必须带
/:/www/wwwroot/site/而非/www/wwwroot/site,否则 rsync 会把整个目录名当成文件同步
宝塔计划任务里跑 rsync 总失败?几个硬坑要绕开
宝塔默认用 www 用户执行定时任务,但它没有 SSH 密钥权限、PATH 不含 /usr/bin、也无法读取 ~/.ssh/id_rsa:
- 计划任务的「运行用户」必须设为
root(或你配置好密钥的用户),不能留默认 - 私钥路径必须用绝对路径,且权限严格:
chmod 600 /root/.ssh/id_rsa,chmod 700 /root/.ssh - 命令里别写
rsync,写/usr/bin/rsync(先which rsync确认位置) - 脚本开头加
#!/bin/bash,并用chmod +x赋权;计划任务里只写bash /www/scripts/sync.sh - 首次运行务必加
--dry-run,确认输出里没有意外的deleting或路径错位
同步完成但网站 404 或 PHP 报错?别只盯文件
rsync 只管文件,不管运行时状态。千万小文件同步期间,原站可能还在写日志、生成缓存、处理上传——这些动态内容不会被同步,反而会在目标端残留旧缓存或锁文件,引发冲突:
- 同步前在源站临时停掉相关服务:
bt stop php、bt stop nginx(若允许短时中断) - 同步后在目标站手动清空:
rm -rf /www/wwwroot/site/runtime/ /www/wwwroot/site/cache/ /www/wwwroot/site/logs/ - 检查 SELinux 状态:
getenforce,如为Enforcing,需restorecon -Rv /www/wwwroot/site/重置上下文 - PHP 扩展是否一致?用
php -m | sort对比两边输出,缺的模块要手动装,比如bt install php_extension redis











