使用inotify + rsync和sersync实现文件的同步,并且总结两种方式的优缺点

使用inotify + rsync和sersync实现文件的同步,并且总结两种方式的优缺点

一、核心原理

1. inotify 原理

inotify 是Linux内核(2.6.13+)内置的文件系统事件监控接口,以「事件驱动」替代传统定时轮询:

  • 核心能力:实时捕获目录/文件的创建、删除、修改、移动、属性变更等事件,响应延迟仅毫秒级;
  • 资源占用:仅监控目标目录,无事件时CPU/内存占用趋近于0;
  • 核心工具:inotifywait(持续监控并输出触发事件的文件路径)、inotifywatch(统计事件频次,用于调试)。

2. rsync 原理

rsync 是Linux工业级增量同步工具,解决"全量拷贝耗带宽/资源"的问题:

  • 同步逻辑:首次同步全量拷贝文件,后续仅传输「文件差异部分」(通过MD5校验+分块对比);
  • 核心特性:
    • 免密同步:适配SSH免密,无需手动输入密码;
    • 压缩传输:-z参数压缩数据,降低网络带宽占用;
    • 一致性保障:--delete参数删除目标主机冗余文件,保持源/目标目录完全一致;
    • 属性保留:-a参数保留文件权限、时间戳、属主等属性。

3. sersync 原理

sersync 是基于 inotify+rsync 的二次开发工具,解决原生方案的核心痛点:

  • 原生痛点:短时间内高频修改同一文件(如1秒改3次),会触发3次rsync调用,浪费系统资源;
  • 核心优化:内置「事件队列」,合并5秒内的重复事件(如1秒改3次仅触发1次rsync);
  • 额外优势:
    • 配置化管理:通过XML文件整合监控规则、同步参数,无需编写shell脚本;
    • 多目标同步:支持同时同步到多台服务器;
    • 日志轮转:自动切割日志,避免日志文件过大。

二、环境说明

主机角色 IP地址 核心操作 依赖工具
源主机 10.0.0.12 部署监控同步服务、触发同步 inotify-tools/rsync/sersync
目标主机 10.0.0.15 接收同步数据 rsync(仅需接收能力)

三、详细安装步骤

1. 源主机安装核心依赖

bash 复制代码
# 命令1:安装EPEL第三方源(Rocky 9官方源无inotify-tools,必须先装)
yum install -y epel-release
# 作用:启用EPEL仓库(包含inotify-tools等第三方工具)
# 预期结果:提示"已安装"或"完毕",无报错

# 命令2:安装同步核心工具
yum install -y inotify-tools rsync wget tar
# 作用:
# - inotify-tools:提供inotifywait监控工具(inotify+rsync方案核心);
# - rsync:实现增量同步(所有方案均依赖);
# - wget/tar:下载解压sersync安装包(sersync方案需用);
# 验证安装:执行 inotifywait --help | head -1,输出版本号即成功

2. 目标主机基础配置

bash 复制代码
# 命令:创建同步目录+安装rsync(仅需接收同步数据)
mkdir -p /data/sync_dir && chmod 755 /data/sync_dir && yum install -y rsync
# 作用:
# - mkdir -p:递归创建目录,避免"目录不存在"报错;
# - chmod 755:保证root可读写,其他用户可读取,避免权限不足;
# - yum install rsync:安装接收同步的工具,无rsync则无法接收数据;
# 验证:ls -ld /data/sync_dir,输出 drwxr-xr-x 2 root root ... 即正常

四、方案1:inotify+rsync

1. 源主机配置SSH免密

bash 复制代码
# 命令:生成免密密钥对+推送公钥到目标主机
ssh-keygen -t rsa -b 2048 -N '' && ssh-copy-id root@10.0.0.15
# 逐段解释:
# - ssh-keygen -t rsa -b 2048 -N '':生成无密码的RSA密钥对(-N ''=空密码);
# - ssh-copy-id root@10.0.0.15:将公钥推送到目标主机,授权免密登录;
# 执行提示:输入目标主机root密码(仅首次需要);
# 验证免密:ssh root@10.0.0.15 "echo 免密成功",无密码提示且输出"免密成功"即生效

