1. 项目概述与核心价值最近在梳理几个业务系统的数据备份方案时我又把尘封的rsync和sersync这套组合拳拿出来打磨了一番。这听起来像是个老掉牙的技术栈对吧但恰恰是这种经过时间考验的方案在应对服务器目录实时同步、跨机房数据备份这类“脏活累活”时展现出了惊人的稳定性和效率。很多新手运维可能会直接奔向各种商业备份软件或云服务但对于追求可控性、低成本和高性能的团队来说自己动手搭建一套基于rsyncsersync的实时监控备份同步体系依然是性价比极高的选择。简单来说这个项目的核心目标就是当源服务器上指定目录里的文件发生任何变化增、删、改、属性变更都能在秒级内自动、可靠地同步到一台或多台备份服务器上。它解决的痛点非常明确——避免手动执行备份脚本的滞后和遗漏确保备份数据的时效性为数据安全加上一道自动化的保险。无论是代码发布后的同步、日志文件的集中归档还是作为数据库物理备份文件的分发通道这套方案都能胜任。接下来我就结合最近一次的实施经验把这套方案的里里外外、坑坑洼洼都拆解清楚。2. 技术选型与架构设计思路为什么是rsync加sersync而不是别的这背后是一套经过深思熟虑的权衡。2.1 核心组件角色解析首先得明白这两个工具各自扮演什么角色rsync它是同步操作的“执行引擎”。它的核心能力是增量同步和快速差异校验。通过独特的“rsync算法”它只传输源文件和目标文件之间的差异部分对于大文件或频繁小改动的场景能极大节省网络带宽和传输时间。它支持通过SSH加密传输也支持以守护进程daemon模式运行提供网络服务功能强大且配置灵活。sersync它是触发同步的“监控大脑”。它利用Linux内核的inotify机制实时监控指定目录下文件系统的变化事件。一旦检测到有文件被修改、创建、删除或移动它就会立刻触发一个预定义的动作——通常就是调用rsync命令将发生变化的文件同步到远程服务器。sersync对inotify的使用做了优化解决了单个进程监控文件数有限制、递归目录监控等问题并且自带失败重传和过滤机制比单纯写inotifywait脚本要健壮得多。2.2 架构模式选择在实际部署时通常有两种架构模式推送模式Push这是最常用的模式。sersync和rsync客户端部署在源服务器数据产生端。由sersync监控本地目录变化发生后主动调用rsync将数据推送到备份服务器。这种模式主动权在源端备份服务器相对被动只需启动rsync daemon服务接收数据即可。拉取模式Pullrsync客户端部署在备份服务器由备份服务器定期或通过其他触发方式主动从源服务器拉取数据。这种模式更适用于从多个源收集数据到一处但实时性不如推送模式。我们这个项目采用推送模式因为它能实现最快的实时响应。架构很简单源服务器上跑sersync备份服务器上跑rsync daemon。sersync监听到事件就通过rsync协议将数据推送到备份服务器的daemon端口。2.3 与其他方案的简单对比lsyncd也是一个利用inotify/fsevents的同步工具功能上与sersync类似配置语法不同。sersync的XML配置对某些用户来说更直观且其多线程同步和过滤功能在某些场景下更高效。商业备份软件如Veeam、Commvault等功能全面管理界面友好但成本高昂且可能过于“重型”。云存储同步如AWS S3 Sync、阿里云OSS工具适合云原生环境但可能涉及数据出云、长期存储成本等问题。纯rsynccron通过定时任务执行无法做到实时总有数据窗口期。选择rsyncsersync就是在成本、可控性、实时性和可靠性之间找到了一个优秀的平衡点。3. 环境准备与核心组件部署理论说完我们进入实战环节。假设我们有两台CentOS 7服务器源服务器SourceIP为 192.168.1.100需要同步的目录是/data/app/logs。备份服务器BackupIP为 192.168.1.200接收数据的目录是/backup/app_logs。3.1 备份服务器配置安装并配置 rsync daemon首先在备份服务器上操作配置rsync以守护进程模式运行等待接收数据。安装 rsync通常系统已自带若无则安装。yum install -y rsync # CentOS/RHEL # 或 apt-get install -y rsync # Ubuntu/Debian编辑 rsync 守护进程配置文件/etc/rsyncd.conf# 全局配置 uid root gid root use chroot no max connections 10 pid file /var/run/rsyncd.pid lock file /var/run/rsync.lock log file /var/log/rsyncd.log timeout 300 # 模块配置这里定义一个名为 [app_logs_backup] 的模块 [app_logs_backup] path /backup/app_logs # 备份服务器上的真实路径 comment Application logs backup directory read only no # 非只读允许写入 list yes # 允许列出模块 auth users rsync_user # 认证用户名 secrets file /etc/rsync.passwd # 密码文件路径 hosts allow 192.168.1.100 # 只允许源服务器IP连接重要注意use chroot设为no可以避免一些权限路径问题但安全性稍降。在生产环境如果目录结构固定可以设为yes并做好路径映射。hosts allow是重要的安全配置务必限定IP。创建认证密码文件/etc/rsync.passwdecho rsync_user:YourSecurePassword123 /etc/rsync.passwd chmod 600 /etc/rsync.passwd # 关键必须限制权限否则rsync会报错格式为用户名:密码。创建备份目录并启动服务mkdir -p /backup/app_logs chmod 755 /backup/app_logs # 启动rsync守护进程以daemon模式运行 rsync --daemon --config/etc/rsyncd.conf可以将其加入开机自启echo “/usr/bin/rsync --daemon --config/etc/rsyncd.conf” /etc/rc.local chmod x /etc/rc.d/rc.local验证服务在备份服务器上执行netstat -tlnp | grep 873应看到rsync在监听873端口。3.2 源服务器配置安装 sersync 与 rsync 客户端安装 rsync 客户端同样确保rsync命令可用。yum install -y rsync下载并部署 sersyncsersync是国人开发的项目我们需要去其开源地址下载二进制包。这里以64位系统为例。wget https://github.com/wsgzao/sersync/raw/master/sersync2.5.4_64bit_binary_stable_final.tar.gz tar -zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz -C /opt/ mv /opt/GNU-Linux-x86/ /opt/sersync cd /opt/sersync目录下关键文件是sersync2主程序和confxml.xml配置文件。配置 sersync编辑/opt/sersync/confxml.xml这是核心。?xml version1.0 encodingISO-8859-1? host hostiplocalhost port8008/host !-- 本地调试端口一般不改 -- debug startfalse/ !-- 是否开启调试正式运行设为false -- fileSystem xfsfalse/ !-- 是否使用xfs文件系统一般false -- filter startfalse !-- 过滤规则如不需要过滤可关闭 -- exclude expression(.*)\.svn/exclude exclude expression(.*)\.gz/exclude exclude expression^info/*/exclude /filter inotify !-- inotify监控参数 -- delete starttrue/ !-- 监控删除事件 -- createFolder starttrue/ !-- 监控创建文件夹 -- createFile starttrue/ !-- 监控创建文件 -- closeWrite starttrue/ !-- 监控关闭写操作即文件修改完成 -- moveFrom starttrue/ !-- 监控移动出 -- moveTo starttrue/ !-- 监控移动到 -- attrib starttrue/ !-- 监控属性变更 -- modify starttrue/ !-- 监控修改 -- /inotify sersync localpath watch/data/app/logs !-- 要监控的本地目录 -- remote ip192.168.1.200 nameapp_logs_backup/ !-- 远程rsync模块 -- !--remote ip192.168.1.201 namebackup/-- !-- 可配置多个备份目标 -- /localpath rsync !-- rsync命令配置 -- commonParams params-artuz/ !-- rsync参数a归档模式r递归t保持时间u跳过更新的z压缩 -- auth starttrue usersrsync_user passwordfile/etc/rsync.passwd/ !-- 启用认证 -- userDefinedPort startfalse port874/!-- 非默认端口时使用 -- timeout startfalse time100/!-- 超时设置 -- ssh startfalse/ !-- 是否使用ssh协议我们用的是rsync daemon模式所以为false -- /rsync failLog path/tmp/rsync_fail_log.sh timeToExecute60/!-- 失败重传脚本 -- crontab startfalse schedule600!-- 定时全量同步作为实时同步的补充 -- crontabfilter startfalse exclude expression*.php/exclude exclude expressioninfo/*/exclude /crontabfilter /crontab plugin startfalse namecommand/ !-- 插件功能 -- /sersync关键配置解读localpath watch/data/app/logs指定监控目录。remote ip... name...对应备份服务器的IP和rsyncd.conf中定义的模块名。commonParams params-artuz-a是归档模式包含递归、保持属性等-r递归-t保持时间-u跳过目标端更新的文件避免覆盖-z传输时压缩。这是常用组合。auth starttrue ...启用密码认证passwordfile是源服务器上存放密码的文件。在源服务器创建密码文件echo YourSecurePassword123 /etc/rsync.passwd # 注意这里只有密码没有用户名 chmod 600 /etc/rsync.passwd重要区别在rsync客户端源服务器如果使用rsync daemon协议且配置了auth users密码文件只需包含密码。如果使用ssh协议则是另一套密钥认证。创建待监控目录mkdir -p /data/app/logs4. 同步流程与核心配置详解配置完成后我们来深入理解整个同步流程和配置中的关键点。4.1 实时同步触发流程用户或进程在/data/app/logs目录下创建、修改或删除一个文件example.log。Linux内核的inotify子系统捕获到该事件并通知正在监听的sersync进程。sersync解析事件类型如close_write并根据confxml.xml中的过滤规则判断是否需要处理。如果需要同步sersync会组装rsync命令。例如对于修改事件命令类似于/usr/bin/rsync -artuz /data/app/logs/example.log rsync_user192.168.1.200::app_logs_backup --password-file/etc/rsync.passwdrsync客户端连接备份服务器的873端口进行认证并开始计算文件差异。利用rsync算法只传输文件中变化的部分如果是文本文件可能是变化的行如果是二进制文件则是变化的块。传输完成后备份服务器上的文件example.log与源服务器保持同步。4.2 关键配置参数深度解析inotify事件选择不是所有事件都需要监控。例如close_write通常比modify更高效因为它确保在文件写入完成后再触发同步避免同步到一半的文件。对于临时文件如.swp,.tmp可以通过filter排除。rsync参数-a与-u-a是“归档”模式它等价于-rlptgoD意味着保持符号链接、递归、保持权限、时间戳、组、所有者等。-u--update是精髓之一它让rsync跳过目标端修改时间比源端更新的文件。这在某些特殊场景下比如备份服务器文件被手动恢复过能防止旧数据覆盖新数据。--delete参数的使用我们的配置里没有加--delete。这意味着如果在源服务器删除文件备份服务器不会自动删除。这是出于数据安全考虑防止误删操作被同步。如果你需要严格的镜像同步可以在commonParams中加入--delete但务必谨慎并确保有额外备份。多目标同步confxml.xml支持配置多个remote节点可以将数据同时推送到多个备份服务器实现冗余。失败重传机制failLog path/tmp/rsync_fail_log.sh timeToExecute60/这个配置非常有用。当某次同步失败时失败的rsync命令会被记录到指定脚本。sersync会每隔timeToExecute秒这里是60秒尝试重新执行这个脚本直到成功。这有效应对了网络闪断等临时故障。5. 启动、测试与日常运维5.1 启动服务与测试在备份服务器确保rsync daemon已运行。在源服务器启动sersynccd /opt/sersync ./sersync2 -d -r -o ./confxml.xml-d以守护进程模式运行。-r在启动时先做一次全量同步基于监控目录的当前状态。-o指定配置文件。还可以加-n参数指定线程数默认为10对于大量小文件可以适当调高。测试实时同步在源服务器/data/app/logs/下创建一个测试文件touch test_sync.txt。立即到备份服务器的/backup/app_logs/目录下查看文件应该几乎瞬间出现。在源服务器向文件写入内容echo hello rsync test_sync.txt。检查备份服务器上的文件内容是否更新。在源服务器删除该文件rm test_sync.txt。由于我们没有启用--delete备份服务器的文件应该还在。查看日志源服务器sersync日志默认输出到终端启动后可以重定向到文件。也可以查看系统日志/var/log/messages中与rsync相关的条目。备份服务器的日志在/var/log/rsyncd.log可以查看连接和传输记录。5.2 将 sersync 加入系统服务为了方便管理我们可以为sersync创建 systemd 服务。在源服务器创建文件/etc/systemd/system/sersync.service[Unit] DescriptionSersync File Real-Time Synchronization Daemon Afternetwork.target [Service] Typeforking ExecStart/opt/sersync/sersync2 -d -r -o /opt/sersync/confxml.xml ExecStop/bin/kill -TERM $MAINPID Restarton-failure RestartSec10 Userroot Grouproot [Install] WantedBymulti-user.target然后使用systemctl命令管理systemctl daemon-reload systemctl start sersync systemctl enable sersync systemctl status sersync6. 性能调优与高级技巧当同步目录文件数量巨大数十万以上或更新极其频繁时需要进行一些优化。6.1 针对海量小文件的优化inotify本身有监控队列上限/proc/sys/fs/inotify/max_user_watches默认可能只有8192。对于海量文件目录需要调整echo 999999 | sudo tee /proc/sys/fs/inotify/max_user_watches echo 999999 | sudo tee /proc/sys/fs/inotify/max_user_instances为了使配置永久生效编辑/etc/sysctl.conf添加fs.inotify.max_user_watches999999 fs.inotify.max_user_instances999999执行sysctl -p生效。6.2 rsync 传输优化带宽限制如果同步占用过多生产带宽可以在commonParams中加入--bwlimitRATE单位KB/s例如--bwlimit10240限制为10MB/s。压缩传输-z参数在传输时进行压缩对文本、日志类文件效果显著但会消耗CPU。如果网络是瓶颈而CPU空闲建议开启如果文件已经是压缩格式如jpg, zip则可以关闭。部分同步通过filter规则可以排除临时文件、缓存文件等不需要同步的内容减少不必要的传输和监控压力。6.3 使用 rsync over SSH 的替代方案我们上面用的是rsync daemon模式。另一种常见模式是rsync over SSH它利用SSH加密通道无需在备份服务器单独配置rsyncd更简单但性能可能略低于daemon模式。修改confxml.xmlrsync commonParams params-artuz/ auth startfalse/ !-- 关闭daemon认证 -- userDefinedPort startfalse port22/ timeout startfalse time100/ ssh starttrue/ !-- 启用SSH -- /rsync同时需要配置源服务器到备份服务器的SSH密钥免密登录。这种方式下remote配置中的name就变成了远程路径例如remote ip192.168.1.200 name/backup/app_logs/。7. 常见问题排查与故障恢复即使方案再成熟运维过程中也难免遇到问题。这里记录几个典型场景和排查思路。7.1 同步延迟或不同步检查sersync进程状态ps aux | grep sersync看进程是否在运行。检查系统资源CPU、内存、IO是否过载。检查inotify限制cat /proc/sys/fs/inotify/max_user_watches如果监控的文件数接近或超过此值事件会丢失导致不同步。按6.1节调整。检查sersync日志启动时加-d -o confxml.xml但不加-d参数在前台运行观察输出信息。手动测试rsync命令在源服务器手动执行sersync会触发的rsync命令可以从日志或失败脚本中获取看是否能成功。这能快速定位是网络问题、认证问题还是路径问题。检查备份服务器rsyncd日志/var/log/rsyncd.log会记录连接和错误信息。7.2 权限问题错误提示ERROR: auth failed on module检查备份服务器/etc/rsync.passwd文件权限是否为600检查用户名密码是否正确。错误提示ERROR: chroot failed检查rsyncd.conf中use chroot设置和path路径权限。如果use chroot yes则path指定的路径及其所有上级目录属主必须是rsyncd.conf中指定的uid通常是root且不能有软链接指向外部。同步后文件属主发生变化确保rsyncd.conf中的uid和gid设置正确并且备份服务器上存在对应的用户/组。也可以考虑在rsync参数中加入-o(保持属主) 和-g(保持属组)但要求rsync以root身份运行且有相应权限。7.3 网络中断与数据一致性网络闪断依靠failLog机制会自动重试。长时间中断如果源端和备份端都持续有写入长时间中断后再恢复可能会因文件冲突导致同步混乱。此时建议暂停源端应用写入。在源端使用rsync做一次全量对比同步rsync -avn先模拟rsync -av执行确保两端基础一致。清空sersync的失败队列删除/tmp/rsync_fail_log.sh或类似文件。重启sersync服务。恢复应用。定期全量校验虽然实时同步很可靠但仍建议每周或每月在业务低峰期通过一个独立的cron任务执行一次rsync -avn模拟运行或rsync -avc使用校验和检查文件内容慢但彻底来校验两端数据一致性。这可以作为最后一道防线。7.4 资源占用过高CPU/IO过高可能是rsync在计算大量文件的差异。考虑调整sersync的同步延迟参数在配置文件中默认是立即同步可以合并短时间内的大量事件一次同步。或者优化过滤规则减少不必要的文件监控。内存占用sersync本身不占太多内存。如果rsync传输大文件时内存高是正常现象。监控整体系统内存即可。8. 监控与告警集成一个健壮的备份系统离不开监控。除了检查进程是否存在我们还需要监控同步状态本身。8.1 基础进程监控使用如Supervisor、systemd的自愈功能或简单的cron脚本检查进程是否存在不存在则重启。#!/bin/bash # check_sersync.sh if ! pgrep -x sersync2 /dev/null then systemctl start sersync echo $(date): sersync restarted /var/log/sersync_monitor.log fi将脚本加入crontab每分钟执行一次。8.2 同步延迟监控这是更高级的监控。思路是在源端监控目录下定期如每分钟生成一个带有时间戳的“心跳文件”然后在备份端检查这个文件的时间戳。如果时间戳与当前时间差超过阈值如5分钟则发出告警。源端生成心跳文件cron job*/1 * * * * echo $(date %s) /data/app/logs/.sync_heartbeat备份端检查脚本cron job#!/bin/bash HEARTBEAT_FILE/backup/app_logs/.sync_heartbeat THRESHOLD300 # 5分钟单位秒 if [[ -f $HEARTBEAT_FILE ]]; then file_time$(cat $HEARTBEAT_FILE) current_time$(date %s) time_diff$((current_time - file_time)) if [[ $time_diff -gt $THRESHOLD ]]; then # 发送告警例如通过邮件、钉钉、企业微信等 echo 警告rsync同步延迟超过 ${THRESHOLD}秒当前延迟 ${time_diff}秒。 | mail -s 同步延迟告警 adminexample.com fi else echo 警告心跳文件不存在同步可能已停止。 | mail -s 同步停止告警 adminexample.com fi8.3 日志分析与告警定期分析备份服务器的/var/log/rsyncd.log和源服务器的sersync运行日志如果重定向了搜索error,failed,timeout等关键字通过日志收集系统如ELK或简单脚本汇总并触发告警。这套rsyncsersync的方案就像一位沉默寡言但极其可靠的老兵在无数个深夜默默地守护着数据的一致性。它的价值不在于技术的新颖而在于极致的简单、稳定和高效。在实施过程中最关键的是理解其工作流程合理配置过滤和参数并建立有效的监控和校验机制。当它平稳运行起来后你几乎会忘记它的存在——而这正是一个好的基础设施工具该有的样子。