inotify+rsync实现实时备份

本实验使用A(192.168.34.108)作为客户端,B(192.168.34.103)作为实时备份服务器,利用inotify对同步数据目录信息进行监控,当监控到目录相应内容变化时,利用rsync完成对数据的同步。记录利用inotify+rsync实现实时备份的过程。

基础知识梳理

inotify基础知识

linux内核高于2.6.13的版本,默认支持inotify,可使用ll /proc/sys/fs/inotify查看该目录下的文件,如果有以下文件说明服务器内核支持inotify。

-rw-r--r-- 1 root root 0 Dec 7 10:10 max_queued_events #inotify时间队列的最大长度,如果此值太小会出现Event Queue Overflow错误,默认值为16384
-rw-r--r-- 1 root root 0 Dec 7 10:10 max_user_instances #可以监视的文件数量(单进程),默认值为8192
-rw-r--r-- 1 root root 0 Dec 6 05:54 max_user_watches #每个用户创建inotify实例最大值,默认值为128
详细的参数说明可已通过man 7 inotify查看

inotify参考文档

https://github.com/rvoicilas/inotify-tools/wiki

inotify-tools包主要的文件

  • inotifywait:在被监控的文件或目录上等待特定文件系统时间(open close delete等)发生,常用于实时同步的目录监控
  • inotifywatch:收集被监控的文件系统使用的统计数据,指文件系统时间发生的次数统计。

inotifywait命令的常用选项

-m,--monitor    始终保持事件监听
-d,--daemon        以守护进程的方式执行,和-m相似,配合-o使用
-r,--recursive    递归监控目录数据信息变化
-q,--quiet        输出少量信息事件
--timefmt <fmt>    指定时间输出格式
--format <fmt>    指定输出的格式;即市级监控输出的内容
-e                 指定监听的时间,如果省略,表示监听所有时间
--exclude <pattern>    指定排除文件或目录,使用扩展的正则表达式匹配的模式实现
--excludei <pattern>    和exclude相似,不区分大小写
-o,--outfile <file>        打印时间到文件中,相当于标准正确输出
-s,--syslogoutput        发送错误到syslog,相当于标准错误输出

其中–timefmt < fmt> 的格式,可以参考man 3 strftime,主要选项如下

%Y 年份信息,包含世纪信息
%y 年份信息,不包括世纪信息
%m 显示月份,范围 01-12
%d 每月的第几天,范围是 01-31
%H 小时信息,使用 24小时制,范围 00-23
%M 分钟,范围 00-59

例如:–timefmt “%Y-%m-%d %H:%M” 表示按时间年-月-日 时-分的格式输出时间

–format < fmt> 的格式定义的相关选项如下

%T 输出时间格式中定义的时间格式信息,通过 --timefmt option 语法格式指定时间信息
%w 事件出现时,监控文件或目录的名称信息
%f 事件出现时,将显示监控目录下触发事件的文件或目录信息,否则为空
%e 显示发生的事件信息,不同的事件默认用逗号分隔
%Xe 显示发生的事件信息,不同的事件指定用X进行分隔

例如:

  • –format “%T %w%f event: %;e”
  • –format ‘%T %w %f’

-e选项指定的时间类型如下

create 文件或目录创建
delete 文件或目录被删除
modify 文件或目录内容被写入
attrib 文件或目录属性改变
close_write 文件或目录关闭,在写入模式打开之后关闭的
close_nowrite 文件或目录关闭,在只读模式打开之后关闭的
close 文件或目录关闭,不管读或是写模式
open 文件或目录被打开
moved_to 文件或目录被移动到监控的目录中
moved_from 文件或目录从监控的目录中被移动
move 文件或目录不管移动到或是移出监控目录都触发事件
access 文件或目录内容被读取
delete_self 文件或目录被删除,目录本身被删除
unmount 取消挂载

例如:-e create,delete,moved_to,close_write 表示当目录内有创建,删除,移动,修改时记录

使用inotidy监控时间示例

  • 监控一次性事件

    inotifywait /data

  • 持续监控

    inotifywait -mrq /data

  • 持续后台监控,并记录日志

    inotifywait -o /root/inotify.log -drq /data –timefmt “%Y-%m-%d %H:%M” –format “%T %w%f event: %e”

  • 持续后台监控特定事件

    inotifywait -mrq /data –timefmt “%F %H:%M” –format “%T %w%f event: %;e” -e create,delete,moved_to,close_write

配置B服务器

修改配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@ansible ~]#cd /etc/
[root@ansible etc]#cp rsyncd.conf{,.bak}
[root@ansible etc]#vi rsyncd.conf
uid = root #以root身份执行进程
gid = root #进程所属组
use chroot = no #
max connections = 0 #最大连接数不限制
ignore errors #忽略错误
exclude = lost+found/ #排除该文件夹
log file = /var/log/rsyncd.log #日志文件存放位置
pid file = /var/run/rsyncd.pid #进程pid存放位置
lock file = /var/run/rsyncd.lock #进程锁文件存放位置
reverse lookup = no #不启用反向名字解析服务
hosts allow = 192.168.8.0/24 #允许哪个网段访问
[backup] #备份的模块,可以有多个
path = /backup/ #接收的备份存放目录
comment = backup #注释信息
read only = no #可写
auth users = rsyncuser #同步时使用的虚拟用户账号
secrets file = /etc/rsync.pass #口令存放文件

生成服务器端口令验证文件

1
2
[root@ansible etc]#echo "rsyncuser:centos" > /etc/rsync.pass
[root@ansible etc]#chmod 600 /etc/rsync.pass

准备服务器端存放备份的目录

1
$ mkdir /backup

服务器端启动rsync服务

1
2
$ rsync --daemon   #监听873端口
$ echo "rsync --daemon" > /etc/rc.d/rc.local #加入开机自启

配置客户端A

客户端配置密码文件

1
2
$ echo "centos" > /etx/rsync.pass
$ chmod 600 /etc/rsync.pass

在客户端测试同步数据

1
$ rsync -avz --password-file=/etc/rsync.pass /data/ rsyncuser@192.168.34.103::backup

创建客户端inotify_rsync.sh脚本,实现后台监控实时备份

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@apache bin]#vi backup.sh 
SRC='/data/'
DEST='rsyncuser@192.168.34.103::backup'
inotifywait -mrq --timefmt '%Y-%m-%d %H-%M' --format '%T %w %f' -e \
attrib,create,delete,moved_to,close_write ${SRC} |while read DATE TIME DIR \
FILE;do
FILEPATH=${DIR}${FILE}
rsync -az --delete --password-file=/etc/rsync.pass ${SRC} ${ \
DEST} && echo "At ${TIME} on ${DATE},file ${FILEPATH} was \
backuped up via rsync" >> /var/log/changelist.log
done
[root@apache bin]#bash /data/bin/backup.sh &
[root@apache bin]#echo "bash /data/bin/backup.sh" >> /etc/rc.d/rc.local