rsync+inotify的部署与使用

1、思路

先安装rsync实现服务器之间文件的同步,在安装inotify监控指定文件夹,当检测到改动,创建、删除等操作时,调用rsync进行同步

2、业务痛点

相较于传统的 scp 和 cp 等,rsync 的主要优势就在于实时性备份,但是同时也存在问题:

  • rsync 同步需要扫描所有文件进行对比,然后进行差异性同步,如果文件数量很大,就会非常耗时。
  • rsync 无法实时的去检测文件变化,使用定时任务肯定会存在时间差,这就无法实现实时同步。

为了解决上面的问题,于是引入了 inotify。

  • inotify 是一种强大的,细粒度的异步文件系统事件监控,从 Linux 的 2.6.13内核之后开始支持。
  • inotify 通过内核的接口,实现了实时的去监控系统中文件的添加,删除,修改,移动等细粒度操作。

3、安装inotify

inotify 是 Github 上面的一个开源项目,可以去下载:

http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
https://github.com/rvoicilas/inotify-tools

准备两台 CentOS 7 的机器,IP 地址为:node-01(192.168.200.101),node-02(192.168.200.102)

数据同步方向为:node-01(客户端)实时同步到 node-02(服务端)上面。
node-01:查看服务器是否支持

uname -a

# 查看是否有三个文件
ls /proc/sys/fs/inotify

4、介绍inotify

inotify 主要涉及的文件:

  • inotifywait:用于等待文件或文件集上的一个特定事件,他可以监控任何文件和目录设置,并且可以递归地监控整个目录树。
  • inotifywatch:用于收集被监控的文件系统统计数据,包括每个inotify事件发生多少次等信息。

阈值配置:/proc/sys/fs/inotify/下的文件

  • max_queued_events:调用 inotify_init 时分配给 inotify instance 中可排队的 event 的数据最大值,超出这个值的事件被丢弃,但会触发 IN_Q_OVERFLOW 事件。
  • max_user_instances:每个 real user ID 可创建的 inotify instatnces 的数量上限,默认 128。
  • max_user_watches:每个 inotify instatnces 可监控最大文件数,如果文件数目巨大,需要增加此值的大小

5、配置服务器

node-02:安装 rsync 服务端

# 安装 rsync
yum -y install rsync

# 添加用户
useradd rsync -s /sbin/nologin -M

# 创建测试数据目录,由于同步真实用户使用的是 rsync 用户,所以需要给目录授权
mkdir /data
chown rsync.rsync /data/

node-02:添加主配置文件 /etc/rsyncd.conf

# RSYNC Config
# 指定传输文件使用的用户
uid = rsync
# 指定传输文件使用的用户组
gid = rsync
# 安全设置,切换到安全目录
use chroot = no
# 最大连接数
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
    # 传输的删除时忽略 I/O 错误,报错会跳过--delete
    ignore errors
    # 允许写入
    read only = false
    # 不允许列出
    list = false
    # 允许的网段,多个使用空格隔开
    hosts allow = 192.168.200.0/24
    # 拒绝的网段,拒绝所有
    hosts deny = 0.0.0.0/32
    # 连接的虚拟用户,非系统用户
    auth users = rsync_user
    # 虚拟用户的账号密码文件
    secrets file = /etc/rsync-data.password
    # 注释说明
    comment = Test file share

node-02:创建密码文件 /etc/rsync-data.password

echo "rsync_user:123456" > /etc/rsync-data.password
chmod 600 /etc/rsync-data.password

node-02:启动服务

rsync --daemon
netstat -tlunp | grep 873

6、客户端配置

node-01:直接安装

# 安装 rsync
yum -y install rsync

# 解压安装 inotify
tar -zxf inotify-tools-3.20.2.2.tar.gz 
cd inotify-tools-3.20.2.2/
./configure 
make 
make install

# 查看安装结果
ll /usr/local/bin/inotifywa*

由于 inotify 是用于监控文件变化,所以需要安装在内容发布节点。

创建密码文件
node-01:配置 rsync 客户端密码文件

echo "123456" > /etc/rsync-data.password
chmod 600 /etc/rsync-data.password

了解inotify
node-01:在启动脚本之前做一个inotify的小实验
在node-01-窗口一:执行inotifywait工具对/root/jiaofan目录进行监控。

inotifywait -mrq -e modify,create,move,delete /root/jiaofan
#inotifywait 可监控 modify(修改),create(创建),move(移动),delete(删除),attrib(属性更改)等各种事件

在node-01-窗口二:在/root/jiaofan下创建文件或者文件夹

[root@localhost jiaofan]# mkdir aaa
[root@localhost jiaofan]# touch a.txt
[root@localhost jiaofan]# touch b.txt
[root@localhost jiaofan]# rm -f b.txt

观察node-01-窗口一:

/root/jiaofan/ CREATE,ISDIR aaa
/root/jiaofan/ CREATE a.txt
/root/jiaofan/ CREATE b.txt
/root/jiaofan/ DELETE b.txt
#inotifywait输出的监控结果中,每行记录中包括目录,事件,文件,可识别变动情况,所以需要编写脚本,只要检测到有变动时就执行rsync上行同步操作。

7、为inotify编写脚本
node-01:创建同步脚本 /shell/RSYNC_INOTIFY.sh

#!/bin/sh

#############################################################
# 用途:rsync + inotify 数据实时同步
# 作者:Dylan
# 时间:2021年8月28日
#############################################################

#############################################################
# 变量配置
#############################################################
# 需要同步的本地目录
SOURCE_DIR=/data/

# 同步到 rsync 服务端的模块
DST=data

# 同步用户
RSYNC_USER=rsync_user

# 同步密码文件
PASSWORD_FILE=/etc/rsync-data.password

# 服务端机器的 IP,可以多个
DST_IP=(
192.168.200.102
)

#############################################################
# 同步监听
#############################################################
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move ${SOURCE_DIR} | while read DIRECTORY EVENT FILE
do
    for IP in ${DST_IP[@]};do
        rsync -avH --port=873 --progress --delete ${SOURCE_DIR} ${RSYNC_USER}@${IP}::${DST} --password-file=${PASSWORD_FILE}
        echo "  ${DIRECTORY} ${EVENT} ${FILE} was rsynced" >> /tmp/rsync.log 2>&1
    done
done

启动脚本

sh /shell/RSYNC_INOTIFY.sh &

8、inotifywait参数说明

-m:--monitor,表示始终保持事件监听状态。
-r:--recursive,表示递归查询目录。
-q:--quiet,表示打印出监控事件。
--timefmt:时间格式。
--format:监听到的文件变化的信息:
   %w:表示发生事件的目录。
   %f:表示发生事件的文件。
   %e:表示发生的事件。
   %T:使用由 --timefmt 定义的时间格式。
-e:--event,指定要监控的事件:
   access:访问,读取文件。
   modify:修改,文件内容被修改。
   attrib:属性,文件元数据被修改。
   move:移动,对文件进行移动操作。
   create:创建,生成新文件。
   open:打开,对文件进行打开操作。
   close:关闭,对文件进行关闭操作。
   delete:删除,文件被删除。

9、测试同步

此时只需要在 node-01 上面创建删除文件,则会同步到 node-02的 /data 目录下,并且两边的文件保持一致。

值得注意的地方为:

  • 如果 node-02的 /data 目录下原本有其它文件,请确保该文件 rsync 用户具备权限,否则同步时无法删除。
  • 对于线上数据备份机器,不建议 rsync 命令中加入 --delete 参数,也不去监听 delete
    操作,避免误删在备份机器上也没有保留。