2. 源主机创建同步脚本

bash 复制代码
cat > /usr/local/bin/inotify_sync.sh << 'EOF'
#!/bin/bash
# ===================== 核心配置(可按需修改) =====================
SRC_DIR="/data/sync_dir"       # 源主机同步目录
DEST_HOST="10.0.0.15"          # 目标主机IP
DEST_USER="root"               # 目标主机登录用户(与免密配置一致)
DEST_DIR="/data/sync_dir"      # 目标主机同步目录(需与源主机一致)
LOG_FILE="/var/log/inotify_sync.log"  # 同步日志(排查问题核心)
EVENT_TYPES="create,delete,modify,move"  # 监控的事件类型
SLEEP_TIME=0.5  # 事件合并时间(0.5秒内重复事件仅触发1次同步)

# ===================== 初始化操作(避免运行报错) =====================
# 确保同步目录存在
mkdir -p ${SRC_DIR}
# 确保日志文件存在,避免写入失败
touch ${LOG_FILE}
# 给日志文件赋权,避免权限不足
chmod 644 ${LOG_FILE}

# ===================== 核心监控+同步逻辑 =====================
# 持续监控目录事件
inotifywait -mrq -e ${EVENT_TYPES} ${SRC_DIR} | while read FILE_PATH FILE_EVENT FILE_NAME
do
    # 合并短时间内的重复事件,降低rsync调用次数
    sleep ${SLEEP_TIME}
    
    # 执行增量同步(核心命令)
    rsync -avz --delete \
    ${SRC_DIR}/ \
    ${DEST_USER}@${DEST_HOST}:${DEST_DIR}/ \
    >> ${LOG_FILE} 2>&1
    
    # 记录同步日志(便于排查问题)
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] 事件:${FILE_EVENT} | 同步文件:${FILE_NAME} | 状态:完成" >> ${LOG_FILE}
done
EOF

3. 源主机启动&持久化服务

bash 复制代码
# 步骤1:给脚本添加执行权限(Linux脚本必须有x权限才能运行)
chmod +x /usr/local/bin/inotify_sync.sh

# 步骤2:创建systemd服务文件(实现开机自启+崩溃自动重启)
cat > /usr/lib/systemd/system/inotify-sync.service << 'EOF'
[Unit]
Description=Inotify+Rsync Real-Time Sync Service
After=network.target sshd.service  
# 网络、SSH启动后再启动本服务,避免依赖问题
Documentation=man:inotifywait(1) man:rsync(1)

[Service]
Type=simple  
# 简单服务类型(脚本持续运行,无复杂fork)
ExecStart=/usr/local/bin/inotify_sync.sh  
# 脚本绝对路径(必须准确)
Restart=always  
# 脚本崩溃/被杀死时,自动重启(核心保障)
RestartSec=3    
# 重启间隔3秒,避免频繁重启耗资源
User=root       
# 以root运行,保证目录读写权限
StandardOutput=append:/var/log/inotify_sync.log  
# 标准输出重定向到日志
StandardError=append:/var/log/inotify_sync.log   
# 错误输出重定向到日志

[Install]
WantedBy=multi-user.target  
# 多用户模式下开机自启(服务器默认模式)
EOF

# 步骤3:启动服务并设置开机自启
systemctl daemon-reload  # 重新加载systemd配置,识别新服务
systemctl start inotify-sync  # 启动同步服务
systemctl enable inotify-sync  # 设置开机自启
systemctl status inotify-sync  # 验证服务状态

# 状态验证标准:
# 1. 服务行显示 active (running)(绿色);
# 2. 无 red 报错信息;
# 3. 进程行能看到 inotify_sync.sh 进程。

4. 详细验证同步

bash 复制代码
# 场景1:创建文件同步
# 源主机执行
touch /data/sync_dir/test_create.txt && echo "创建文件测试" > /data/sync_dir/test_create.txt
# 目标主机验证(预期:文件存在+内容一致)
ssh root@10.0.0.15 "cat /data/sync_dir/test_create.txt"

