linux服务-rsync+inotify文件同步-ssh
rsync+inotify 实战示例-ssh
rsync+inotify 是 Linux 下实时文件同步的经典方案,核心逻辑是 inotify 监控文件变化 + rsync 实现增量同步,二者协同实现 “实时响应、低耗高效” 的同步效果,广泛适用于数据备份、集群文件共享等场景。
一、原理
-
工具说明
- rsync:核心负责数据同步,支持本地或跨主机传输。首次同步全量复制,后续仅传输文件差异部分(基于校验和对比),同时能保留文件权限、时间戳等属性,还支持压缩传输节省带宽。
- inotify:Linux 内核级文件系统事件监控机制(2.6.13 内核以上支持),通过 inotify-tools 工具集(inotifywait 核心命令)实现实时监控,能捕获文件创建、删除、修改、移动等事件,无需轮询,资源消耗极低。
-
同步流程
-
初始化全量同步:先用 rsync 执行一次全量同步,确保源端和目标端初始数据一致;
-
实时事件监控:inotifywait 持续监控源端目录,捕获文件增 / 删 / 改 / 移等事件;
-
触发增量同步:一旦检测到事件,立即调用 rsync 执行增量同步,仅传输变化数据;
-
校验一致性:rsync 通过文件属性和数据块校验,确保目标端与源端数据完全一致。

