Administrator
发布于 2025-02-11 / 13 阅读
0

shell脚本+inotify+rsync监听文件变动自动同步更新

手动同步数据

rsync参数

-a 保持文件原有属性

-v 显示传输细节情况

-z 对传输数据进行压缩

-P 显示传输进度

--delete 删除目标目录里多余的文件,确保源目录和目的目录数据一致

--bwlimit= 限制rsync传输速度,后面参数输入1代表1M

生成大文件

dd if=/dev/zero of=output.txt bs=1G count=1

服务端

安装rsync程序

yum -y install rsync

创建rsync程序使用普通用户

useradd -s /sbin/nologin rsync

插件创建用户信息

[root@localhost data]# id rsync

uid=1000(rsync) gid=1000(rsync) groups=1000(rsync)

设置rsync模块目录权限

chown -R rsync:rsync /data/

修改rsync配置文件

vim /etc/rsyncd.conf
uid = rsync 	#运行进程的用户
gid = rsync	#运行进程的组用户
port = 873	#监听端口
fake super = yes	#无需让rsync以root身份运行
use chroot = no	#禁锢推送的数据到某个目录,不允许跳出该目录
max connections = 200	#最大连接数
timeout = 600	#超时时间
ignore errors	#忽略错误信息
read only = false	#对备份数据只读可写
list = false	#是否列出模块信息
auth users = rsync_backup	#定义虚拟用户,作为连接认证用户
secrets file = /etc/rsync.passwd	#定义rsync程序用户连接认证密码文件路径
log file = /var/log/rsyncd.log	#日志存放路径
#####################################
[data]	#定义模块名字
comment= 注释信息	#模块注释信息
path = /data	#模块存储路径

创建虚拟用户密码文件与授权

echo 'rsync_backup:qazwsx' > /etc/rsync.passwd

[root@localhost data]# cat /etc/rsync.passwd

rsync_backup:qazwsx

对密码文件授权,权限降低为600,否则rsync启动会报错

[root@localhost data]# chmod 600 /etc/rsync.passwd

查看文件权限

[root@localhost data]# ll /etc/rsync.passwd

-rw------- 1 root root 20 Feb 10 19:46 /etc/rsync.passwd

开机启动rsync服务