# 场景2:修改文件同步
# 源主机执行
echo "新增修改内容" >> /data/sync_dir/test_create.txt
# 目标主机验证(预期:内容包含新增行)
ssh root@10.0.0.15 "cat /data/sync_dir/test_create.txt"

# 场景3:删除文件同步
# 源主机执行
rm -f /data/sync_dir/test_create.txt
# 目标主机验证(预期:文件不存在)
ssh root@10.0.0.15 "ls /data/sync_dir/test_create.txt"

# 场景4:目录+嵌套文件同步
# 源主机执行
mkdir -p /data/sync_dir/test_dir/sub_dir && touch /data/sync_dir/test_dir/sub_dir/nested.txt
# 目标主机验证(预期:目录和文件均存在)
ssh root@10.0.0.15 "ls /data/sync_dir/test_dir/sub_dir/nested.txt"

# 场景5:查看同步日志(验证事件记录)
# 源主机执行
tail -n 10 /var/log/inotify_sync.log
# 预期:日志包含上述所有操作的时间、事件类型、文件名,无 error 关键词。

五、方案2:sersync

1. 源主机安装sersync

bash 复制代码
# 步骤1:下载sersync预编译包(64位,兼容Rocky 9)
yum install -y wget
wget https://github.com/wsgzao/sersync/raw/master/sersync2.5.4_64bit_binary_stable_final.tar.gz -O /tmp/sersync.tar.gz

# 步骤2:创建安装目录(统一管理,便于维护)
mkdir -p /usr/local/sersync

# 步骤3:解压安装包(提取核心文件)
tar -zxvf /tmp/sersync.tar.gz -C /usr/local/sersync --strip-components=1

# 步骤4:验证安装(预期:看到 sersync2 可执行文件)
ls -l /usr/local/sersync/sersync2
# 输出:-rwxr-xr-x 1 root root ... sersync2 (有x权限即正常)

2. 源主机配置sersync

bash 复制代码
cat > /usr/local/sersync/confxml.xml << 'EOF'
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
    <host hostip="localhost" port="8008"></host>  <!-- 本地监控端口,无需修改 -->
    <debug start="false"/>  <!-- 调试模式:false=关闭(生产环境),true=开启(调试) -->
    <fileSystem xfs="true"/>  <!-- 文件系统:Rocky 9默认XFS,设为true;EXT4设为false -->
    
    <!-- 文件过滤规则:排除无需同步的文件类型 -->
    <filter start="true">
        <exclude expression="(.*)\.tmp"></exclude>  <!-- 排除.tmp临时文件 -->
        <exclude expression="(.*)\.log"></exclude>  <!-- 排除.log日志文件(可选) -->
        <exclude expression="\.DS_Store"></exclude>  <!-- 排除MAC系统隐藏文件 -->
    </filter>

    <!-- inotify监控事件配置(与inotify+rsync一致) -->
    <inotify>
        <delete start="true"/>        <!-- 监控删除事件 -->
        <createFolder start="true"/>  <!-- 监控目录创建事件 -->
        <createFile start="true"/>    <!-- 监控文件创建事件 -->
        <closeWrite start="true"/>    <!-- 监控文件写入完成事件(避免同步未写完的文件) -->
        <moveFrom start="true"/>      <!-- 监控文件移出事件 -->
        <moveTo start="true"/>        <!-- 监控文件移入事件 -->
        <attrib start="true"/>        <!-- 监控属性变更事件(权限/时间戳) -->
        <modify start="true"/>        <!-- 监控文件内容修改事件 -->
    </inotify>

    <sersync>
        <!-- 源主机同步目录(与inotify+rsync一致) -->
        <localpath watch="/data/sync_dir">
            <!-- 目标主机配置:ip=目标IP,name=同步目录(无需写全路径) -->
            <remote ip="10.0.0.15" name="sync_dir"/>
            <!-- 多目标同步示例(如需同步到多台,复制该行修改IP即可) -->
            <!-- <remote ip="10.0.0.16" name="sync_dir"/> -->
        </localpath>

        <!-- rsync同步参数配置(与inotify+rsync一致) -->
        <rsync>
            <commonParams params="-avz --delete"/>  <!-- 核心同步参数 -->
            <auth start="false"/>  <!-- 关闭rsync认证(用SSH免密即可) -->
            <timeout time="100"/>  <!-- 同步超时时间(秒) -->
            <ssh start="true"/>    <!-- 启用SSH免密同步(必须开启,与之前的免密配置适配) -->
        </rsync>

        <!-- 日志配置:自动轮转,避免日志过大 -->
        <log logfile="/var/log/sersync.log" logsize="10000000"/>  <!-- 10MB自动切割 -->
    </sersync>
