zoukankan      html  css  js  c++  java
  • Rsync+Inotify实时同步环境部署

    随着应用系统规模的不断扩大,对数据的安全性和可靠性也提出的更好的要求,rsync在高端业务系统中也逐渐暴露出了很多不足。
    首先,rsync在同步数据时,需要扫描所有文件后进行比对,进行差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将是非常耗时的,并且正在发生变化的往往是其中很少的一部分,这是非常低效的方式。
    其次,rsync不能实时的去监测、同步数据,虽然它可以通过linux守护进程的方式进行触发同步,但是两次触发动作一定会有时间差,这样就导致了服务端和客户端数据可能出现不一致,无法在应用故障时完全的恢复数据。

    基于以上两种情况,可以使用rsync+inotify的组合来解决,可以实现数据的实时同步。

    inotify是一种强大的、细粒度的、异步的文件系统事件控制机制。linux内核从2.6.13起,加入了inotify支持,通过inotify可以监控文件系统中添加、删除、修改、移动等各种事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools正是实施监控的软件。
    在使用rsync首次全量同步后,结合inotify对源目录进行实时监控,只有有文件变动或新文件产生,就会立刻同步到目标目录下,非常高效使用!

    -----------------------------------------------------------------------------------------------------------
    下面分享下我在实际工作中的一个rsync+inotify案例(其实是个网站图片备份方案):

    需求说明:
    分别将
    192.168.1.106的/Data/fangfull_upload和/Data/erp_upload
    192.168.1.57的/Data/xqsj_upload/和/Data/fanghu_upload_src
    192.168.1.139的/Data/Static_img/webroot/ssapp-prod和/usr/local/nginx/html/ssapp.prod
    实时同步到
    192.168.1.5的/home/backup/image-back目录下对应的fangfull_upload、erp_upload、xqsj_upload、fanghu_upload_src、ssapp-prod和ssapp.prod目录。

    这样的话:
    (1)192.168.1.106、192.168.1.57、192.168.1.139这三台服务器是源服务器,作为rsync的客户端,部署rsync+inotify。
    (2)192.168.1.5是目标服务器,作为rsync的服务端。只需要安装配置rsync即可,不需要安装inotify。

    ---------------------------------------------------------------
    详细部署过程,记录如下:

    第一部分:在目标服务器192.168.1.5上部署rsync服务端。

    1)关闭selinux
    [root@bastion-IDC ~]# vim /etc/selinux/config 
    SELINUX=disabled 
    [root@bastion-IDC ~]# setenforce 0

    2)防火墙上允许以上三台源服务器访问它的22端口和873端口
    [root@bastion-IDC ~]# vim /etc/sysconfig/iptables
    .......
    .......
    -A INPUT -s 192.168.1.106 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
    -A INPUT -s 192.168.1.57 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
    -A INPUT -s 192.168.1.139 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
    -A INPUT -s 192.168.1.106 -m state --state NEW -m tcp -p tcp --dport 873 -j ACCEPT
    -A INPUT -s 192.168.1.57 -m state --state NEW -m tcp -p tcp --dport 873 -j ACCEPT
    -A INPUT -s 192.168.1.139 -m state --state NEW -m tcp -p tcp --dport 873 -j ACCEPT

    [root@bastion-IDC ~]# /etc/init.d/iptables restart

    如若hosts.allow里面做了限制,同样也要开放以上三台源服务器的权限
    [root@bastion-IDC ~]# vim /etc/hosts.allow 
    #
    # hosts.allow This file contains access rules which are used to
    # allow or deny connections to network services that
    # either use the tcp_wrappers library or that have been
    # started through a tcp_wrappers-enabled xinetd.
    #
    # See 'man 5 hosts_options' and 'man 5 hosts_access'
    # for information on rule syntax.
    # See 'man tcpd' for information on tcp_wrappers
    #
    sshd:192.168.1.106,192.168.1.57,192.168.1.139:allow
    sshd:all:deny
    [root@bastion-IDC ~]# cat /etc/hosts.deny 
    #
    # hosts.deny This file contains access rules which are used to
    # deny connections to network services that either use
    # the tcp_wrappers library or that have been
    # started through a tcp_wrappers-enabled xinetd.
    #
    # The rules in this file can also be set up in
    # /etc/hosts.allow with a 'deny' option instead.
    #
    # See 'man 5 hosts_options' and 'man 5 hosts_access'
    # for information on rule syntax.
    # See 'man tcpd' for information on tcp_wrappers
    #

    3)安装部署rsync服务
    注意:CentOS中是以xinetd来管理Rsync服务的
    [root@bastion-IDC ~]# yum install rsync xinetd
    [root@bastion-IDC ~]# vim /etc/xinetd.d/rsync 
    .....
    disable = no               #由默认的yes改为no,设置开机启动rsync

    启动xineted服务
    [root@bastion-IDC ~]# /etc/init.d/xinetd start

    创建/etc/rsyncd.conf文件,并配置同步策略。添加如下代码:
    [root@bastion-IDC ~]# vim /etc/rsyncd.conf
    log file = /var/log/rsyncd.log          #日志文件位置,启动rsync后自动产生这个文件,无需提前创建
    pidfile = /var/run/rsyncd.pid           #pid文件的存放位置
    lock file = /var/run/rsync.lock        #支持max connections参数的锁文件
    secrets file = /etc/rsync.pass         #用户认证配置文件,里面保存用户名称和密码,后面会创建这个文件
    motd file = /etc/rsyncd.Motd          #rsync启动时欢迎信息页面文件位置(自己创建这个文件,内容随便自定义)

    [fangfull_upload]                            #自定义名称
    path = /home/backup/image-back/fangfull_upload           #rsync服务端数据目录路径,即同步到目标目录后的存放路径
    comment = fangfull_upload                                             #模块名称与[fangfull_upload]自定义名称相同
    uid = nobody                                 #设置rsync运行的uid权限。这个要保证同步到目标目录后的权限和源目录一致,即都是nobody!
    gid = nobody                                #设置rsync运行的gid权限。
    port=873                                    #默认的rsync端口
    use chroot = no                          #默认为true,修改为no或false,增加对目录文件软连接的备份
    read only = no                            #设置rsync服务端文件为读写权限
    list = no                                      #不显示rsync服务端资源列表
    max connections = 200              #最大连接数
    timeout = 600                           #设置超时时间
    auth users = RSYNC_USER          #执行数据同步的用户名,需要后面手动设置。可以设置多个,用英文状态下逗号隔开
    hosts allow = 192.168.1.106        #允许进行数据同步的客户端IP地址,可以设置多个,用英文状态下逗号隔开
    hosts deny = 192.168.1.194       #禁止数据同步的客户端IP地址,可以设置多个,用英文状态下逗号隔开(如果没有禁止,就不用设置这一行)

    [erp_upload] 
    path = /home/backup/image-back/erp_upload
    comment = erp_upload
    uid = nobody 
    gid = nobody
    port=873 
    use chroot = no 
    read only = no
    list = no
    max connections = 200 
    timeout = 600 
    auth users = RSYNC_USER
    hosts allow = 192.168.1.106

    [xqsj_upload] 
    path = /home/backup/image-back/xqsj_upload
    comment = xqsj_upload
    uid = nobody 
    gid = nobody
    port=873 
    use chroot = no 
    read only = no
    list = no
    max connections = 200 
    timeout = 600 
    auth users = RSYNC_USER
    hosts allow = 192.168.1.57

    [fanghu_upload_src] 
    path = /home/backup/image-back/fanghu_upload_src
    comment = fanghu_upload_src
    uid = nobody 
    gid = nobody
    port=873 
    use chroot = no 
    read only = no
    list = no
    max connections = 200 
    timeout = 600 
    auth users = RSYNC_USER
    hosts allow = 192.168.1.57

    [ssapp-prod] 
    path = /home/backup/image-back/ssapp-prod
    comment = ssapp-prod
    uid = nginx
    gid = nginx
    port=873 
    use chroot = no 
    read only = no
    list = no
    max connections = 200 
    timeout = 600 
    auth users = RSYNC_USER
    hosts allow = 192.168.1.139

    [ssapp.prod] 
    path = /home/backup/image-back/ssapp.prod
    comment = ssapp.prod
    uid = nginx 
    gid = nginx
    port=873 
    use chroot = no 
    read only = no
    list = no
    max connections = 200 
    timeout = 600 
    auth users = RSYNC_USER
    hosts allow = 192.168.1.139

    创建用户认证文件 (多个模块用的是这同一个认证文件)
    [root@bastion-IDC ~]# vim /etc/rsync.pass 
    RSYNC_USER:123456@rsync

    设置文件权限,即rsyncd.conf和rsync.pass认证文件都是600权限!
    [root@bastion-IDC ~]# chmod 600 /etc/rsyncd.conf 
    [root@bastion-IDC ~]# chmod 600 /etc/rsync.pass

    重启rsync服务
    [root@bastion-IDC ~]# /etc/init.d/xinetd restart
    [root@bastion-IDC ~]# lsof -i:873
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    xinetd 22041 root 5u IPv6 3336440 0t0 TCP *:rsync (LISTEN)

    4)最后,创建rsync同步过来后的目标目录
    [root@bastion-IDC ~]# cd /home/backup/image-back/
    [root@bastion-IDC image-back]# mkdir fangfull_upload erp_upload xqsj_upload fanghu_upload_src ssapp-prod ssapp.prod
    [root@bastion-IDC image-back]# ll
    total 40
    drwxr-xr-x. 8 nobody nobody 4096 Jun 12 17:25 erp_upload
    drwxrwxrwx. 584 nobody nobody 20480 Oct 26 13:41 fangfull_upload
    drwxr-xr-x. 11 nobody nobody 4096 Oct 26 14:23 fanghu_upload_src
    drwxr-xr-x. 10 nginx nginx 4096 Oct 26 13:44 ssapp-prod
    drwxr-xr-x. 7 nginx nginx 4096 Oct 24 18:01 ssapp.prod
    drwxrwxrwx. 144 nobody nobody 4096 Sep 26 11:25 xqsj_upload

    第二部分:在源服务器192.168.1.106、192.168.1.57、192.168.1.139部署rsync客户端和inotify监控。

    1)三台机器同样操作
    关闭selinux,做为客户端的rsync可以不用在iptables里开放873端口
    [root@static-img ~]# vim /etc/selinux/config 
    SELINUX=disabled 
    [root@static-img ~]# setenforce 0

    2)三台机器同样操作
    安装rsync
    [root@static-img ~]# yum install rsync xinetd 
    [root@static-img ~]# vim /etc/xinetd.d/rsync 
    .....
    disable = no                     #由默认的yes改为no,设置开机启动rsync

    启动rsync服务
    [root@static-img ~]# /etc/init.d/xinetd start 
    [root@static-img ~]# lsof -i:873
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    xinetd 3268 root 5u IPv4 4139812 0t0 TCP *:rsync (LISTEN)

    创建同步的密码文件,这个文件名可以跟服务端的认证文件不一样,但是里面的密码必须一致!用于rsync同步命令中。不过,最好两边的文件设置成一样,便于管理
    [root@static-img ~]# vim /etc/rsync.pass 
    123456@rsync

    设置rsync.pass密码文件为600权限
    [root@static-img ~]# chmod 600 /etc/rsync.pass

    3)三台机器同样操作
    查看服务器内核是否支持inotify,出现下面的内容,说明服务器内核支持inotify
    [root@static-img ~]# ll /proc/sys/fs/inotify
    total 0
    -rw-r--r-- 1 root root 0 Oct 26 12:03 max_queued_events
    -rw-r--r-- 1 root root 0 Oct 26 12:03 max_user_instances
    -rw-r--r-- 1 root root 0 Oct 26 12:03 max_user_watches

    注意:Linux下支持inotify的内核最小为2.6.13,可以输入命令:uname -a查看内核
    CentOS 5.X 内核为2.6.18,默认已经支持inotify
    [root@static-img ~]# uname -a
    Linux static-img 2.6.32-573.22.1.el6.x86_64 #1 SMP Wed Mar 23 03:35:39 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

    下面开始安装inotify-tools
    [root@static-img ~]# yum install make gcc gcc-c++                          #安装编译工具
    [root@static-img ~]# cd /usr/local/src
    [root@static-img src]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
    [root@static-img src]# tar zxvf inotify-tools-3.14.tar.gz
    [root@static-img src]# cd inotify-tools-3.14
    [root@static-img inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify
    [root@static-img inotify-tools-3.14]# make && make install

    发现已经成功安装inotify-tools了
    [root@static-img inotify-tools-3.14]# ll -d /usr/local/inotify/
    drwxr-xr-x 6 root root 4096 Oct 26 12:01 /usr/local/inotify/

    设置系统环境变量
    [root@static-img ~]# vim /etc/profile
    ......
    export PATH=$PATH:/usr/local/inotify/bin
    [root@static-img ~]# source /etc/profile

    添加库文件
    [root@static-img ~]# vim /etc/ld.so.conf
    /usr/local/inotify/lib
    [root@static-img ~]# ldconfig

    修改inotify默认参数(inotify默认内核参数值太小)
    查看系统默认参数值
    [root@static-img ~]# sysctl -a | grep max_queued_events
    fs.inotify.max_queued_events = 16384
    [root@static-img ~]# sysctl -a | grep max_user_watches
    fs.inotify.max_user_watches = 8192
    [root@static-img ~]# sysctl -a | grep max_user_instances
    fs.inotify.max_user_instances = 128

    修改参数:
    [root@static-img ~]# sysctl -w fs.inotify.max_queued_events="99999999"
    [root@static-img ~]# sysctl -w fs.inotify.max_user_watches="99999999"
    [root@static-img ~]# sysctl -w fs.inotify.max_user_instances="65535"

    参数说明:
    max_queued_events:
    inotify队列最大长度,如果值太小,会出现"** Event Queue Overflow **"错误,导致监控文件不准确
    max_user_watches:
    要同步的文件包含多少目录,可以用:find /Data/xqsj_upload -type d | wc -l 统计这些源目录下的目录数,必须保证max_user_watches值大于统计结果(这里/Data/xqsj_upload为同步的源文件目录)
    max_user_instances:
    每个用户创建inotify实例最大值


    4)接着执行同步操作:
    分别在三台源服务器上执行rsync首次全量同步的操作(加--delete参数,保持目标目录和源目录下文件绝对一致)
    -------------------------------------------------------------------------------------------------------------------------------------------------------
    在192.168.1.106服务器上
    第一次全量同步:
    [root@fangfull_web ~]# rsync -avH --port=873 --progress --delete /Data/fangfull_upload/ RSYNC_USER@192.168.1.5::fangfull_upload --password-file=/etc/rsync.pass
    [root@fangfull_web ~]# rsync -avH --port=873 --progress --delete /Data/erp_upload/ RSYNC_USER@192.168.1.5::erp_upload --password-file=/etc/rsync.pass

    待第一次rsync全量同步完成后,就进行rsync+inotify实时同步脚本操作。
    实时同步脚本里添加的是--delete-before参数,而不是--delete参数(第一次全量同步时rsync用的参数),二者区别:
    --delete参数:表示rsync同步前,暴力删除目标目录中的所有文件,然后再执行同步操作。
    --delete-before参数:表示rsync同步前,会先对目标目录进行一次扫描检索,删除目标目录中对比源目录的多余文件,然后再执行同步操作。显然比--delete参数安全些。
    [root@fangfull_web1 ~]# cd /home/rsync/
    [root@fangfull_web1 rsync]# cat rsync_fangfull_upload_inotify.sh 
    #!/bin/bash
    SRCDIR=/Data/fangfull_upload/
    USER=RSYNC_USER
    IP=192.168.1.5
    DESTDIR=fangfull_upload
    /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $SRCDIR | while read file
    do
    /usr/bin/rsync -avH --port=873 --progress --delete-before $SRCDIR $USER@$IP::$DESTDIR --password-file=/etc/rsync.pass
    echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1
    done
    [root@fangfull_web1 rsync]# cat rsync_erp_upload_inotify.sh 
    #!/bin/bash
    SRCDIR=/Data/erp_upload/
    USER=RSYNC_USER
    IP=192.168.1.5
    DESTDIR=erp_upload
    /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $SRCDIR | while read file
    do
    /usr/bin/rsync -avH --port=873 --progress --delete-before $SRCDIR $USER@$IP::$DESTDIR --password-file=/etc/rsync.pass
    echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1
    done

    然后启动同步脚本,放在后台执行!
    [root@fangfull_web1 rsync]# nohup sh rsync_fangfull_upload_inotify.sh &
    [root@fangfull_web1 rsync]# nohup sh rsync_erp_upload_inotify.sh &

    检查下是否脚本启动成功了
    [root@fangfull_web1 rsync]# ps -ef|grep inotify
    root 11390 1 0 13:41 ? 00:00:00 sh rsync_erp_upload_inotify.sh
    root 11392 11390 0 13:41 ? 00:00:00 sh rsync_erp_upload_inotify.sh
    root 11397 1 0 13:41 ? 00:00:00 sh rsync_fangfull_upload_inotify.sh
    root 11399 11397 0 13:41 ? 00:00:00 sh rsync_fangfull_upload_inotify.sh
    root 21842 11702 0 17:22 pts/0 00:00:00 grep --color=auto inotify

    最后进行测试:
    比如在源目录/Data/fangfull_upload中创建一个文件或目录,会自动实时同步到目标机器192.168.1.5的目标目录/home/backup/image-back/fangfull_upload中。

    --------------------------------------------------------------------------------------------------------------------------------------------------
    在192.168.1.57服务器上
    第一次全量同步:
    [root@xqsj_web ~]# rsync -avH --port=873 --progress --delete /Data/xqsj_upload/ RSYNC_USER@192.168.1.5::xqsj_upload --password-file=/etc/rsync.pass
    [root@xqsj_web ~]# rsync -avH --port=873 --progress --delete /Data/fanghu_upload_src/ RSYNC_USER@192.168.1.5::fanghu_upload_src --password-file=/etc/rsync.pass

    rsync+inotify实时同步:
    [root@xqsj_web1 ~]# cd /home/rsync/
    [root@xqsj_web1 rsync]# cat rsync_xqsj_upload_inotify.sh 
    #!/bin/bash
    SRCDIR=/Data/xqsj_upload/
    USER=RSYNC_USER
    IP=192.168.1.5
    DESTDIR=xqsj_upload
    /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $SRCDIR | while read file
    do
    /usr/bin/rsync -avH --port=873 --progress --delete-before $SRCDIR $USER@$IP::$DESTDIR --password-file=/etc/rsync.pass
    echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1
    done
    [root@xqsj_web1 rsync]# cat rsync_fanghu_upload_src_inotify.sh 
    #!/bin/bash
    SRCDIR=/Data/fanghu_upload_src/
    USER=RSYNC_USER
    IP=192.168.1.5
    DESTDIR=fanghu_upload_src
    /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $SRCDIR | while read file
    do
    /usr/bin/rsync -avH --port=873 --progress --delete-before $SRCDIR $USER@$IP::$DESTDIR --password-file=/etc/rsync.pass
    echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1
    done

    然后启动同步脚本,放在后台执行!
    [root@fangfull_web1 rsync]# nohup sh rsync_xqsj_upload_inotify.sh &
    [root@fangfull_web1 rsync]# nohup rsync_fanghu_upload_src_inotify.sh &

    最后进行测试:
    比如在源目录/Data/xqsj_upload中创建一个文件或目录,会自动实时同步到目标机器192.168.1.5的目标目录/home/backup/image-back/xqsj_upload中。

    --------------------------------------------
    在192.168.1.139服务器上
    第一次全量同步:
    [root@static-img ~]# rsync -avH --port=873 --progress --delete /Data/Static_img/webroot/ssapp-prod/ RSYNC_USER@192.168.1.5::ssapp-prod --password-file=/etc/rsync.pass
    [root@static-img ~]# rsync -avH --port=873 --progress --delete /usr/local/nginx/html/ssapp.prod/ RSYNC_USER@192.168.1.5::ssapp.prod --password-file=/etc/rsync.pass

    rsync+inotify实时同步:
    [root@static-img ~]# cd /home/rsync/
    [root@static-img rsync]# cat rsync_ssapp-prod_inotify.sh 
    #!/bin/bash
    SRCDIR=/Data/Static_img/webroot/ssapp-prod/
    USER=RSYNC_USER
    IP=192.168.1.5
    DESTDIR=ssapp-prod
    /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $SRCDIR | while read file
    do
    /usr/bin/rsync -avH --port=873 --progress --delete-before $SRCDIR $USER@$IP::$DESTDIR --password-file=/etc/rsync.pass
    echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1
    done

    [root@static-img rsync]# cat rsync_ssapp.prod_inotify.sh 
    #!/bin/bash
    SRCDIR=/usr/local/nginx/html/ssapp.prod/
    USER=RSYNC_USER
    IP=192.168.1.5
    DESTDIR=ssapp.prod
    /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $SRCDIR | while read file
    do
    /usr/bin/rsync -avH --port=873 --progress --delete-before $SRCDIR $USER@$IP::$DESTDIR --password-file=/etc/rsync.pass
    echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1
    done

    然后启动同步脚本,放在后台执行!
    [root@fangfull_web1 rsync]# nohup sh rsync_ssapp-prod_inotify.sh &
    [root@fangfull_web1 rsync]# nohup rsync_ssapp.prod_inotify.sh &

    最后进行测试:
    比如在源目录/Data/Static_img/webroot/ssapp-prod中创建一个文件或目录,会自动实时同步到目标机器192.168.1.5的目标目录/home/backup/image-back/ssapp-prod中。

    如果在同步过程中,发现中途报错!重复执行同步命令一直是报这个错误:
    rsync error: some files/attrs were not transferred (see previous errors) (code 23) at
    main.c(1505)

    最后发现原因:
    是因为在同步的时候,源目录下有软链接文件!
    rsync同步软链接文件,应该加参数-l

    所以,最好在使用rsync同步命令的时候,后面跟-avpgolr参数组合(将上面的-avH改成-avpgolr)
    -a:递归
    -v:打印详细过程
    -p:保持文件属性
    -g:文件所属组不变
    -o:文件所属者不变
    -l:软连接属性
    -r:同步目录时的参数

    参考文章:
    https://www.cnblogs.com/kevingrace/p/6001252.html

  • 相关阅读:
    三数之和
    罗马数字与整数
    Oracle 开启或关闭归档
    Oracle RMAN scripts to delete archivelog
    Oracle check TBS usage
    Oracle kill locked sessions
    场景9 深入RAC运行原理
    场景7 Data Guard
    场景4 Data Warehouse Management 数据仓库
    场景5 Performance Management
  • 原文地址:https://www.cnblogs.com/MR-ws/p/15019205.html
Copyright © 2011-2022 走看看