使用 inotify 和 rsync 实现文件实时同步

2023-07-05 21:06:40 浏览数 (2)

在生产中有一种需求是,当目录下的文件数据发生变化时,就将数据备份到备份服务器上。实现这样的需求需要做到以下两点:

  • 利用监控服务 inotify,监控到要同步服务器的目录文件的变化
  • 发现目录数据发生变化就利用 rsync 服务将数据发送到备份服务器

因此,利用 rsync inotify 可实现数据的实时同步。

1. inotify

notify是一种强大的,细粒度的。异步的文件系统事件监控机制,linux内核从2.6.13起,加入了 Inotify支持,通过Inotify可以监控文件系统中添加、删除,修改、移动等各种事件。 利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而 inotify-tools 正是实施这样监控的软件。

1.1 安装 inotify

前置条件:Linux需要2.6.13以后内核版本才能支持inotify软件。

代码语言:txt复制
# 查看内核发行版本
uname -r 
  • yum安装
代码语言:txt复制
yum install -y inotify-tools
  • 编译安装
代码语言:txt复制
cd /usr/local/src/  
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar zxvf inotify-tools-3.14.tar.gz  
cd inotify-tools-3.14  
./configure --prefix=/usr/local/inotify   
make  
make install

1.2 inotify 的组成

  • inotifywait(主要)

在被监控的文件或目录上等待特定文件系统事件(open close delete等)发生,执行后处于阻塞状态,适合在shell脚本中使用。

  • inotifywatch

收集被监控的文件系统使用的统计数据,指文件系统事件发生的次数统计。

在实时同步的时候,主要是利用 inotifywait 对目录进行监控。

1.3 inotifywait 的常用参数

代码语言:txt复制
-m 是要持续监视变化
-r 使用递归形式监视目录
-q 减少冗余信息,只打印出需要的信息
-e 指定要监视的事件列表
--timefmt 是指定时间的输出格式
--format 指定文件变化的详细信息
--excludei <pattern> 排除文件或目录时,不区分大小写

close_write 文件或目录关闭,在写入模式打开之后关闭的。

move 文件或目录不管移动到或是移出监控目录都触发事件

create 文件或目录创建在监控目录中

delete 文件或目录被删除在监控目录中

1.4 inotifywait 使用

比如监听 文件的创建

代码语言:shell复制
# 一个终端开始监听
inotifywait -mrq  /root/rsync_test --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e create

# 另一个终端创建文件
cd /root/rsync_test
touch 123.txt

# 即可在第一个终端页面看到监听信息

2. rsync

Rsync用于在两个远程计算机之间同步文件和文件夹。它仅通过传输源和目标之间的差异来提供快速的增量文件传输。 Rsync可用于镜像数据,增量备份,在系统之间复制文件,可替代scp,sftp 和 cp 日常等使用的命令。

代码语言:txt复制
#安装
yum install rsync

2.1 rsync的常用参数

代码语言:txt复制
-v :展示详细的同步信息
-a :归档模式,相当于 -rlptgoD
    -r :递归目录
    -l :同步软连接文件
    -p :保留权限
    -t :将源文件的"modify time"同步到目标机器
    -g :保持文件属组
    -o :保持文件属主
    -D :和--devices --specials一样,保持设备文件和特殊文件
-z :发送数据前,先压缩再传输
-H :保持硬链接
-n :进行试运行,不作任何更改
-P same as --partial --progress
    --partial :支持断点续传
    --progress :展示传输的进度
--delete :如果源文件消失,目标文件也会被删除
--delete-excluded :指定要在目的端删除的文件
--delete-after :默认情况下,rsync是先清理目的端的文件再开始数据同步;如果使用此选项,则rsync会先进行数据同步,都完成后再删除那些需要清理的文件。
--exclude=PATTERN :排除匹配PATTERN的文件
--exclude-from=FILE :如果要排除的文件很多,可以统一写在某一文件中
-e ssh :使用SSH加密隧道传输

2.2 rsync的三种用法

2.2.1 本地文件同步
代码语言:shell复制
rsync -avH /root/testfolder/ /tmp/testfolder/
# 如果没有desc目录,会自动创建
2.2.2 远程文件同步—shell方式
代码语言:txt复制
# 远程主机文件同步到主机
rsync [选项] USER@HOST:SRC DEST
# 本机文件同步到远程主机
rsync [选项] SRC USER@HOST:DEST
代码语言:shell复制
# 推文件
# 从本地传到远端,目标文件会被写成ssh登录用户的属组和属主(如下 www)
rsync -avH /root/rsync_test/ backuptest@your_server_ip:/tmp/rsync_test/

# 使用 ssh 加密隧道方式传输,保障数据的安全性
rsync -avHe ssh /root/rsync_test/ backuptest@your_server_ip:/tmp/rsync_test/

# 拉文件
# 从远端传到本地,只要对目标文件有读的权限,就可以同步到本地
rsync -avH backuptest@your_server_ip:/tmp/rsync_test/ /root/rsync_test/