</head>
EOF

# 验证配置文件(XML语法检查,避免配置错误)
xmllint /usr/local/sersync/confxml.xml
# 预期:输出配置文件内容,无 XML parse error 报错。

3. 源主机启动&持久化sersync

bash 复制代码
# 步骤1:先停止inotify-sync服务(避免端口/监控冲突)
systemctl stop inotify-sync

# 步骤2:创建sersync的systemd服务文件
cat > /usr/lib/systemd/system/sersync.service << 'EOF'
[Unit]
Description=Sersync Real-Time Sync Service
After=network.target sshd.service
Documentation=https://github.com/wsgzao/sersync

[Service]
Type=forking  
# sersync以守护进程运行,必须设为forking
# 启动命令解释:
# -d:后台运行;-r:首次启动全量同步;-o:指定配置文件路径
ExecStart=/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/confxml.xml
Restart=always  
# 崩溃自动重启
RestartSec=3
User=root
StandardOutput=append:/var/log/sersync.log
StandardError=append:/var/log/sersync.log

[Install]
WantedBy=multi-user.target
EOF

# 步骤3:启动服务并设置开机自启
systemctl daemon-reload
systemctl start sersync
systemctl enable sersync
systemctl status sersync

# 状态验证标准:
# 1. active (running);
# 2. ps -ef | grep sersync2 能看到进程;
# 3. 无报错信息。

4. 详细验证sersync

bash 复制代码
# 场景1:高频修改文件(验证事件合并)
# 源主机执行(1秒内修改3次同一文件)
for i in {1..3}; do
    echo "高频修改第${i}次" >> /data/sync_dir/high_freq.txt
    sleep 0.3
done

# 目标主机验证(预期:文件包含所有修改内容)
ssh root@10.0.0.15 "cat /data/sync_dir/high_freq.txt"

# 场景2:查看sersync日志(验证事件合并)
# 源主机执行
tail -n 5 /var/log/sersync.log
# 预期:仅看到1次rsync调用记录(3次修改合并为1次),无重复同步。

# 场景3:批量创建文件(验证高频同步效率)
# 源主机执行(1秒创建10个文件)
for i in {1..10}; do
    echo "批量文件${i}" > /data/sync_dir/batch_${i}.txt
    sleep 0.1
done

# 目标主机验证(预期:10个文件均存在,内容一致)
ssh root@10.0.0.15 "ls /data/sync_dir/batch_*.txt | wc -l"
# 输出:10(表示10个文件均同步成功)

六、完整运维手册

1. 服务启停命令

bash 复制代码
# inotify+rsync 服务
systemctl start inotify-sync   # 启动
systemctl stop inotify-sync    # 停止
systemctl restart inotify-sync # 重启
systemctl status inotify-sync  # 查看状态

# sersync 服务
systemctl start sersync   # 启动
systemctl stop sersync    # 停止
systemctl restart sersync # 重启
systemctl status sersync  # 查看状态

2. 常见问题排错

问题现象 排查步骤 解决方法
inotify-tools安装失败 执行 yum repolist grep epel,查看EPEL仓库是否启用
同步提示Permission denied 源主机执行 ls -ld /data/sync_dir,目标主机执行同样命令 chmod 755 /data/sync_dir && chown root:root /data/sync_dir
SSH免密失效 源主机执行 ssh root@10.0.0.15,查看是否需要输密码 重新执行 ssh-copy-id root@10.0.0.15
sersync启动失败 执行 journalctl -u sersync -n 20,查看报错;执行 xmllint 检查XML配置 修正XML配置语法错误,确保 适配文件系统
同步无反应 源主机执行 ps -ef grep inotifywait(或sersync2),查看进程是否存在

