
rsync 本身不支持实时同步,必须搭配 inotify 才能触发变化即同步;单纯靠 crontab 定时拉取是“伪实时”,延迟取决于轮询间隔,且浪费资源。
rsync 拉取同步命令写错路径会复制整个目录而非内容
常见错误:执行 rsync -avz user@host:/path/to/dir /local/ 时,/path/to/dir 末尾没加 /,结果把 dir 目录本身(含父名)整个复制到 /local/dir/;正确写法是 /path/to/dir/(末尾斜杠),这样才只同步目录下内容。
其他关键点:
-
-a已包含-r(递归)、-l(软链)、-p(权限)、-t(时间戳)等,日常同步优先用-avz(v可视化、z压缩传输) - 若目标已有文件但源已删除,需加
--delete才能同步删除动作,否则目标端残留旧文件 - 用
ssh通道时,端口非默认 22 需显式指定:-e 'ssh -p 2222' - 首次同步数据量大时,
rsync比scp或tar + ssh慢,可先用tar全量传一次,再用rsync增量维护
inotifywait 必须监控父目录,不能只监子目录或文件
inotifywait 默认不递归,且对新建子目录下的事件无感知。比如监控 /data,但有人在 /data/upload/2026/04/ 下放文件,若没开 -m -r,事件根本不会触发。
正确启动方式示例:
inotifywait -m -r -e create,delete,modify,move_to /data/
说明:
-
-m:持续监听,不退出 -
-r:递归监控所有子目录 -
-e后列出具体事件类型,避免用all(太重,易漏判) - 不要监控
/data/file.txt这种单文件——inotifywait对已存在文件的修改事件不稳定,应监控其所在目录
rsync + inotify 脚本里容易忽略锁机制和空事件
当批量上传(如解压、git pull)触发大量 inotify 事件时,脚本可能并发执行多次 rsync,导致冲突或重复传输。
必须加简单锁控制:
- 用
if [ -f /tmp/rsync.lock ]; then exit; else touch /tmp/rsync.lock; ...; rm -f /tmp/rsync.lock; fi -
inotifywait可能因网络抖动或文件系统缓存返回空事件,建议加|| continue避免脚本中断 - 每次 rsync 前先
sleep 1,防止连续事件洪峰(尤其 NFS 或 CIFS 挂载点) - 务必在 rsync 命令后判断
$?,失败时不删锁,便于人工排查
inotify 内核参数过小会导致监控失效且无提示
默认 /proc/sys/fs/inotify/max_user_watches 常为 8192,一旦监控目录层级深或子目录多,很快耗尽,inotifywait 会静默退出,看起来像“不工作了”。
检查与修复:
- 运行
cat /proc/sys/fs/inotify/max_user_watches查当前值 - 临时调高:
echo 524288 > /proc/sys/fs/inotify/max_user_watches - 永久生效:在
/etc/sysctl.conf加一行fs.inotify.max_user_watches=524288,再执行sysctl -p - 同理注意
max_user_instances和max_queued_events,生产环境建议一并调至 65536 级别
inotify 的边界很“硬”——超限就静默失败,不像 rsync 会报错,这点最容易被忽略。