-
-
关键技术特性
-
rsync 增量原理:先对比文件大小、修改时间,再校验数据块校验和,仅同步差异部分,效率极高;
-
inotify 监控优势:异步事件通知,支持递归监控目录,可自定义监控事件类型和排除规则;
-
支持两种认证方式:SSH 免密认证、rsync 协议认证。
认证协议 核心特点 适用场景 SSH 协议 无需启动 rsync 守护进程(daemon),无需配置 /etc/rsyncd.conf配置文件;依赖 SSH 登录认证(用户名 + 密码 / 密钥对),直接触发同步小型场景、临时同步、已配置 SSH 免密的环境 rsync 协议 需在服务端启动 rsync 守护进程,依赖 /etc/rsyncd.conf配置文件(定义同步模块、权限、认证信息等);通过配置文件中的认证用户 / 密码验证长期稳定同步、多客户端访问控制、批量设备同步场景
-
二、环境准备
-
适用场景
- 源端(监控 + 同步发起端):Linux(需 inotify 内核支持,
uname -r查看内核版本 ≥2.6.13); - 目标端(同步接收端):Linux/Windows(Windows 需安装 rsync 服务,如 cwRsync)。
- 源端(监控 + 同步发起端):Linux(需 inotify 内核支持,
-
单向同步与双向同步差异 --> 文档这里用双向同步
模式 核心逻辑 关键注意点 单向同步 A 监控本地 → 同步到 B(仅 A→B 方向) 无需担心冲突,仅 A 主动触发同步 双向同步 A 监控本地→同步到 B;B 监控本地→同步到 A(双向触发) 需避免 “循环同步” 和 “文件冲突”,核心是 “变化端主动同步,接收端不重复触发” -
主机信息(示例)
主机角色 主机名 IP 地址 本地监控 / 同步目录 对方主机同步目录 主机 A nodeA 192.168.189.129 /data/bidirroot@192.168.189.133:/data/bidir主机 B nodeB 192.168.189.133 /data/bidirroot@192.168.189.129:/data/bidir -
依赖安装(两台主机都执行)
yum install -y rsync inotify-tools -
双向 SSH 免密配置
# A\B主机都需要先创建 mkdir /data/bidir -pv# 步骤 1:在主机 A 执行(配置 A→B 免密) ssh-keygen -t rsa # 一路回车,无密码 ssh-copy-id root@192.168.189.133 # 复制公钥到 B ssh root@192.168.189.133 # 测试免密登录(成功则退出)# 步骤 2:在主机 B 执行(配置 B→A 免密) ssh-keygen -t rsa # 一路回车,无密码 ssh-copy-id root@192.168.189.129 # 复制公钥到 A ssh root@192.168.189.129 # 测试免密登录(成功则退出) -
初始化全量同步(确保初始数据一致)
rsync -avz --delete /data/bidir root@192.168.189.133:/data/bidir
三、双向同步实战示例
-
核心思路
两台主机分别部署相同逻辑的同步脚本:脚本监控本地目录变化,当捕获到文件增 / 删 / 改 / 移时,自动同步到对方主机,同时排除临时文件避免循环。
-
编写双向同步脚本(两台主机都需配置)
[root@node1 bidir]# cat ../synca.sh #!/bin/bash # # 直接指定监控目录(绝对路径,不拼接,避免错误) MONITOR_DIR="/data/bidir" LOCAL_DIR="$MONITOR_DIR/" # 源路径加 /,同步目录内内容 REMOTE_HOST="A填B地址,B填A地址" # 各填对方主机地址 REMOTE_DIR="/data/bidir/" REMOTE_USER="root" LOG_DIR=/data/templog# 仅过滤 vi 临时文件(不影响任何正常文件操作) EXCLUDE="--exclude='*.swp' --exclude='.*.swp' --exclude='*.swo' --exclude='.*.swo'" # rsync 强制删除参数:--delete 直接删除目标端多余文件 RSYNC_OPTS="-avz --delete $EXCLUDE" # inotify 仅保留基础事件,确保捕获删除 INOTIFY_EVENTS="create,delete,modify" # inotify 直接监控目标目录,不加任何冗余参数 INOTIFY_OPTS="-m -r -e $INOTIFY_EVENTS" # ======================================================# 检查监控目录是否存在(必做) if [ ! -d "$MONITOR_DIR" ]; thenecho "[$(date)] 错误:监控目录 $MONITOR_DIR 不存在!" > ${LOG_DIR}/bidir_force_delete.log 2>&1exit 1 fi# 初始化全量同步(确保两端初始一致) echo "[$(date)] 初始化同步到 $REMOTE_HOST" >> ${LOG_DIR}/bidir_force_delete.log rsync $RSYNC_OPTS $LOCAL_DIR $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR >> ${LOG_DIR}/bidir_force_delete.log 2>&1 echo "[$(date)] 初始化同步完成" >> ${LOG_DIR}/bidir_force_delete.log# 核心监控逻辑:强制捕获+强制同步 echo "[$(date)] 开始监控 $MONITOR_DIR(删除强制同步)" >> ${LOG_DIR}/bidir_force_delete.log inotifywait $INOTIFY_OPTS $MONITOR_DIR | while read -r dir events file; doFULL_PATH="$dir/$file"# 仅过滤 vi 临时文件的创建/修改(不影响任何正常文件)if [[ $file == *.swp || $file == .*.swp || $file == *.swo || $file == .*.swo ]]; thenif [[ $events == *"create"* || $events == *"modify"* ]]; thenecho "[$(date)] 忽略临时文件:$events $FULL_PATH" >> ${LOG_DIR}/bidir_force_delete.logcontinuefifi# 所有正常事件(create/delete/modify)直接触发同步,无延迟echo "[$(date)] 捕获事件:$events $FULL_PATH" >> ${LOG_DIR}/bidir_force_delete.log# 执行同步(强制删除目标端多余文件)rsync $RSYNC_OPTS $LOCAL_DIR $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR >> ${LOG_DIR}/bidir_force_delete.log 2>&1echo "[$(date)] 同步完成(强制同步,含删除)" >> ${LOG_DIR}/bidir_force_delete.log done-
自己编写时应注意
源路径格式 同步逻辑 示例(A 主机→B 主机) 结果(B 主机目录) 源路径不加 /同步 “目录本身” 到目标路径 A: /data/bidir→ B:/data/bidirB: /data/bidir/bidir(嵌套,错误)源路径加 /同步 “目录内的所有内容” 到目标路径 A: /data/bidir/→ B:/data/bidirB: /data/bidir/文件/子目录(正确,无嵌套)
-
-
脚本授权与前台测试
# 注意: 第一次执行的时候,数据在哪台哪台就先执行 chmod +x syncA.sh <-- 主机A bash syncA.shchmod +x syncB.sh <-- 主机B bash syncB.sh -
验证双向同步效果
# 创建a-z文件 tocuh /data/bidir/{a..z} touch /data/bidir/temp.tmp vim /data/bidir/edit.txt # 退出时产生 .edit.txt.swp 临时文件rm -rf {a..n} # 删除a-n文件 -
最后配成开机自启
[Unit] Description=Bidirectional Sync (nodeA ↔ nodeB) # 网络就绪后启动 After=network.target [Service] Type=simple # 关键:指定 root 用户(避免权限不足) User=root Group=root # 工作目录(脚本所在目录父级) WorkingDirectory=/data # 绝对路径:bash 解释器 + 脚本完整路径 ExecStart=/bin/bash /data/syncb.sh # 失败时自动重启 Restart=on-failure # 重启间隔 3 秒 RestartSec=3 # 输出日志 StandardOutput=append:/data/templog/syncA.log # 错误日志 StandardError=append:/data/templog/syncA_error.log[Install] # 多用户模式下启动 WantedBy=multi-user.target
四、inotifywait 与 rsync 参数
4.1、inotifywait 常用参数
-
常用参数
参数 核心作用 文档示例 备注说明 -m, --monitor持续监控事件(默认监控一次后退出) inotifywait -mrq /data实时同步必选参数 -r, --recursive递归监控目标目录及所有子目录 inotifywait -mrq /data监控多层目录结构时必需 -q, --quiet静默输出,仅打印关键事件信息(减少冗余日志) inotifywait -mrq /data生产环境推荐启用 -e, --event指定要监控的事件(如创建、删除等),多个事件用逗号分隔 inotifywait -mrq -e create,delete /data不指定则监控所有事件 --exclude <pattern>排除匹配正则表达式的文件 / 目录(不监控其事件) inotifywait --exclude='*.log' /data可过滤临时文件、日志文件 --excludei <pattern>与 --exclude功能一致,忽略大小写inotifywait --excludei='*.TMP' /data适配大小写不统一的场景 --format <fmt>自定义事件输出格式(如时间、目录、文件名、事件) --format "%T %w%f 事件信息: %e"常用格式符:% T(时间)、% w(目录)、% f(文件)、% e(事件) -o, --outfile <file>将事件日志输出到指定文件(而非 stdout) inotifywait -o /var/log/inotify.log /data便于日志归档排查 -s, --syslog将错误信息发送到系统日志(而非 stderr) inotifywait -s -mr /data统一日志管理时使用 -
常用监控事件(通过
-e指定)事件名称 作用说明 文档示例 create监控文件 / 目录的创建事件 inotifywait -e create /datadelete监控文件 / 目录的删除事件 inotifywait -e delete /datamodify监控文件内容被修改的事件 inotifywait -e modify /datamove监控文件 / 目录的移动(移入或移出监控目录) inotifywait -e move /data包含 moved_to和moved_from事件close_write监控文件以 “写入模式” 打开后关闭的事件(文件修改完成的标志) inotifywait -e close_write /data替代 modify更精准捕捉修改完成attrib监控文件 / 目录的属性变化(如权限、时间戳等) inotifywait -e attrib /data需同步属性时启用
4.2、rsync 常用参数
-
常用参数
参数 核心作用 文档示例 备注说明 -a, --archive归档模式(等价于 -rlptgoD),保留文件权限、时间戳、软链接等所有属性rsync -avz /data 目标端同步必选参数,确保数据一致性 -z, --compress传输时压缩数据,减少网络带宽占用 rsync -avz /data 目标端跨主机同步推荐启用 --delete删除目标端存在但源端没有的文件 / 目录,保持两端数据完全一致 rsync -az --delete /data 目标端无差异同步必需(谨慎使用) --password-file <file>指定密码文件(适用于 rsync 协议认证),避免手动输入密码 rsync --password-file=/etc/rsync.password 源端 目标端密码文件权限必须为 600 -r, --recursive递归同步目录( -a已包含此参数,单独使用仅递归不保留属性)rsync -rz /data 目标端不推荐单独使用,优先用 -a-p, --perms保留文件权限( -a已包含此参数)rsync -ap /data 目标端单独使用时仅保留权限 --exclude <pattern>排除指定文件 / 目录(不同步该文件 / 目录) rsync -avz --exclude='*.tmp' /data 目标端可过滤临时文件、冗余数据 --ignore-errors忽略同步过程中的非致命错误(如个别文件权限不足),继续同步其他文件 rsync -avz --ignore-errors /data 目标端
4.3、高频组合示例
-
inotifywait 监控组合
# 递归监控 /data 目录,捕获创建、删除、修改、移动事件,输出时间和事件详情 inotifywait -mrq --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件: %e" -e create,delete,modify,move /data -
rsync 同步组合(rsync 协议)
# 同步 /data 目录到目标端,保留属性、压缩传输、删除多余文件,使用密码文件认证 rsync -avz --delete --exclude='*.swp' --password-file=/etc/rsync.password /data rsync_backup@172.16.1.41::nfsbackup -
脚本整合组合(文档核心实战)
# 监控 /data 目录变化,触发 rsync 同步 inotifywait -mrq --format "%w%f" -e create,delete,close_write,move /data | while read line; dorsync -az --delete /data/ rsync_backup@172.16.1.41::nfsbackup --password-file=/etc/rsync.password done
五、排查
-
脚本未捕获 delete 事件?
-
直接在 A 主机执行纯监控命令(单独终端):
inotifywait -m -r -e create,delete,modify /data/bidir -
另开终端删除文件:
rm -f /data/bidir/test.txt -
若监控命令无:
DELETE test.txt -
输出:说明 inotify-tools 异常,重新安装:
yum remove -y inotify-tools && yum install -y inotify-tools
-
-
rsync 执行但未删除?
-
手动执行 rsync 命令(模拟脚本逻辑):
rsync -avz --delete --exclude='*.swp' --exclude='.*.swp' --exclude='*.swo' --exclude='.*.swo' /data/bidir/ root@192.168.1.100:/data/bidir/ -
观察输出:若包含
deleting xxx.txt,说明 rsync 正常,问题在脚本未触发; -
若不包含:检查 B 主机目录权限,临时开放最大权限:
ssh root@192.168.1.100 "chmod 777 /data/bidir/" -
重新执行手动 rsync 命令,再验证。
-