3. 日志管理

bash 复制代码
# 日志轮转配置(以inotify_sync.log为例)
cat > /etc/logrotate.d/inotify_sync << 'EOF'
/var/log/inotify_sync.log {
    daily          # 按天轮转
    rotate 7       # 保留7天日志
    compress       # 压缩旧日志
    missingok      # 日志不存在时不报错
    notifempty     # 空日志不轮转
    create 644 root root  # 轮转后创建新日志,权限644
}
EOF

# sersync日志轮转(同理)
cat > /etc/logrotate.d/sersync << 'EOF'
/var/log/sersync.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    create 644 root root
}
EOF

sersync 与 inotifywait+rsync 方案优缺点对比表

对比维度 sersync 方案 inotifywait + rsync 方案
系统兼容性 仅兼容 CentOS6/7 等旧系统;在 Rocky9/CentOS9 上因 glibc 版本过高,必然触发 core dump 崩溃 完全兼容所有主流 Linux 发行版(包括 Rocky9、CentOS9、Ubuntu22.04 等),无依赖兼容性问题
功能完整性 集成实时监控+rsync 同步+失败重试+日志记录+插件扩展(如 CDN 刷新) 核心功能覆盖(实时监控+rsync 同步),可通过脚本自定义日志、重试逻辑,无插件扩展
维护成本 项目多年未更新,无官方维护;遇到问题无解决方案,需手动修改源码适配 基于系统原生工具(inotify-tools/rsync),工具本身由系统发行版维护,问题可通过官方文档解决
配置复杂度 配置文件为 XML 格式,标签多、语法严格,易因标签未闭合等导致启动失败 配置通过 Shell 脚本实现,逻辑直观,参数简单,新手易上手
资源占用 二进制程序,占用内存较小(约 1-2MB) 脚本+两个进程(inotifywait/rsync),内存占用略高(约 3-5MB),可忽略不计
生产环境可用性 不推荐用于生产环境,兼容性问题导致服务不稳定,易中断同步 推荐用于生产环境,稳定可靠,是 Rocky9/CentOS9 实时同步的主流方案
故障排查难度 崩溃时仅输出 core dump 栈追踪,无明确报错信息,排查困难 可通过日志文件直接查看同步失败原因(如网络不通、权限不足),排查简单
扩展能力 支持插件机制,但插件功能老旧,无新版系统适配 可通过 Shell 脚本自由扩展(如增加邮件告警、多目标同步、过滤特定文件)

总结建议

适用场景 推荐方案
旧系统(CentOS6/7)、需要插件功能 sersync
新系统(Rocky9/CentOS9/Ubuntu22.04)、生产环境稳定需求 inotifywait + rsync
相关推荐
爱笑的眼睛112 小时前
PyTorch自动微分:超越基础,深入动态计算图与工程实践
java·人工智能·python·ai
qq_479875432 小时前
systemd-resolved.service实验实战3
linux·服务器·c++
AI浩2 小时前
SemOD:基于语义增强的多天气条件目标检测网络
网络·人工智能·目标检测
QT 小鲜肉2 小时前
【孙子兵法之终篇】《孙子兵法》真人阅读、朗读、讲解的视频链接
网络·笔记·音视频·读书·孙子兵法
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ2 小时前
java实现登录:多点登录互踢,30分钟无操作超时
java·前端
testpassportcn2 小时前
CompTIA A+ 220-1201 認證介紹|最新版本 A+ Core 1 220-1201 考試完整指南
网络·学习·改行学it
angushine2 小时前
服务器网络连接突然暴增如何分析
运维·服务器
Three K2 小时前
Redisson限流器特点
java·开发语言
Halo_tjn2 小时前
Java 多线程机制
java·开发语言·windows·计算机