首页 小组 文章 搜索 用户

[数据同步]centos7下搭建rsync+inotify实现单向数据实时同步

2020-09-03 19:57:05
0
251

测试环境,centos7,分别ip为server1:192.168.0.5和server2:192.168.0.6,场景:把server1的/home/web目录下全部同步到server2的/home/osyum目录。注意,先要确定在server1和server2上有这两个文件夹。

yum update -y
yum -y install epel*
yum install -y groupinstall pcre-devel zlib-devel gcc gcc-c++ autoconf automake make pcre-devel zlib-devel
yum -y install pcre-devel ctags-etags openssl openssl-devel
yum install lz4* libzstd* xx* net-tools -y

在server2上增加防火墙873端口

firewall-cmd --add-port=873/tcp --permanent
firewall-cmd --reload

分别在两台服务器上下载安装rsync最新版,你可以去rsync官网下载,解压后并安装

wget https://download.samba.org/pub/rsync/src/rsync-3.2.3.tar.gz
tar zxvf rsync-3.2.3.tar.gz
cd rsync-3.2.3
./configure
make&&make install
1.先配置server2也就是192.168.0.6的目标服务器
创建rsync配置文件
vi /etc/rsyncd.conf
复制左边的代码文件
log file =/var/log/rosyumd.log
pidfile =/var/run/rosyumd.pid
lock file =/var/run/rosyum.lock
secretsfile = /etc/rsync.pass
motd file =/etc/rosyumd.Motd
[osyum]
path = /home/osyum/
comment = osyum
uid = root
gid = root
port=873
use chroot= no
read only =no
list = no
maxconnections = 200
timeout =600
auth users= osyum
hosts allow= 192.168.0.5
hosts deny= 192.168.0.2

log file 日志文件位置,启动rsync后自动产生这个文件,无需提前创建

pidfile pid文件的存放位置

lock file 支持max connections参数的锁文件

secretsfile 用户认证配置文件,里面保存用户名称和密码,后面会创建这个文件

motd file rsync启动时欢迎信息页面文件位置(文件内容自定义)

[osyum] #自定义名称

path rsync服务端数据目录路径

comment 模块名称与[md]自定义名称相同

uid 设置rsync运行权限为root

gid 设置rsync运行权限为root

port 默认端口

use chroot 默认为true,修改为no,增加对目录文件软连接的备份

read only  设置rsync服务端文件为读写权限

list 不显示rsync服务端资源列表

maxconnections 最大连接数

timeout 设置超时时间

auth users =认证用户,没用就是匿名

hosts allow 允许进行数据同步的客户端IP地址,可以设置多个,用英文状态下逗号隔开

hosts deny 禁止数据同步的客户端IP地址,可以设置多个,用英文状态下逗号隔开

保存并退出后,创建用户名为osyum用户密码为W812Ca158的认证文件,
echo 'osyum:W812Ca158 ' >>/etc/rsync.pass

设置权限

chmod 600 /etc/rsyncd.conf
chmod 600 /etc/rsync.pass
启动rsnc
rsync --daemon --config=/etc/rsyncd.conf
加入开机启动
echo "rsync --daemon --config=/etc/rsyncd.conf" >>/etc/rc.local
tail -1 /etc/rc.local
chmod +x /etc/rc.local
查看有无运行
ps -ef|grep rsync
成功以下
root       1528      1  0 13:57 ?        00:00:00 rsync --daemon --config=/etc/rsyncd.conf
root       1559   1481  0 14:01 pts/0    00:00:00 grep --color=auto rsync
2.配置源服务器也就是server1,192.168.0.5
配置rsnc文件
vi /etc/reyncd.conf
输入以下代码
log file = /var/log/rsyncd.log
pidfile = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
motd file = /etc/rsyncd.Motd
[osyum]
comment = osyum
uid = root
gid = root
port=873
保存并退出后,创建密码文件
echo 'W812Ca158 ' >>/etc/passwd.txt

保存并退出,并给权限

chmod 600 /etc/passwd.txt

在server1上的/home/web目录里创建一个qbc.txt文件并给权限

echo 'aaaaa ' >>/home/web/aaa.txt
chown -R nobody:nobody /home/web/aaa.txt

现在可以测试了

rsync -avH --port=873 --progress --delete -o -g /home/web/ osyum@192.168.0.6::osyum --password-file=/etc/passwd.txt

现在到server2的/home/web目录里查看有没有aaa.txt的文件

cd /home/web
ll

显示

-rw-r--r--. 1 nobody nobody 5 Sep  4 13:57 aaa.txt

这里已经把rsync的同步完成了

3.在server1上配置inotify实现监控文件有增加或修改时自动同步

yum install git libtool* -y
cd /root
git clone  https://github.com/inotify-tools/inotify-tools.git
cd inotify-tools
sh autogen.sh
./configure
make&&make install

创建监控脚本

