两台Linux服务器共享文件夹同步,最靠谱的方案是用rsync配合inotify实现实时单向同步,或者用lsyncd做自动触发同步,双向同步则用unison。这几种工具都是开源免费的,在行业内用了很多年,稳定性经得起考验,接下来我会把这几种方案的具体配置步骤、适用场景和坑都讲清楚,帮你少走弯路。
两台linux服务器共享文件夹同步,先搞清楚你要单向还是双向
动手配置之前,先想明白一个核心问题:你的两台服务器数据流是单向的,还是双向的?
单向同步的场景很常见,比如主备架构,一台主服务器写数据,备份服务器只需要定期或者实时拉取主服务器的变更,这种情况用rsync就足够了,成本低,配置简单,带宽占用也可控。
双向同步则复杂得多,比如两台服务器都在对外提供服务,都有可能写入文件,需要互相合并,这种情况直接用rsync会出问题,因为rsync的镜像逻辑是“以源端为准”,两边互相覆盖会丢数据,得用unison这类专门做双向同步的工具,或者干脆上分布式文件系统(比如GlusterFS、Ceph),但后者架构重,小规模场景没必要。
另外还要考虑同步的实时性要求,如果允许几分钟的延迟,crontab定时rsync就够了,如果要求秒级响应,比如用户刚上传的文件立刻要在另一台服务器能访问到,那就要用inotify或lsyncd配合rsync做事件触发。
rsync+inotify实现linux服务器文件夹实时同步,配置步骤详解
这是目前用得最多的组合方案,rsync负责传输,inotify负责“盯着”目录变化,一旦有文件被创建、修改、删除,立刻触发rsync去同步。
环境假设和准备工作
假设有两台服务器,A服务器(源端)IP是192.168.1.10,B服务器(目标端)IP是192.168.1.20,我们要把A服务器上/data/wwwroot这个目录下的所有文件实时同步到B服务器的/data/wwwroot。
先检查两台服务器是否装了rsync:
rsync --version
如果没有,用包管理器装一下:
# CentOS/RHEL yum install -y rsync # Ubuntu/Debian apt-get install -y rsync
inotify-tools也需要装:
# CentOS/RHEL yum install -y inotify-tools # Ubuntu/Debian apt-get install -y inotify-tools
Linux内核从2.6.13版本开始就内置了inotify机制,所以不用额外打补丁,直接装工具集就能用。
配置SSH免密登录,让rsync能自动拉起
rsync走SSH通道是最省事的做法,不用单独启动rsync守护进程,先给A服务器生成密钥,然后把公钥放到B服务器上:
# 在A服务器执行 ssh-keygen -t rsa -b 4096 ssh-copy-id root@192.168.1.20
注意:
- 生产环境建议用专用同步账号,别直接用root,权限控制得更精细。
- 如果两台服务器之间有防火墙,记得放行22端口。
- 密钥一定要设置好权限,
chmod 600,否则SSH会拒绝使用。
编写inotify监控脚本
这是整个方案的核心,创建一个脚本文件/root/sync.sh:
#!/bin/bash
SRC_PATH=/data/wwwroot
DEST_SERVER=root@192.168.1.20
DEST_PATH=/data/wwwroot
/usr/bin/inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format '%w%f'
-e create,modify,delete,move,attrib ${SRC_PATH}
| while read file
do
/usr/bin/rsync -avz --delete --progress ${SRC_PATH} ${DEST_SERVER}:${DEST_PATH}
done
脚本的逻辑很简单:
-m表示持续监控,-r递归子目录,-q静默模式。-e指定要监控的事件:创建、修改、删除、移动、属性变更。- 一旦有事件发生,就把整个目录同步过去。
给脚本加执行权限,然后放后台跑:
chmod +x /root/sync.sh nohup /root/sync.sh > /dev/null 2>&1 &
脚本的坑和优化
别高兴太早,这个脚本有几个问题需要注意。
频繁触发导致rsync跑不完又启动新进程。 如果目录里文件很多,rsync传一次可能要几秒,但inotify事件可能一秒刷几十条,脚本会疯狂fork rsync进程,得加个锁:
#!/bin/bash
LOCK_FILE=/tmp/rsync_sync.lock
# 检查是否已有同步进程在跑
if [ -f "$LOCK_FILE" ]; then
PID=$(cat $LOCK_FILE)
if kill -0 $PID 2>/dev/null; then
exit 0
fi
fi
echo $$ > $LOCK_FILE
inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format '%w%f'
-e create,modify,delete,move,attrib /data/wwwroot
| while read file
do
# 用flock避免并发
flock -n 200
/usr/bin/rsync -avz --delete /data/wwwroot root@192.168.1.20:/data/wwwroot
flock -u 200
done 200>$LOCK_FILE
--delete参数双刃剑。 它保证目标端和源端完全一致,源端删了文件,目标端也会删,这在一个方向上是安全的,但如果有人误操作删了源端文件,目标端也会被删,根据实际需求决定是否保留这个参数。
大量小文件的场景效率低。 如果目录里是几万个图片文件,事件触发会很密集,建议把-e参数里的attrib事件去掉,减少无谓的触发,很多情况下,只监控create,modify,delete就够用了。
服务器重启后脚本不会自动启动。 把nohup那行写进/etc/rc.local,或者用systemd搞成一个服务,才能保证开机自启。
lsyncd让linux服务器文件实时同步更省心,配置更简洁
如果你觉得手写inotify脚本太麻烦,可以试试lsyncd,它把inotify和rsync包装成了配置文件,思路是一样的,但管理起来规范得多,支持故障自动重试,行为更可预测。
安装lsyncd:
# CentOS/RHEL yum install -y lsyncd # Ubuntu/Debian apt-get install -y lsyncd
编辑配置文件/etc/lsyncd.conf:
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
inotifyMode = "CloseWrite",
maxProcesses = 8,
maxDelays = 5
}
sync {
default.rsyncssh,
source = "/data/wwwroot",
host = "root@192.168.1.20",
targetdir = "/data/wwwroot",
excludeFrom = "/etc/lsyncd-exclude.lst",
rsync = {
archive = true,
compress = true,
delete = true,
whole_file = false
}
}
解释一下关键配置:
default.rsyncssh:通过SSH隧道跑rsync,不需要目标端开rsync服务。inotifyMode = "CloseWrite":只在文件关闭写入后触发,减少中间态事件。maxDelays:合并事件延迟,如果5秒内没新事件就执行同步,避免频繁触发。
排除文件列表/etc/lsyncd-exclude.lst,用法和rsync的exclude类似:
.tmp
.swp
.git/
cache/
启动lsyncd:
systemctl start lsyncd systemctl enable lsyncd
lsyncd适合中等规模场景,业内专家指出,当同步文件数量级达到百万以上时,lsyncd的inotify事件处理也可能成为瓶颈,建议考虑分布式文件系统方案。
两台linux服务器双向文件同步用什么工具,unison了解一下
如果两台服务器都要写文件,那上面说的单向同步就不好使了,unison是双向同步的老牌工具,它记录每个文件的同步状态,能检测出哪些文件在哪一端被修改过,然后尝试合并。
举个例子:A服务器改了config.php,B服务器改了logo.png,unison会同时保留两边的修改,再把对方的变更拉到本地,如果同一个文件在两台服务器的修改时间相差不大且内容不同它会检测到冲突,然后根据配置决定保留哪一份,或者让你手动处理。
安装unison:
# 两台服务器都需要安装 yum install -y unison # 或 apt-get install -y unison
然后编写同步配置,比如/root/sync/unison-default.prf:
root = /data/wwwroot
root = ssh://root@192.168.1.20//data/wwwroot
batch = true
auto = true
times = true
terse = true
silent = true
logfile = /var/log/unison.log
跑一次同步测试:
unison unison-default.prf -testServer
确认没问题后,用crontab定时跑双向同步:
/5 /usr/bin/unison /root/sync/unison-default.prf >> /var/log/unison.log 2>&1
不过说实话,双向同步是个高风险操作。 除非业务真的需要两台服务器同时读写同一份数据,否则不建议这么做,因为一旦出现冲突,你很难判断哪一份文件才是“正确”的,与其双向,不如好好评估业务架构,看看能不能把写操作收敛到一台服务器上,另一台只读。
同步之外的可选方案:分布式文件系统
如果两台服务器的数据用rsync同步不过来比如数据量上百TB,文件数量上千万,或者在网络丢失时两端都要保持读写能力那就得考虑上分布式文件系统了。
GlusterFS是目前比较轻量的选择,它把多台服务器的磁盘聚合为一个全局命名空间,客户端直接挂载使用,数据在后端自动复制多份,配置简单,没有中心节点,两台服务器组一个replica 2卷就够了。
Ceph则是重量级的,适合规模更大、需要高可靠性的场景,但它需要至少3个节点起步,运维成本明显高不少。
对于绝大多数只有两台服务器、数据量几百GB到几TB的场景,老老实实用rsync或lsyncd就够了,没必要上分布式文件系统给自己增加维护负担,分布式文件系统的架构复杂度是“非必要不上”的,上了可能比业务本身还难维护。
全量对比:几种Linux服务器共享文件夹同步方案选型参考
| 方案 | 同步方向 | 实时性 | 配置难度 | 适用场景 | 风险点 |
|---|---|---|---|---|---|
| crontab + rsync | 单向 | 分钟级延迟 | 低 | 备机、异地灾备 | 数据丢失窗口大 |
| inotify + rsync | 单向 | 秒级 | 中 | 主备实时同步、Web文件发布 | 脚本自身稳定性和并发控制 |
| lsyncd | 单向 | 秒级 | 低 | 生产环境主备同步 | 无内置web管理界面 |
| unison | 双向 | 分钟级 | 中 | 双活写场景 | 冲突处理机制依赖人工 |
| GlusterFS | 双向 | 实时 | 较高 | 大数据量双活 | 需要客户端兼容、架构较重 |
行业共识认为,没有哪套方案是万能的,选择的关键是匹配你的业务支撑能力,如果只有一台运维人员兼职维护,那crontab+rsync是性价比最高的起点。
同步做完之后,验证和监控别忘掉
配置完成后,一定要做一次完整的验证,确认数据真的同步过去了,光看rsync退出的状态码不够,建议做这几步验证:
- 全量同步对比,统计源端和目标端的文件总数和大小是否一致:
find /data/wwwroot -type f | wc -l
find /data/wwwroot -type f -size +1M -exec md5sum {} ; | sort > /tmp/source.md5
再把目标端同样的命令结果拿过来对比一下。
-
故障恢复测试,模拟源端服务器宕机、网络中断,看目标端数据是否可用,恢复后同步是否能自动追上。
-
监控日志,重点关注rsync的报错信息,尤其要留意
Connection refused等网络错误,以及No space left on device这类磁盘耗尽错误,日志里Permission denied出现的次数多了,就要检查文件权限是否稳定。
日常运维中,跑完同步任务花几分钟检查一下日志是值得的,总比哪天用户反馈文件缺失了再排查要省事得多。
常见问题排查
Q:rsync同步到一半报错,提示“Broken pipe”,是哪里出了问题?
A:这个错误多数是网络不稳定或SSH连接超时导致的,检查一下两台服务器之间的物理链路,看一看网卡有没有丢包,如果传输的是大文件,建议把rsync的--partial参数加上,断点续传,不然每次都从头传,大文件根本传不完。
Q:inotifywait脚本一直在跑,但文件变更后目标端没有更新,可能是什么情况?
A:先确认脚本确实在监控源目录,看看ps aux | grep inotifywait的输出,然后手动在源目录touch一个文件,观察脚本有没有被触发如果触发了但rsync没跑,手动执行脚本里的rsync命令,排查是不是SSH免密登录失效了,密钥过期或者authorized_keys文件被改动,是最常见的黑手。
另外也得注意,inotify默认监控的目录层次是有限制的如果你的目录层级特别深,需要用--recursive确保子目录也被监控到。
Q:两台服务器共享文件夹同步用什么工具性价比最高?
A:对于大多数场景,rsync就是最佳选择,它免费开源、Linux自带、不需要装额外依赖、增量传输省带宽,如果你连定时任务都不想配,想更自动化一点,那就用lsyncd花费的学习成本很低,但换来的是更可靠的触发机制和更清晰的日志,至于unison和分布式文件系统,只有在双向写这种特定需求下才值得考虑,投资回报比反而不高。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/677428.html