[root@localhost data]# systemctl start rsyncd
[root@localhost data]# systemctl status rsyncd
● rsyncd.service - fast remote file copy program daemon
   Loaded: loaded (/usr/lib/systemd/system/rsyncd.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2025-02-10 19:48:44 CST; 6s ago
 Main PID: 1320 (rsync)
   CGroup: /system.slice/rsyncd.service
           └─1320 /usr/bin/rsync --daemon --no-detach

Feb 10 19:48:44 localhost.localdomain systemd[1]: Started fast remote file copy program daemon.
Feb 10 19:48:44 localhost.localdomain rsyncd[1320]: params.c:Parameter() - Ignoring badly formed line in config file: ignore errors
Feb 10 19:48:44 localhost.localdomain rsyncd[1320]: rsyncd version 3.1.2 starting, listening on port 873
[root@localhost data]# systemctl enable rsyncd
Created symlink from /etc/systemd/system/multi-user.target.wants/rsyncd.service to /usr/lib/systemd/system/rsyncd.service.

检查端口

客户端

1、安装rsync程序

[root@localhost ~]# yum -y install rsync

2、密码连接方式

1、创建密码文件,用于和rsyncd服务端认证,降低权限

[root@localhost ~]# echo 'qazwsx' > /etc/rsync.pwd
[root@localhost ~]# chmod 600 /etc/rsync.pwd 
[root@localhost ~]# ll /etc/rsync.pwd 
-rw------- 1 root root 7 Feb 10 19:55 /etc/rsync.pwd

2、不用密码文件,采用环境变量

[root@localhost ~]# export RSYNC_PASSWORD=qazwsx

客户端从服务端拉去数据(下载数据)

拉取data模块的数据

服务端

没有数据就创造一些数据出来

客户端拉取数据

使用密码文件
[root@localhost ~]# rsync -avzP --password-file=/etc/rsync.pwd rsync_backup@192.168.200.200::data /tmp/

使用环境变量设置密码拉取数据

先删除客户端已经拉去的数据

[root@localhost ~]# rm -rf /tmp/

设置环境变量

[root@localhost ~]# export RSYNC_PASSWORD=qazwsx

再次拉去数据

[root@localhost ~]# rsync -avzP rsync_backup@192.168.200.200::data /tmp/

客户端往服务端上传数据

客户端上传测试文件

服务端查看文件

自动同步

部署inotify-tools软件(客户端安装)

检查工作

检查linux内核是否支持inotify,内核在2.6.13起才支持

查看系统是否存在三个系统文件,存在则支持

[root@localhost ~]# ls /proc/sys/fs/inotify/
max_queued_events  max_user_instances  max_user_watches

备注文件解释:

max_queued_events 设置inotifywait或者inotifywatch命令可以监视的文件数量(单进程)默认只能监控8192个文件

max_user_instances 设置每个用户可以运行inotifywait或者inotifywaitch命令的进程数,默认每个用户可以开启inotify服务128个进程

max_user_watches 设置inotify实例时间(event)队列可容纳的事件数量,默认监控事件队列长度为16384

安装inotify-tools工具

安装epel源

[root@localhost ~]# yum -y install epel-release

安装inotify-tools工具

[root@localhost ~]# yum -y install inotify-tools

检查软件生成命令

[root@localhost ~]# rpm -ql inotify-tools |head -2

/usr/bin/inotifywait

/usr/bin/inotifywatch

intoifywait讲解

inotifywait:在被监控的目录等待特定文件系统事件(open、close、delete等事件)执行后处于阻塞状态,适合在shell脚本使用,是实现监控的关键

inotifywatch:手机被监控的文件系统使用的统计数据(文件系统事件发生的次数统计

inotifywait命令介绍

inotifywait用于等待文件或文件集上的一个待定事件,可以监控任何文件和目录设置,并且可以递归地监控整个目录树;

inotifywatch用于收集被监控的文件系统计数据,包括每个inotify事件发生多少次等信息

从上面可知inotifywait是一个监控事件,可以配合shell脚本使用它。与它相关的参数:

语法格式:inotifywait [-hcmrq][-e][-t][–format][-timefmt][…]

-m: 即“–monitor” 表示始终保持事件监听状态。

-d:类似于-m参数,将命令运行在后台,记录出发的事件信息,记录在指定文件里,加上--outfile参数

-r: 即“–recursive” 表示递归查询目录

-q: 即“–quiet” 表示打印出监控事件

-o: 即“–outfile” 输出事情到一个文件而不是标准输出

-s: 即“–syslog” 输入错误信息到系统日志

-e: 即“–event”, 通过此参数可以指定要监控的事件,常见的事件有modify、delete、create、close_write、move、close、unmount和attrib等


-format: 指定输出格式;常用的格式符如:

%w:表示发生事件的目录

%f:表示发生事件的文件

%e:表示发生的事件

%Xe:事件以“X”分隔

%T:使用由-timefmt定义的时间格式

-timefmt:指定时间格式,用于-format选项中的%T格式

利用Inotify软件监控的事件主要是如下,也是我们使用命令,需要指定的那些事件,指的就是你想监控文件内容变化了,还是被删了,还是正在被编辑,被修改,等情况。

Events    含义
access    文件或目录被读取
modify    文件或目录内容被修改
attrib    文件或目录属性被改变
close    文件或目录封闭,无论读/写模式
open    文件或目录被打开
moved_to    文件或目录被移动至另外一个目录
move    文件或目录被移动到另一个目录或从另一个目录移动至当前目录
create    文件或目录被创建在当前目录
delete    文件或目录被删除
umount    文件系统被卸载

关于监控事件的细节解释

可监控的事件
有几种事件能够被监控。一些事件,比如 IN_DELETE_SELF 只适用于正在被监控的项目,而另一些,比如 IN_ATTRIB 或者 IN_OPEN 则只适用于监控过的项目,或者如果该项目是目录,则可以应用到其所包含的目录或文件。

IN_ACCESS
被监控项目或者被监控目录中的条目被访问过。例如,一个打开的文件被读取。
IN_MODIFY
被监控项目或者被监控目录中的条目被修改过。例如,一个打开的文件被修改。
IN_ATTRIB
被监控项目或者被监控目录中条目的元数据被修改过。例如,时间戳或者许可被修改。
IN_CLOSE_WRITE
一个打开的,等待写入的文件或目录被关闭。
IN_CLOSE_NOWRITE
一个以只读方式打开的文件或目录被关闭。
IN_CLOSE
一个掩码,可以很便捷地对前面提到的两个关闭事件(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)进行逻辑操作。
IN_OPEN
文件或目录被打开。
IN_MOVED_FROM
被监控项目或者被监控目录中的条目被移出监控区域。该事件还包含一个 cookie 来实现 IN_MOVED_FROM 与 IN_MOVED_TO 的关联。
IN_MOVED_TO
文件或目录被移入监控区域。该事件包含一个针对 IN_MOVED_FROM 的 cookie。如果文件或目录只是被重命名,将能看到这两个事件,如果它只是被移入或移出非监控区域,将只能看到一个事件。如果移动或重命名一个被监控项目,监控将继续进行。参见下面的 IN_MOVE-SELF。
IN_MOVE
可以很便捷地对前面提到的两个移动事件(IN_MOVED_FROM | IN_MOVED_TO)进行逻辑操作的掩码。
IN_CREATE
在被监控目录中创建了子目录或文件。
IN_DELETE
被监控目录中有子目录或文件被删除。
IN_DELETE_SELF
被监控项目本身被删除。监控终止,并且将收到一个 IN_IGNORED 事件。
IN_MOVE_SELF
监控项目本身被移动。

inotifywait实践

[root@localhost ~]# inotifywait -mrq --timefmt '%d-%m-%y %H:%M' --format '%T%w%f' -e create,delete /data/

使用参数解释

命令用法
inotifywait -mrq   --timefmt "%d/%m/%y %H:%M" --format "%T %w%f" /data


-m: 即“–monitor” 表示始终保持事件监听状态。
-r: 即“–recursive” 表示递归查询目录
-q: 即“–quiet” 表示打印出监控事件
-e: 即“–event”, 通过此参数可以指定要监控的事件,常见的事件有modify、delete、create、close_write、move、close、unmount和attrib等



--timefmt:指定时间格式
%m  月份(以01-12来表示)。
%d  日期(以01-31来表示)。
%y  年份(以00-99来表示)。
%F  

%w:表示发生事件的目录
%f:表示发生事件的文件
%T:使用由-timefmt定义的时间格式
%e:表示发生的事件

当我们的代码目录,有了更新,希望立即实现数据同步,即可以检测create事件

所有事件

执行命令,对输出日志格式化,默认检测所有事件

只监听create delete操作

[root@localhost ~]# inotifywait -mrq --timefmt "%F %T" --format "%T %w%f" -e create,delete  /data/

move事件

[root@localhost ~]# inotifywait -mrq --timefmt "%F %T" --format "%T %w%f" -e move  /data/

可以看到,inotify的作用是,基于不同的事件,检测文件夹中、文件的变化

当检测到有事件发生后,证明文件发生了变化,我们就可以根据这个进行数据同步操作

数据实时检测备份

shell监本循环检测

[root@localhost data]# vim about_inotify.sh
#!/bin/bash
path=data
backup_server=192.168.200.200
export RSYNC_PASSWORD=qazwsx
/usr/bin/inotifywait -mrq -e modify,delete,create,attrib,move /data|while read line
do
        echo ${line}
        rsync -az /data/ rsync_backup@${backup_server}::data
done

可以看到我们在客户端删除了123.txt文件,脚本检测到了删除操作,但是在备份服务器没有删除操作,这是因为我们脚本中rsync同步命令中没有添加--delete操作

总结

优点:
1.linux内核本身支持inotify机制
2.用于监控文件系统事件变化的神器

缺点:
1.如果并发修改的文件超过200个,同步会延迟,以及会丢掉部分文件,这是inotifywait软件的bug,官网有说明。

2.该脚本监控到事件后,调用rsync是单进程执行,一次cpu只会同步一次rsync命令,效率很低,大数据量下没法使用。
3.自己写的脚本,其实问题还是很多的,简单场景没问题,高并发,复杂场景下,要求多的情况下,那就有点羞涩了。
4.其实已经有了更牛b的程序员,开发了第三方工具,强化了inotify的作用,再结合rsync实现实时同步。