mkdir -p /inotify
vi /inotify/keep.sh

#1输入以下代码,这个代码每次都是全备份,建议使用#2

#!/bin/bash
inotifywait -mrq --timefmt '%Y/%m/%d %H:%M' --format '%T %e %w%f' -e create,attrib,modify,moved_to,close_write,delete,move  /home/web/ |while read file
do
rsync -avH --port=873 --progress --delete -o -g /home/web/ osyum@192.168.0.6::osyum --password-file=/etc/passwd.txt
done

#2,此源码来源于网络的(广州小朱)对于小文件优化的更好

#!/bin/bash
src=/home/web/                           # 需要同步的源路径
des=osyum                             # 目标服务器上 rsync --daemon 发布的名称,rsync --daemon这里就不做介绍了,网上搜一下,比较简单。
rsync_passwd_file=/etc/passwd.txt          # rsync验证的密码文件
host1=192.168.0.6                 # 目标服务器1
user=osyum                            # rsync --daemon定义的验证用户名
cd ${src}                              # 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file         # 把监控到有发生更改的"文件路径列表"循环
do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify输出切割 把文件路径部分赋值给INO_FILE
        echo "-------------------------------$(date)------------------------------------"
        echo $file
        #增加、修改、写入完成、移动进事件
        #增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
        if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]         # 判断事件类型
        then
                echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
                rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host1}::${des}
                 #仔细看 上面的rsync同步命令 源是用了$(dirname ${INO_FILE})变量 即每次只针对性的同步发生改变的文件的目录(只同步目标文件的方法在生产环境的某些极端环境下会漏文件 现在可以在不漏文件下也有不错的速度 做到平衡) 然后用-R参数把源的目录结构递归到目标后面 保证目录结构一致性
        fi
        #删除、移动出事件
        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
        then
                echo 'DELETE or MOVED_FROM'
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host1}::${des} 
                #看rsync命令 如果直接同步已删除的路径${INO_FILE}会报no such or directory错误 所以这里同步的源是被删文件或目录的上一级路径,并加上--delete来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。这里有更好方法的同学,欢迎交流。
        fi
        #修改属性事件 指 touch chgrp chmod chown等操作
        if [[ $INO_EVENT =~ 'ATTRIB' ]]
        then
                echo 'ATTRIB'
                if [ ! -d "$INO_FILE" ]                 # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync会顺带更新此目录。
                then
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host1}::${des} 
                fi
        fi
done

如果需要有多个同步,使用#3此源码来源于网络的(广州小朱)对于小文件优化的更好

#!/bin/bash
src=/home/web/                           # 需要同步的源路径
des=osyum                            # 目标服务器上 rsync --daemon 发布的名称,rsync --daemon这里就不做介绍了,网上搜一下,比较简单。
rsync_passwd_file=/etc/rsyncd.passwd            # rsync验证的密码文件
host1=192.168.0.11                 # 目标服务器1
host2=192.168.0.12                 # 目标服务器2
user=osyum                            # rsync --daemon定义的验证用户名
cd ${src}                              # 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file         # 把监控到有发生更改的"文件路径列表"循环
do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify输出切割 把文件路径部分赋值给INO_FILE
        echo "-------------------------------$(date)------------------------------------"
        echo $file
        #增加、修改、写入完成、移动进事件
        #增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
        if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]         # 判断事件类型
        then
                echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
                rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host1}::${des} &&         # INO_FILE变量代表路径哦  -c校验文件内容
                rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host2}::${des}
                 #仔细看 上面的rsync同步命令 源是用了$(dirname ${INO_FILE})变量 即每次只针对性的同步发生改变的文件的目录(只同步目标文件的方法在生产环境的某些极端环境下会漏文件 现在可以在不漏文件下也有不错的速度 做到平衡) 然后用-R参数把源的目录结构递归到目标后面 保证目录结构一致性
        fi
        #删除、移动出事件
        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
        then
                echo 'DELETE or MOVED_FROM'
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host1}::${des} &&
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host2}::${des}
                #看rsync命令 如果直接同步已删除的路径${INO_FILE}会报no such or directory错误 所以这里同步的源是被删文件或目录的上一级路径,并加上--delete来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。这里有更好方法的同学,欢迎交流。
        fi
        #修改属性事件 指 touch chgrp chmod chown等操作
        if [[ $INO_EVENT =~ 'ATTRIB' ]]
        then
                echo 'ATTRIB'
                if [ ! -d "$INO_FILE" ]                 # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync会顺带更新此目录。
                then
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host1}::${des} &&            
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${host2}::${des}
                fi
        fi
done

给权

chmod 755 /inotify/keep.sh

这时可以放入后台进行测试

/inotify/keep.sh &

加入开机启动

echo "/inotify/keep.sh &" >>/etc/rc.local
tail -1 /etc/rc.local
chmod +x /etc/rc.local

重启进行测试。完成

评论