通过rsync+inotify实现实时数据同步
rsync(Remote Sync)
是一个开源的快速备份工具,可以在不同主机之间镜像同步整个目录树,支持增量备份,并保持链接和权限,且采用优化的同步算法,传输前执行压缩,因此非常使用与异地备份、镜像服务器等应用。在远程同步任务重,负责发起rsync同步操作的客户机称为发起端,二负责响应来自客户机的rsync同步操作的服务器称为同步源。在同步过程中,同步源负责提供文件的原始位置,发起端应对该位置具有读取权限。
- 支持本地复制,或者与其他SSH、rsync 主机同步
- 官方网站:https://rsync.samba.org/
命令参数
常用参数
参数 | 说明 |
---|---|
-v | verbose 详细输出 |
-a | 归档模式,递归方式传输文件,并保持连接,权限,用户和组,时间信息 |
-z | 压缩文件传输 |
-h | human-readable, 输出友好 |
-u | 跳过已经存在的文件,备份更新 |
-r | --recursive 对子目录以递归模式处理 |
--delete | 删除那些 DST 中 SRC 没有的文件 |
-p | --perms 保持文件权限 |
所有参数
参数 | 说明 |
---|---|
-v | --verbose 详细模式输出 |
-q | --quiet 精简输出模式 |
-c | --checksum 根据校验和(而不是文件大小、修改时间)来决定是否跳过文件 |
-a | --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于 -rlptgoD |
-r | --recursive 对子目录以递归模式处理 |
-R | --relative 使用相对路径信息 |
-b | --backup 创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename。可以使用 --suffix 选项来指定不同的备份文件前缀。 |
--backup-dir | 将备份文件(如~filename) 存放在在目录下。 |
-suffix=SUFFIX | 定义备份文件前缀 |
-u | --update 仅仅进行更新,也就是跳过所有已经存在于 DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件) |
-l | --links 保留软链结 |
-L | --copy-links 想对待常规文件一样处理软链结 |
--copy-unsafe-links | 仅仅拷贝指向 SRC 路径目录树以外的链结 |
--safe-links | 忽略指向 SRC 路径目录树以外的链结 |
-H | --hard-links 保留硬链结 |
-p | --perms 保持文件权限 |
-o | --owner 保持文件属主信息 |
-g | --group 保持文件属组信息 |
-D | --devices 保持设备文件信息 |
-t | --times 保持文件时间信息 |
-S | --sparse 对稀疏文件进行特殊处理以节省 DST 的空间 |
-n | --dry-run 现实哪些文件将被传输 |
-W | --whole-file 拷贝文件,不进行增量检测 |
-x | --one-file-system 不要跨越文件系统边界 |
-B | --block-size=SIZE 检验算法使用的块尺寸,默认是 700 字节 |
-e | --rsh=COMMAND 指定使用 rsh、ssh 方式进行数据同步 |
--rsync-path=PATH | 指定远程服务器上的 rsync 命令所在路径信息 |
-C | --cvs-exclude 使用和 CVS 一样的方法自动忽略文件,用来排除那些不希望传输的文件 |
--existing | 仅仅更新那些已经存在于 DST 的文件,而不备份那些新创建的文件 |
--delete | 删除那些 DST 中 SRC 没有的文件 |
--delete-excluded | 同样删除接收端那些被该选项指定排除的文件 |
--delete-after | 传输结束以后再删除 |
--ignore-errors | 及时出现 IO 错误也进行删除 |
--max-delete=NUM | 最多删除 NUM 个文件 |
--partial | 保留那些因故没有完全传输的文件,以是加快随后的再次传输 |
--force | 强制删除目录,即使不为空 |
--numeric-ids | 不将数字的用户和组 ID 匹配为用户名和组名 |
--timeout=TIME IP | 超时时间,单位为秒 |
-I | --ignore-times 不跳过那些有同样的时间和长度的文件 |
--size-only | 当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间 |
--modify-window=NUM | 决定文件是否时间相同时使用的时间戳窗口,默认为 0 |
-T --temp-dir=DIR | 在 DIR 中创建临时文件 |
--compare-dest=DIR | 同样比较 DIR 中的文件来决定是否需要备份 |
-P | 等同于 --partial |
--progress | 显示备份过程 |
-z | --compress 对备份的文件在传输时进行压缩处理 |
--exclude=PATTERN | 指定排除不需要传输的文件模式 |
--include=PATTERN | 指定不排除而需要传输的文件模式 |
--exclude-from=FILE | 排除 FILE 中指定模式的文件 |
--include-from=FILE | 不排除 FILE 指定模式匹配的文件 |
--version | 打印版本信息 |
安装
服务端(同步源)
安装rsync
[root@openresty-dev ~]# dnf -y install rsync
创建用户
[root@openresty-dev ~]# useradd rsync -s /sbin/nologin
创建同步目录
[root@openresty-dev ~]# mkdir /data/webfile [root@openresty-dev ~]# chown -R rsync:rsync /data/webfile
修改配置文件
[root@openresty-dev ~]# vim /etc/rsyncd.conf # RSYNC Config # 指定传输文件使用的用户 uid = rsync # 指定传输文件使用的用户组 gid = rsync # 安全设置,切换到安全目录 use chroot = yes # 最大连接数 max connections = 10 # 客户端超时时间,单位秒,设置为 0 不超时 timeout = 900 # PID 文件 pid file = /var/run/rsyncd.pid # 锁文件 lock file = /var/run/rsync.lock # 日志文件 log file = /var/log/rsyncd.log # 日志记录方式 transfer logging = yes # 忽略文件 exclude = lost+found/ # 忽略不可读文件 ignore nonreadable = yes # 传输时不压缩的文件 dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 # 现在的版本需要添加,保留文件的完整属性 fake super = yes # 模块 [data] # 对应的目录 path = /data/webfile # 传输的删除时忽略 I/O 错误,报错会跳过--delete ignore errors # 允许写入 read only = false # 不允许列出 list = false # 允许的网段,多个使用空格隔开 hosts allow = 192.168.3.0/24 # 拒绝的网段,拒绝所有 hosts deny = 0.0.0.0/32 # 连接的虚拟用户,非系统用户 auth users = rsuser # 虚拟用户的账号密码文件 secrets file = /etc/rsuser.password # 注释说明 comment = Test file share
创建密码文件
[root@openresty-dev ~]# echo "ruser:123456" > /etc/rsuser.password [root@openresty-dev ~]# chmod 600 /etc/rsuser.password
启动服务
[root@openresty-dev ~]# rsync --daemon [root@openresty-dev ~]# ss -tlunp | grep 873 [root@openresty-dev data]# ss -anptu | grep 873 tcp LISTEN 0 5 0.0.0.0:873 0.0.0.0:* users:(("rsync",pid=4193,fd=5)) tcp LISTEN 0 5 [::]:873 [::]:* users:(("rsync",pid=4193,fd=6))
客户端(被同步端)
安装rsync
[root@docker ~]# dnf -y install rsync
创建密码验证文件
# 注意客户端上面的密码文件中,不需要写用户名,直接写密码就可以了。 [root@docker ~]# echo "123456" > /etc/rsuser.password [root@docker ~]# chmod 600 /etc/rsuser.password
测试同步
# 同步远程文件到本地 (Pull) root@docker ~]# rsync -av --password-file=/etc/rsuser.password [email protected]::data /data/webfile receiving incremental file list created directory /data/webfile ./ 1.txt sent 50 bytes received 121 bytes 342.00 bytes/sec total size is 0 speedup is 0.00 # 同步本地文件到远端 (Push) [root@docker ~]# rsync -arvz --password-file=/etc/rsuser.password docker.svr.test [email protected]::data sending incremental file list docker.svr.test sent 109 bytes received 43 bytes 101.33 bytes/sec total size is 0 speedup is 0.00
inotify 介绍及应用
inotify
是一种强大的、细粒度的、异步文件系统监控机制,内置于Linux
内核 2.6.13 及以上版本。为了使用这一内核功能,用户需要配合相应的工具,通常需要用户空间的软件调用才能实现,实现inotify
软件有inotify-tools
、sersync
、lrsyncd
。
inotify-tools
是实现 inotify
的一个常用软件包,主要包含两个工具:
- inotifywait:用于在被监控的文件或目录上等待特定文件系统事件(如打开、关闭、删除等)发生,常用于实时同步的目录监控。
- inotifywatch:用于收集被监控的文件系统的统计数据,指文件系统事件发生次数的统计。
在使用 inotify-tools
时,首先需要开启 inotify
进程,该进程将实时监控目标目录的变化情况,并根据设置通过 rsync
命令立即同步至服务器。要实现 inotify
的实时监控,必须先成功配置并验证 rsync
服务的推送功能。
安装
[root@docker ~]# dnf install -y inotify-tools
内核调优
[root@docker ~]# vim /etc/sysctl.conf #添加以下代码
fs.inotify.max_queued_events = 16384
# 监控事件队列;
# 表示调用inotify_init时分配给instance中可排队的
# event的数目的最大值,超出这个值的事件被丢弃,但会
# 触发IN_Q_OVERFLOW事件
fs.inotify.max_user_instances = 128
# 最多监控实例数;
# 表示每一个真实用户ID可创建的instatnces的数量上限
fs.inotify.max_user_watches = 524288
# 每个实例最多监控目录数;
# 表示每个instatnces可监控的最大目录数量,如果监控
# 的文件数目巨大,需要根据情况,适当增加此值的大小
触发脚本
[root@docker ~]# vim inotify.sh
#!/bin/sh
srcdir=/data/webfile
dstdir=/data/webfile
rsyncuser=rsuser
rsyncpassdir=/etc/rsuser.password
dstip="192.168.3.19"
for ip in $dstip
do
rsync -avH --port=873 --progress --delete $srcdir $rsyncuser@$ip::$dstdir --password-file=$rsyncpassdir
done
/usr/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $srcdir | while read file
do
for ip in $dstip
do
rsync -avH --port=873 --progress --delete $srcdir $rsyncuser@$ip::$dstdir --password-file=$rsyncpassdir
echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1
done
done
[root@docker ~]# chmod a+x inotify.sh
[root@docker ~]# nohup inotify.sh &