# 如果远程服务器ssh端口不是默认的22
rsync -avHe "ssh -p 11222" backuptest@your_server_ip:/tmp/rsync_test/ /root/rsync_test/
2.2.3 远程文件同步—daemon方式
代码语言:txt复制
# 远程主机文件同步到本地,可使用::或用rsync://指定daemon模式
rsync [选项] USER@HOST::SRC DEST
rsync [选项] **rsync://**USER@HOST/SRC DEST

# 本机文件同步到远程主机
rsync [选项] SRC USER@HOST::DEST
rsync [选项] SRC rsync://USER@HOST/DEST

daemon方式区分客户端和服务端,需要在服务端配置才能正常工作。

2.2.3.1 配置服务端
代码语言:shell复制
mkdir /etc/rsync 
cd /etc/rsync
vim rsyncd.motd  # 写入欢迎文件
vim rsyncd.secrets # 写入密码文件,每一行格式是:用户名:密码
chmod 600 rsyncd.secrets 
代码语言:shell复制
vim /etc/rsync/rsyncd.conf # 写rsync服务端配置文件

# rsyncd.conf的配置项分全局参数和模块参数,全局参数只有少数几个,一般保持默认即可
# 模块以[模块名]开头,后续参数仅作用于该模块
# 卸载模块外的参数适用于所有模块
# rsyncd.conf文件的指令和值请参考 man rsyncd.conf 

# 欢迎文件
motd file = /etc/rsync/rsyncd.motd

# 用户和组id
uid = root
gid = root

# 是否chroot,出于安全考虑建议为yes
use chroot = yes
# 是否记录传输记录
transfer logging = no
# 是否只读,值为true时客户端无法上传
read only = false
# 是否只写,值为true时客户端无法下载
write only = false
# 默认拒绝所有主机连接
hosts deny = *

# 用户名密码文件,每一行格式是:用户名:密码
# 该文件权限必须设置为600,除非strict mode设置为false
secrets file = /etc/rsync/rsyncd.secrets

# 定义名为backup的模块
[backup]
	# 模块说明
	comment = backup directory
	# 模块路径,请求改成自己的
	path = /root/rsync_test
	# 允许的主机ip
	hosts allow = your_client_ip
	# 允许的用户名
	auth users = backupuser
	# 是否允许列出该模块,建议为no
	list = no

启动服务,rsync默认监听端口为873,注意服务器安全组的设置。

代码语言:shell复制
 rsync --daemon --config=/etc/rsync/rsyncd.conf
2.2.3.2 客户端测试

在授权的机器上使用授权用户同步文件:

  • rsync -avP 授权用户@服务器ip::backup 本地文件目录rsync -avP backupuser@your_client_ip::backup /tmp/

上述命令每次执行都需要输入密码,还有指定密码文件的方式。

代码语言:shell复制
# 将密码写入文件
echo "backupuser's pwd" > secrets
chmod 600 secrets
# 指定密码文件
rsync -avP --password-file=secrets  backupuser@your_server_ip::backup /tmp/

3. 同步脚本

3.1 rsync 排除多个文件和目录

代码语言:txt复制
# 举例1,排除文件file1.txt,目录dir1下的所有内容,目录dir2
# vim /tmp/include.txt
*

# vim /tmp/exclude.txt  
file1.txt
dir1/*
dir2


# 举例2,排除所有文件,只想同步 .jpg 文件
# vim /tmp/include.txt
*.jpg

# vim /tmp/exclude.txt  
*

3.2 inotify 监听 和 rsync 同步脚本

代码语言:txt复制
#!/bin/bash 
#vim rsync.sh
path=/tmp/testfolder #inotify监控的文件夹  
host=your_server_ip #同步的目标服务器  
src=/tmp/testfolder/ #rsync同步的文件夹  
des=backup #rsync同步的目标模块名  
user=rsyncbackuptest #默认用户
include=/tmp/include.txt #同步列表 
exclude=/tmp/exclude.txt #不同步列表  

#inotify监听文件夹变更
/usr/bin/inotifywait -mq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib,close_write $path | while read files  
do  

#rsync同步变更
/usr/bin/rsync -avH --delete --include-from=$include --exclude-from=$exclude --password-file=/tmp/secret $src $user@$host::$des  

#记录同步日志
echo "${files} was rsynced" >> /tmp/rsync.log 2>&1   
done

3.3 supervisor 管理脚本进程

代码语言:txt复制
# vim /etc/supervisord.d/rsync.ini

[program:rsync]
command = sh /root/rsync.sh 
process_name=%(program_name)s_%(process_num)02d
numprocs = 1
directory = /root
redirect_stderr = true
stdout_logfile_maxbytes = 20MB  
stdout_logfile_backups = 20
stdout_logfile = /var/log/supervisor_rsync_test.log
stopasgroup = true
killasgroup = true
stopsignal = KILL

参考:

rsync inotify实现数据实时同步

rsync 排除文件和目录

使用rsync daemon跨主机安全同步

0 人点赞