Rsync+Inotify 实时增量同步神器
Rsync
可以用于实现数据增量同步:
基于sshd服务器,并client使用server的OS帐号同步数据,可以结合ssh公钥认证。
Server端启动rsyncd服务,并创建专用的rsync帐号(最终也要映射到系统帐号,对应一定的权限)
语法:
远程拷贝
Usage: rsync [OPTION]… SRC [SRC]… DEST
or rsync [OPTION]… SRC [SRC]… [USER@]HOST:DEST
or rsync [OPTION]… SRC [SRC]… [USER@]HOST::DEST
# yum -y install rsync
# rsync -va /etc/hosts /tmp/
# rsync -va /etc 192.168.1.251:/tmp
# rsync -va /etc/ 192.168.1.251:/tmp
# rsync -vza /etc 192.168.1.251:/tmp
# rsync -vza --delete /etc root@192.168.1.251:/tmp
# rsync -vza 192.168.1.251:/tmp /var/tmp
# rsync -vza --delete /etc/ 192.168.1.251:/
参数说明
# rsync --help
-v, --verbose increase verbosity
-r, --recursive recurse into directories
-l, --links copy symlinks as symlinks
-p, --perms preserve permissions
-t, --times preserve modification times
-o, --owner preserve owner (super-user only)
-g, --group preserve group
--devices preserve device files (super-user only)
--specials preserve special files
-D same as --devices --specials
-a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)
-H, --hard-links preserve hard links
-A, --acls preserve ACLs (implies --perms)
-X, --xattrs preserve extended attributes
-z, --compress compress file data during the transfer, 增量拷贝
--delete delete extraneous files from destination dirs
--exclude=pattern 同步时忽略什么样的文件
# rsync -vaz --delete /var/www/html/ 192.168.122.10:/var/www/html
# rsync -vazHAX --delete /var/www/html/ 192.168.122.10:/var/www/html
# rsync -vazHAX --delete /var/www/html 192.168.122.10:/var/www/
同步目录注意事项
-
源:
目录以"/“结尾 #仅传输目录下的内容
目录不以”/"结尾 #传输目录及目录下所有的内容 -
目标:
目标目录不存在 #先创建目录,再传输. 如果创建时父目录不存在, 则报错
传输大文件
创建一个大文件
[root@ansible ~]# dd if=/dev/zero of=abc/test bs=100M count=10
记录了10+0 的读入
记录了10+0 的写出
1048576000字节(1.0 GB)已复制,2.61383 秒,401 MB/秒
传输
[root@ansible ~]# rsync -rv abc 192.168.23.188:/opt
sending incremental file list
abc/
abc/test
sent 1,048,832,116 bytes received 39 bytes 139,844,287.33 bytes/sec
total size is 1,048,576,000 speedup is 1.00
在接收端查看发现成功接收:
[root@db-server opt]# ls
abc
失败的增量拷贝
查看是否是增量拷贝,在发送端增加新内容,然后发现这不是增量拷贝而是全量拷贝
[root@db-server opt]# echo world > abc/b.txt
[root@ansible ~]# rsync -rv abc 192.168.23.188:/opt
sending incremental file list
abc/b.txt
abc/test
成功的增量拷贝
我们更改发送端/abc/b.txt
的文本内容,然后通过 -avz
和发送abc/
的内容实现增量拷贝
[root@ansible ~]# vim abc/b.txt
[root@ansible ~]# rsync -avz abc/ 192.168.23.188:/opt/abc
sending incremental file list
./
b.txt
sent 161 bytes received 44 bytes 410.00 bytes/sec
total size is 1,048,576,023 speedup is 5,115,004.99
# -a archive mode; 存档模式;
# -v 增加详细程度
# -z compress file data during the transfer, 增量拷贝
拷贝删除操作--delete
为了安全起见rsync不会将删除操作拷贝,为了拷贝删除操作,我们需要加入--delete
实验,我们在发送端删除abc/c.txt
,然后--delete
拷贝
[root@ansible ~]# rm -rf abc/c.txt
[root@ansible ~]# rsync -avz --delete abc/ 192.168.23.188:/opt/abc
sending incremental file list
deleting c.txt
./
sent 90 bytes received 24 bytes 228.00 bytes/sec
total size is 1,048,576,015 speedup is 9,198,035.22
在接收端查看,发现c.txt被删除
[root@db-server opt]# ls abc
b.txt c.txt test
发生改变但不想拷贝--exclude
我们在abc/b.txt
内添加一行666666
vim abc/b.txt
world
xxxxxxxx
66666666
然后执行exclude
拷贝发现没有文件拷贝
[root@ansible ~]# rsync -avz --delete --exclude=b.txt abc/ 192.168.23.188:/opt/abc
sending incremental file list
created directory /opt/abc
./
test
sent 1,019,863 bytes received 38 bytes 119,988.35 bytes/sec
total size is 1,048,576,000 speedup is 1,028.12
Inotify
Inotify 是一种强大的、细粒度的、异步的文件系统事件监控机制,linux内核从2.6.13起,加入了Inotify支持,通过Inotify可以监控文件系统中添 加、删除,修改、移动等各种细微事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools就是这样的一个第三方软件。
rsync可以实现触发式的文件同步,但是通过crontab守护进程方式进行触发,同步的数据和实际数据会有差异,而inotify可以监控文件系统的各种变化,当文件有任何变动时,就触发rsync同步,这样刚好解决了同步数据的实时性问题。
安装inotify工具inotify-tools
- 确认内核支持
# ll /proc/sys/fs/inotify
总计 0
-rw-r--r-- 1 root root 0 10-01 08:07 max_queued_events
-rw-r--r-- 1 root root 0 10-01 08:07 max_user_instances
-rw-r--r-- 1 root root 0 10-01 08:07 max_user_watches
- 安装rsync与inotify-tools
inotify-tools是用来监控文件系统变化的工具,因此必须安装在内容发布节点(数据源)
# yum install -y inotify-tools-3.14-8.el7.x86_64.rpm
inotify-tools指令:
inotifywait 用于等待文件或文件集上的一个特定事件,它可以监控任何文件和目录
inotifywatch 用于收集被监控的文件系统统计数据,包括每个inotify事件发生多少次等信息
Inotifywait相关参数
Inotifywait是一个监控等待事件,可以配合shell脚本使用,常用的一些参数:
-m ,--monitor 表示始终保持事件监听状态
-r ,--recursive 表示递归查询目录
-q 即--quiet,表示不打印监控事件(最开始的提示信息)
-e 即--event,通过此参数可以指定要监控的事件,常见的事件有modify、delete、create、attrib等
# inotifywait -mrq -e modify,delete,create,attrib /var/www/html/
# inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e modify,delete,create,attrib /var/www/html/
04/06/14 14:23 /var/www/html/file1
04/06/14 14:23 /var/www/html/file1
# nohup inotifywait -mrq --format '%T %w%f' --timefmt '%d/%m/%y %H:%M' -e modify,delete,create,attrib /var/www/html >> file_modify.txt &
# inotifywait -mrq --format '%w%f' -e modify,delete,create,attrib /var/www/html/
/var/www/html/file2
/var/www/html/file2
实验
监控 /root/abc
[root@ansible inotify]# inotifywait -mrq /root/abc
同一台机器,同一个位置操作,观察inotifywait
继续操作,然后观察监控端
[root@ansible inotify]# vim b.txt
监控端
在b.txt
内加入一行aaaaaa
观察监控端
分析inotifywait -- help
监控某些事件-e
示例:
inotifywait -mrq -e modify,move,create,delete /root/abc
# -e event
设置日期格式
[root@ansible inotify]# inotifywait -mrq -e modify,move,create,delete --format '%T %w%f' --timefmt '[%d/%m/%Y %H:%M]' /root/abc
创建文件试一下
[root@ansible inotify]# inotifywait -mrq -e modify,move,create,delete --format '%T %w%f' --timefmt '[%d/%m/%Y %H:%M]' /root/abc
[10/06/2022 16:02] /root/abc/e.txt
日志保存命令
inotifywait -mrq -e modify,move,create,delete --format ' %T %w%f' --timefmt '[%d/%m/%Y %H:%M]' /root/abc | tee -a /var/log/root_abc_w.log
执行操作后发现日志保存成功
[root@ansible abc]# cat /var/log/root_abc_w.log
[10/06/2022 16:05] /root/abc/e.txt
[10/06/2022 16:06] /root/abc/d.txt
[10/06/2022 16:06] /root/abc/f.txt
[10/06/2022 16:06] /root/abc/f.txt
Rsync+Inotify实战
执行前确保建立ssh信任关系
写以下脚本
#!/bin/bash
dst_ip=192.168.23.188 # 目标ip
src_dir=/root/abc
dst_dir=/opt/abc
logfile=/var/log/root_abc_w.log
inotifywait -mrq -e modify,attrib,move,create,delete --format '%T %e %w%f' --timefmt '[%d/%m/%Y %H:%M]' $src_dir |
while read line;do
echo $line >> $logfile
rsync -az --delete $src_dir/ $dst_ip:$dst_dir/ #拷贝
done
执行脚本,发现运行成功
[root@ansible abc]# sh sync.sh &
# & 后台运行
在发送端做如下操作
[root@ansible abc]# vim /var/log/root_abc_w.log
[root@ansible abc]# touch m.txt
[root@ansible abc]# rm -rf l.txt
[root@ansible abc]# echo LZY > m.txt
查看log日志
vim /var/log/root_abc_w.log
查看接收端
[root@db-server abc]# ls
b.txt f.txt m.txt test
[root@db-server abc]# cat m.txt
LZY
同步成功
如何在终端关闭时仍然运行实时同步脚本
linux 命令:nohup 详解
nohub :当我们从后台启动一个进程的时候,如果该进程的父进程被kill,nohub会把该进程交给systemd
nohub sync.sh &
Reference
课堂笔记