inotify本身不支持双向同步,强行用两个inotify+rsync脚本互推会引发循环触发、文件覆盖、状态不一致等问题;应采用单向同步为主+只读挂载、防重入锁、删除策略优化及内核参数调优等补偿机制,并在严格双向需求时选用lsyncd、syncthing等专业工具。

inotify 本身不支持双向同步,强行用两个 inotify + rsync 脚本互推会引发循环触发、文件覆盖、状态不一致等严重问题。所谓“秒级实时双向热备”,不能靠裸写脚本硬凑,必须引入冲突规避和状态协调机制。
inotifywait 监控单向变化时为什么不能直接套用双向逻辑
-
inotifywait只能监听本地文件系统事件(如MODIFY、CREATE、DELETE),它不知道远端是否已同步成功,更无法判断“这次修改是不是刚由远端同步过来的” - 若 A 监控 /data → 推给 B,B 同时监控 /data → 推回 A,一次保存就会触发两次推送:A→B→A→B… 形成无限循环
- 没有版本/时间戳/校验锁机制时,
rsync --delete在两边同时启用会导致互相删除对方新增文件
如何在 Linux 上实现接近“双向热备”的效果(单向为主 + 补偿机制)
- 使用
inotifywait -m -e modify,create,delete,move监控源目录,但只允许一个方向触发rsync - 目标端不运行
inotify监控自身目录,而是通过以下方式规避冲突:- 所有人工写入操作只在主节点进行,备节点挂载为只读(
mount -o ro,bind)或禁用本地编辑 - 若必须在备节点临时修改,先停掉同步脚本,手动
rsync -av --delete拉回主节点,再重启监控 - 在
rsync.sh中加入简单防重入锁:if [ -f /tmp/rsync.lock ]; then exit; fi; touch /tmp/rsync.lock; trap 'rm -f /tmp/rsync.lock' EXIT
- 所有人工写入操作只在主节点进行,备节点挂载为只读(
- 避免使用
--delete在生产环境无保护启用;改用--delete-after+--dry-run日志审计,每天凌晨补一次全量比对
inotify 内核参数调优是秒级响应的前提
默认值根本撑不住真实业务目录:
-
max_user_watches必须 ≥find /your/data/path -type d | wc -l的结果,否则会静默丢事件 -
max_queued_events小于 10 万就可能遇到<strong> Event Queue Overflow </strong>,尤其在批量上传或日志轮转时 - 这些不是临时生效命令,要写进
/etc/sysctl.conf并执行sysctl -p
真正需要双向热备的场景,inotify+rsync 不是合适工具。它本质是单向分发管道,复杂状态协调靠脚本兜底极易出错。如果业务要求严格双向、自动冲突解决、断网续传、多点协同,应该评估 lsyncd(带队列与延迟合并)、syncthing(内置冲突副本与版本控制)或商用方案如 Resilio Sync。用 inotify 硬上双向,最后花在 debug 循环同步和数据修复上的时间,远超换工具的成本。











