在两个 Linux
之间进行文件同步的实践有很多,rsync + inotify
是一个很常见的方案,本文主要介绍基于该方案改进后的 gosync
实现更高效的文件同步。
rsync + inotify
rsync
是 Linux
的一个常用程序,可运行在客户端模式和服务端模式下,实现两个服务器之间的文件同步,而 inotify
则是监听文件系统的变化,配合脚本启动 rsync
客户端实现将变化推送到服务端。脚本一般是用 Shell
写的,功能比较简单,很难进行精细的控制,这会导致大量无效或重复的执行同步任务。比如一个简单的 vim
会监听到 4 次变化事件,从而触发多次的同步。
gosync
gosync
是一个使用 go
语言开发的应用程序,旨在解决传统 rsync + inotify
方案中的一些问题,适用的场景是监听本地文件目录的变化并将变更推送到远端服务器,特性如下:
- 这是一个以推送变更为主的同步工具,远端需要启动
rsyncd
服务来接受更新 - 以
GO
语音开发,可以运行在不同架构的Linux
平台上 - 监听本地目录的变化,并对可以归并的变更进行合并和剔除,提高同步的效率
- 每次启动工具可以先进行一次全量同步
- 支持动态指定全量同步的范围
- 支持
ant
表达式指定排除规则 - 支持禁止同步删除
- 支持失败重试,当失败队列超过阈值,可以触发全量同步
- 支持定时任务,可以灵活的定制一些策略,比如删除本地一周前的数据
远端服务
首先,需要配置同步仓库,编辑 /etc/rsyncd.conf
文件,这里假设远端服务的 IP 为 192.168.0.10
。
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
uid = root
gid = root
secrets file = /etc/rsyncd.secrets
transfer logging = yes
[repo]
path = /path/to/repo
list = yes
read only = no
write only = yes
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
auth users = test
hosts allow = 192.168.0.0/16
然后创建同步账号,并启动 rsyncd
同步服务。
echo "test:123456" > /etc/rsyncd.secrets
systemctl start rsyncd
systemctl enable rsyncd
本地服务
安装
通常 inotify
在 Linux
发行版中已经内置了,我们需要安装 rsync
程序。
# debian / ubantu
apt-get install rsync
# centos / fedora / redhat
yum install rsync
gosync
可以直接下载 二进制文件,也可以选择运行 docker
镜像。
wget https://github.com/wuzhengmao/gosync/releases/download/v0.1.0-rc2/gosync-linux-amd64.tar.gz
tar -zxf gosync-linux-amd64.tar.gz
cd gosync-linux-amd64
mv gosync /usr/local/bin/
mv systemd/gosync.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable gosync
国内对github的访问向来是时断时续的,如果安装失败可以等一等,或者使用科学上网工具,这里推荐可以 注册 一个,目前有免费流量可以薅羊毛。
配置
编辑 /etc/gosync/gosync.yml
文件,配置远端服务。
# gosync.yml
log:
level: info # 日志等级:debug/info(default)/warn/error/fatal
output: file # 日志输出:stdout(default)/syslog/file
file: # 使用文件日志时需要设置
path: /var/log/gosync/gosync.log # 日志文件路径
max-size: 100 # 单个日志文件大小限制(M)
max-backups: 10 # 日志备份数
max-age: 30 # 保留多少天日志
compress: true # 压缩日志归档
rsync:
host: 192.168.0.10 # 远端rsyncd服务主机名或IP
port: 873 # 远端rsyncd服务端口,873为rsync协议的默认端口
username: test # 连接远端rsyncd服务的用户名
password: 123456 # 连接远端rsyncd服务的密码
timeout: 3s # 连接远端rsyncd服务的超时时间
space: repo # 对应远端rsyncd服务的模块
root-path: /path/to/sync # 监听的本地同步目录
watch-scope-eval: scripts/get-watch-scope.sh # 可进一步指定哪些子路径在监听范围
compress: false # 传输时是否启用压缩:true/false(default)
allow-delete: false # 是否允许删除远端:true/false(default)
full-sync: "startup" # 执行全量同步:startup(default 启动时执行)/none(不执行)/cron表达式(以定时任务的方式执行)
excludes: # 配置排除同步的规则,示例中排除了vi产生的临时文件
- "**/*.swp"
- "**/*.swpx"
- "**/4913"
queue:
retry-interval: 2s # 失败重试的时间间隔
queue-capacity: 100 # 同步队列的最大容量,超过这个容量会触发全量同步
jobs:
- cron: "0 2 * * ?" # 定时任务执行时间,支持标准cron表达式,也支持@every/@after+?h?m?s的方式指定
command: scripts/cleanup-7days-up.sh # 可执行命令,运行的工作目录为配置文件所在目录
启动
以服务模式启动 gosync
。
systemctl start gosync