rsync远程同步及rsync+inotify实时同步

思维代入

正确、有效的备份方案是保障系统及数据安全的重要手段。在服务器中,通常会结合计划性任务、shell脚本来执行本地备份。但有时候为了提高备份的可靠性,异地备份也是非常有必要的。那下面就给大家介绍一种异地远程备份的方法:rsync远程备份。

rsync简介

rsync是一个开源的快速备份工具,可以在不同主机之间镜像同步整个目录树,支持增量备份、保持链接和权限,且采用优化的同步算法,在传输前执行压缩,因此非常适用于异地备份、镜像服务等应用。

rsync在同步过程中有两个部分组成:发起端、同步源。负责发起rsync同步操作的客户机称为发起端;负责响应来自客户机的rsync同步操作的服务器称为同步源。在同步过程中,同步源负责提供文档的原始位置;发起端对该位置具有读取权限。

rsync拓扑图

未分类

rsync源服务器的部署

rsync下载地址下载地址https://rsync.samba.org/download.html

CentOS7系统非常友好的默认安装了rsync服务,如果你的系统没有安装rsync服务,那么用上面的链接下载安装即可,因为我这边默认安装了rsync,直接进行修改配置文件,配置文件默认在/etc/rsyncd.conf

  • 修改配置文件
vim /etc/rsyncd.conf
 uid = nobody    
 gid = nobody
 use chroot = yes             //禁锢在源目录
 address = 172.16.10.133      //监听地址
 port 873                     //监听端口
 log file = /var/log/rsyncd.log         //日志文件位置
 pid file = /var/run/rsyncd.pid         //进程ID存放位置
 hosts allow = 172.16.10.0/24           //允许访问的客户机地址

[wwwroot]                     //共享模块的名称
 path=/var/www/html           //源目录的实际路径
 comment=www.yun.com          //注解内容,可不填写
 read only= yes               //是否为只读
 dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2    //同步时不再进行压缩的文件类型
 auth users = backuper         //授权账户
 secrets file = /etc/rsyncd_users.db     //存放账户信息的数据文件
rsync远程同步及rsync+inotify实时同步

未分类

#这边解释一下,对于rsync的同步源最好仅允许以只读方式做同步。同步时也可以采用匿名的方式,只要将上面的auth users和secrets file配置记录加#注释或者删除就可以了。

为备份账户创建数据文件

vim /etc/rsyncd_users.db
backuper:abc123 //创建账户记录,以冒号分割
chmod 600 /etc/rsyncd_users.db

这边由于账户信息采用明文存放,因此上面调整了文件权限,避免账户信息泄露。

备份用户backuper需要对源目录/var/www/html具有相应的读取权限

未分类

  • 开启rsync服务进程
rsync --daemon

未分类

关闭服务的时候,直接采用kill $(cat /var/run/rsyncd.pid) 就可以了

rsync备份工具的使用

  • rsync命令的基本用法

rsync和大多数的备份程序一样,需要指定原始位置和目标位置,命令格式:rsync 源目录位置 目标位置

rsync /etc/fatab /opt

例如这条,意义就是:备份/etc/fstab目录到/opt目录下

命令格式及常用的备份选项

-r:递归模式,包含目录及子目录中的所有文件。
-l:对于符号链接文件仍然复制为符号链接文件。
-v:显示同步过程的详细信息。
-a:归档文件,保留文件的权限、属性等信息。
-z:在传输文件时进行压缩。
-p: 保留文件的权限标记。
-t:保留文件的时间标记。
-g:保留文件的属性标记(仅超级用户使用)。
-o:保留文件的属主标记(仅超级用户使用)。
-H:保留硬连接文件。
-A:保留ACL属性信息。
-D:保留设备文件及其他特殊文件。
--delete:删除目标位置有而原始位置没有的文件。
--checksum:根据校验和(而不是文件大小、修改时间)来决定是否跳过文件。
  • 配置源的表示方法

配置源的表示方法 三种
将对方源目录的文件同步到本地的/opt目录下

格式一:

rsync -avz [email protected]::wwwroot /opt/ 
password:abc123

格式二:

rsync -avz rsync://[email protected]/wwwroot /opt/
password:abc123

格式三:免密码交互

vim /etc/server.pass
abc123
chmod 600 /etc/server.pass
rsync -az --delete --password-file=/etc/server.pass [email protected]::wwwroot /opt
  • rsync备份操作示例
rsync -avz [email protected]::wwwroot /opt/

未分类

配置部署rsync+inotify实时同步

  • 调整inotify内核参数
vim /etc/sysctl.conf
fs.inotify.max_queued_events = 16384     #监控事件队列
fs.inotify.max_user_instances = 1024     #最多监控实例
fs.inotify.max_user_watches = 1048576    #每个实例最多监控文件数

sysctl -p     //刷新使之立即生效
fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 1024
fs.inotify.max_user_watches = 1048576
  • 安装inotify-tools

使用inotify机制需要安装inotify-tools,以便提供inotifywait和inotifywatch辅助工具程序,用来监控和汇总改动情况。

tar xf inotify-tools-3.14.tar.gz -C /opt/     //解压软件至/opt目录下
cd /opt/inotify-tools-3.14/
./configure                      //配置
make && make install          //编译安装

这里以监控网站目录/var/www/html为例,先执行inotifywait命令,然后在源服务器的终端上向/var/www/html目录下进行操作,这边发起端会监控输出结果。

inotifywait -mrp -e modify,create,move,delete /var/www/html

-e用来指定要监控的哪些事件,-m 表示持续监控,-r 表示递归整个目录, -q 简化输出信息。

未分类

  • 编写触发式同步脚本
vim /opt/inotify_rsync.sh

#!/bin/bash
INOTIFY_CMD="inotifywait -mrq -e modify,create,attrib,move,delete /var/www/html/"
RSYNC_CMD="rsync -vazH --delete --password-file=/etc/server.pass /var/www/html/ [email protected]::wwwroot/"
$INOTIFY_CMD | while read DIRECTORY EVENT FILE
do
    if [ $(pgrep rsync | wc -l) -le 5 ] ; then
        $RSYNC_CMD
    fi
done

chmod +x /opt/inotify_rsync.sh 
#添加执行权限

然后我们来看一下脚本执行的效果

未分类

未分类

未分类

未分类

未分类

至此实验结束,试验成功,rsync远程同步及rsync+inotify实时同步就成功了!!!各位看官上手试试吧!!!

inotify+rsync实战演练

试验目的:

演练rsync结合inotify实现服务端目录内文件有变动(包括修改,删除,创建)时,自动立即同步到客户端

试验环境:

centos6.5 192.168.10.89 —–角色:文件同步服务器.原始文件服务器.rsync客户端,inotify服务器
centos 6.5 192.168.10.103—–角色:文件同步客户端,由文件服务器自动向客户端同步

关于rsync和inotify介绍和具体用法.请参考其他笔记内容

实战步骤

一.在inotify服务器安装inotify-tools工具

下载链接https://sourceforge.net/projects/inotify-tools/?source=typ_redirect

安装过程简单:

tar zxvf inotify-tools-3.13.tar.gz
cd inotify-tools-3.13
./configure --prefix=/usr/local/inotify
make && make install 

vim /etc/profile
在结尾处加上:
export PATH=$PATH:/usr/local/inotify/bin

应用profile文件:
source /etc/profile

二.演示inotify使用方法:

执行命令:

inotifywait -rm --format '%Xe %w%f' -e modify,create,delete,attrib /tmp/data

命令输出:

[root@oracle inotify-tools-3.13]# inotifywait -rm --format '%Xe %w%f' -e modify,create,delete,attrib /tmp/data
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

解析:

inotifywait : 持续监控文件的状态变化

-r : 递归监控目录下的所有文件,包括子目录.

Note:如果要监控的目录中文件数量巨大,则通常需要修改/proc/sys/fs/inotify/max_users_watchs内核参数,因为其默认值为8192.

-m: 实现持续监控

–format 显示格式.

  • %X—-事件以”X”分隔.
  • %e—-显示事件(比如CREATE,MODIFY等),
  • %w—-显示文件名
  • %f—–显示目录
  • -e: 表示检测哪些事件

/tmp/data——-监测的目录路径

再开启一个终端,然后在/tmp/data目录下新建一些文件:

[root@localhost data]# touch {x,y,z,u,v,w}.txt
inotify输出如下:

检测到了文件变化.第一列是事件类型.有CREATE,ATTRIB. 第二列是文件的完整路径

[root@oracle inotify-tools-3.13]# inotifywait -rm –format ‘%Xe %w%f’ -e modify,create,delete,attrib /tmp/data
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
CREATE /tmp/data/x.txt
ATTRIB /tmp/data/x.txt
CREATE /tmp/data/y.txt
ATTRIB /tmp/data/y.txt
CREATE /tmp/data/z.txt
ATTRIB /tmp/data/z.txt
CREATE /tmp/data/u.txt
ATTRIB /tmp/data/u.txt
CREATE /tmp/data/v.txt
ATTRIB /tmp/data/v.txt
CREATE /tmp/data/w.txt
ATTRIB /tmp/data/w.txt


再试着删除所有文件:

[root@localhost data]# rm -rf {x,y,z,u,v,w}.txt
inotify检测到DELETE事件:

DELETE /tmp/data/x.txt
DELETE /tmp/data/y.txt
DELETE /tmp/data/z.txt
DELETE /tmp/data/u.txt
DELETE /tmp/data/v.txt
DELETE /tmp/data/w.txt

试试创建和删除目录检测到CREATE和DELETE的目录事件:

CREATEXISDIR /tmp/data/test

试试修改文件内容

[root@localhost data]# echo "haha" > 1.txt

检测到MODIFY事件:

CREATE /tmp/data/1.txt
MODIFY /tmp/data/1.txt

基本用法就介绍到这里.下面实战演练inotify+rsync结合做目录文件同步

在inotify编写脚本文件:

以下是工作在相对路径下

[root@localhost ~]# vim inotify_rsync.sh
#!/bin/bash
src=/tmp/data
des="/" #由于工作在相对路径下,会同步目录名.所以目的路径为/根
ip=192.168.10.103
user=root
cd $src #切换进工作目录
#inotify监测目录下文件是否有改动.主要监测:文件名或者目录修改,创建,删除,移动,文件内容修改.(这里我没有监测文件权限属性发送变化).
#将监测到的文件重定向到while循环.
inotifywait -mr --format '%Xe %w%f' -e modify,create,delete,close_write,move $src | while read file;do
   #获取Inotify的监测事件.有CREATE,MODIFY,DELETE等
   ino_event=$(echo $file | awk '{print $1}')
   #获取inotify监测到的变化文件
   ino_file=$(echo $file | awk '{print $2}')
   echo $file
   #if的正则匹配.如果ino_event变量的内容匹配CREATE开头.那么就条件为true.其实就等于 $ino_event == "CREATE*"
   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同步该文件的父目录到远程主机相关目录下.这里使用了ssh协议.需要提前复制本机公钥到目的主机
         echo $(dirname $ino_file)
         /usr/bin/rsync -avzR -e ssh $(dirname $ino_file) $user@$ip:$des
   elif [[ $ino_event =~ "DELETE" ]] || [[ $ino_event =~ "MOVED_FROM" ]];then
         echo "Delete or Moved_From"
        #如果是文件删除,或者移动到其他地方.则利用rsync删除远程主机上的该文件
        /usr/bin/rsync -avzR --delete $(dirname $ino_file) $user@$ip:$des
   fi
done
以下是工作在绝对路径下:

[root@localhost ~]# vim inotify_rsync.sh
#!/bin/bash
src=/tmp/data
des=/tmp  #由于会同步/tmp/data目录.所以目的路径只需要指定/tmp目录
ip=192.168.10.103
user=root
#inotify监测目录下文件是否有改动.主要监测:文件名或者目录修改,创建,删除,移动,文件内容修改.(这里我没有监测文件权限属性发送变化).
#将监测到的文件重定向到while循环.
inotifywait -mr --format '%Xe %w%f' -e modify,create,delete,close_write,move $src | while read file;do
   #获取Inotify的监测事件.有CREATE,MODIFY,DELETE等
   ino_event=$(echo $file | awk '{print $1}')
   #获取inotify监测到的变化文件
   ino_file=$(echo $file | awk '{print $2}')
   echo $file
   #if的正则匹配.如果ino_event变量的内容匹配CREATE开头.那么就条件为true.其实就等于 $ino_event == "CREATE*"
   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同步该文件的父目录到远程主机相关目录下.这里使用了ssh协议.需要提前复制本机公钥到目的主机
         /usr/bin/rsync -avz -e ssh $ino_file $user@$ip:$des
   elif [[ $ino_event =~ "DELETE" ]] || [[ $ino_event =~ "MOVED_FROM" ]];then
         echo "Delete or Moved_From"
        #如果是文件删除,或者移动到其他地方.则利用rsync删除远程主机上的该文件
        /usr/bin/rsync -avz --delete $ino_file $user@$ip:$des
   fi
done

Note:此脚本中的rsync使用的是ssh协议传输.而不是守护模式.所以需要实现传输本地的公钥到远程主机相关用户下

运行脚本:

[root@localhost ~]# ./inotify_rsync.sh

在/tmp/data目录内创建文件:

[root@localhost data]# touch {1,2,3,4,5,6}.txt

脚本输出:

[root@oracle ~]# ./inotify_rsync.sh
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
CLOSE_WRITEXCLOSE /tmp/data/1.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list
/tmp/
/tmp/data/
/tmp/data/1.txt
/tmp/data/2.txt
/tmp/data/3.txt
/tmp/data/4.txt
/tmp/data/5.txt
/tmp/data/6.txt
/tmp/data/test/

sent 388 bytes  received 138 bytes  350.67 bytes/sec
total size is 5  speedup is 0.01
CREATE /tmp/data/2.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  338.00 bytes/sec
total size is 5  speedup is 0.03
CLOSE_WRITEXCLOSE /tmp/data/2.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  338.00 bytes/sec
total size is 5  speedup is 0.03
CREATE /tmp/data/3.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  112.67 bytes/sec
total size is 5  speedup is 0.03
CLOSE_WRITEXCLOSE /tmp/data/3.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  338.00 bytes/sec
total size is 5  speedup is 0.03
CREATE /tmp/data/4.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  112.67 bytes/sec
total size is 5  speedup is 0.03
CLOSE_WRITEXCLOSE /tmp/data/4.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  338.00 bytes/sec
total size is 5  speedup is 0.03
CREATE /tmp/data/5.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  338.00 bytes/sec
total size is 5  speedup is 0.03
CLOSE_WRITEXCLOSE /tmp/data/5.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  112.67 bytes/sec
total size is 5  speedup is 0.03
CREATE /tmp/data/6.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  338.00 bytes/sec
total size is 5  speedup is 0.03
CLOSE_WRITEXCLOSE /tmp/data/6.txt
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 154 bytes  received 15 bytes  338.00 bytes/sec
total size is 5  speedup is 0.03

在172.16.1.120客户端的/tmp/data目录下查看文件: 文件已成功复制:

[root@www ~]$ll /tmp/data
total 8
-rw-r--r--. 1 root root    5 Jun 24 13:27 1.txt
-rw-r--r--. 1 root root    0 Jun 24 13:27 2.txt
-rw-r--r--. 1 root root    0 Jun 24 13:27 3.txt
-rw-r--r--. 1 root root    0 Jun 24 13:27 4.txt
-rw-r--r--. 1 root root    0 Jun 24 13:27 5.txt
-rw-r--r--. 1 root root    0 Jun 24 13:27 6.txt

演示在Inotify服务上删除刚创建的文件: 监测到文件删除

[root@oracle ~]# ./inotify_rsync.sh
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
DELETE /tmp/data/1.txt
Delete or Moved_From
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list
/tmp/data/
deleting tmp/data/6.txt
deleting tmp/data/5.txt
deleting tmp/data/4.txt
deleting tmp/data/3.txt
deleting tmp/data/2.txt
deleting tmp/data/1.txt

sent 87 bytes  received 18 bytes  70.00 bytes/sec
total size is 0  speedup is 0.00
DELETE /tmp/data/2.txt
Delete or Moved_From
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 84 bytes  received 15 bytes  198.00 bytes/sec
total size is 0  speedup is 0.00
DELETE /tmp/data/3.txt
Delete or Moved_From
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 84 bytes  received 15 bytes  66.00 bytes/sec
total size is 0  speedup is 0.00
DELETE /tmp/data/4.txt
Delete or Moved_From
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 84 bytes  received 15 bytes  198.00 bytes/sec
total size is 0  speedup is 0.00
DELETE /tmp/data/5.txt
Delete or Moved_From
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 84 bytes  received 15 bytes  198.00 bytes/sec
total size is 0  speedup is 0.00
DELETE /tmp/data/6.txt
Delete or Moved_From
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list

sent 84 bytes  received 15 bytes  66.00 bytes/sec
total size is 0  speedup is 0.00

在172.16.1.120服务器上查看/tmp/data目录.下面没有任何文件

[root@www ~]$ll /tmp/data
total 4
drwxr-xr-x. 2 root root 4096 Jun 24 13:17 test

演示:新建一个目录.且在该目录下创建内容 脚本输出:

CREATEXISDIR /tmp/data/haha
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
/tmp/data
Nasty PTR record "172.16.1.120" is set up for 172.16.1.120, ignoring
sending incremental file list
/tmp/data/
/tmp/data/haha/

sent 100 bytes  received 22 bytes  244.00 bytes/sec
total size is 0  speedup is 0.00

目录已经被同步

[root@www ~]$ll /tmp/data
total 8
drwxr-xr-x. 2 root root 4096 Jun 24 13:33 haha
drwxr-xr-x. 2 root root 4096 Jun 24 13:17 test

rsync+inotify实现实时同步acgred.cn

一、无差异同步数据

1.首先,在实践实时同步之前我们先来了解一下rsync无差异同步
无差异推送数据加–delete

1)备份 –delete风险
本地有,远端就有。本地没有远端有也会删除,服务器端的目录数据可能会丢失

无差异拉取数据 www.gaimor.cn

2)代码发布、下载 –delete风险
远端有,本地就有。远端没有的本地有也会删除,本地的目录数据可能丢失

未分类

ps:上图会将远程端的/hzftp/test里的文件完全克隆到客户端的/data1目录中


多模块共享配置,只需新增模块目录地址即可,其他 www.acgred.cn


inotify实施(切记在客户端上安装)

前提:需要rsync daemon已经搭建完成的情况下,可以在服务端上推拉数据
inotifu安装:
检查服务端的rsync服务是正常启用的,并且可以在客户端往服务端推送文件
检查内核版本:uname -r

[root@localhost inotify]# ls 
max_queued_events  max_user_instances  max_user_watches
[root@localhost inotify]# ll /proc/sys/fs/inotify
总用量 0
-rw-r--r--. 1 root root 0 6月  27 22:58 max_queued_events   
-rw-r--r--. 1 root root 0 6月  27 22:58 max_user_instances  
-rw-r--r--. 1 root root 0 6月  27 22:58 max_user_watches

然后从互联网上下载inotify源码安装包
下载好后,解压:tar xf inotify-tools-3.14.tar.gz

cd inotify-tools-3.14
./configure --prefix=/usr/local/inotify-tools-3.14
make && make install
ln -s /usr/local/inotify-tools-3.14 /usr/local/inotify
[root@localhost inotify]# ll /usr/local/inotify
总用量 4
drwxr-xr-x. 2 root root   43 6月  27 23:10 bin  #inotify执行命令
drwxr-xr-x. 3 root root   25 6月  27 23:10 include  #inotify所需头文件
drwxr-xr-x. 2 root root 4096 6月  27 23:10 lib  #动态链接库文件
drwxr-xr-x. 4 root root   26 6月  27 23:10 share   #帮助文档

使用inotify来监控目录文件,当被监控的目录发生变化会产生输出:
监听创建:create
监听删除:delete
监听写入:close_write
ps:当create和close_write同时使用时,创建文件会被监控两遍
======create,delete,close_write同时使用用逗号隔开=======
/usr/local/inotify-tools-3.14/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T %w%f' -e create /backup

未分类

开发inotify数据同步脚本
创建脚本存放路径:mkdir -p /server/scripts
进入脚本存放目录:cd /server/scripts

rsync+inotify实现实时同步案例

公司网站因负载过高不得不搞个负载均衡,那么问题来了,每次更新网站,负载均衡下的服务器全部需要更新,当数据量过大的时候会很麻烦,并切效率低下,当时考虑到用rsync去实时同步,写个计划任务,但更新数据很频繁,并且rsync不能实时的去监测、同步数据,虽然它可以通过linux守护进程的方式进行触发同步,但是两次触发动作一定会有时间差,这样就导致了服务端和客户端数据可能出现不一致,无法在应用故障时完全的恢复数据。基于以上原因,rsync+inotify出现了!

inotify介绍

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

rsync+inotify同步逻辑图
未分类

环境部署

主机名                主机IP地址            系统版本                系统内核版本
inotify-master    192.168.1.1    CentOS release 6.4 (Final)    2.6.32-358.el6.x86_64
inotify-slave    192.168.1.2    CentOS release 6.4 (Final)    2.6.32-358.el6.x86_64

inotify-slave部署

部署rsync服务,rsync daemon工作模式。

检查是否安装rsync

[root@inotify-slave ~]# rpm -aq rsync
rsync-3.0.6-9.el6.x86_64

新建rsync用户及模块目录并更改其用户组

[root@inotify-slave mail]# useradd rsync -s /sbin/nologin  -M #添加rsync用户
[root@inotify-slave mail]# grep rsync /etc/passwd
rsync:x:2004:2004::/home/rsync:/sbin/nologin
[root@inotify-slave mail]# mkdir /backup   #创建rsync daemon工作模式的模块目录
[root@inotify-slave mail]# ll -d /backup/
drwxr-xr-x. 2 root root 4096 4月  22 14:13 /backup/
[root@inotify-slave mail]# chown rsync.rsync /backup/   #更改模块目录的用户组
[root@inotify-slave mail]# ll -d /backup/
drwxr-xr-x. 2 rsync rsync 4096 4月  22 14:13 /backup/

编写rsync daemon配置文件/etc/rsyncd.conf

[root@inotify-slave /]# cat /etc/rsyncd.conf
##rsyncd.conf start##
#工作中指定用户(需要指定用户)
uid = rsync
gid = rsync
#相当于黑洞.出错定位
use chroot = no
#有多少个客户端同时传文件
max connections = 200
#超时时间
timeout = 300
#进程号文件
pid file = /var/run/rsyncd.pid
#日志文件
lock file = /var/run/rsync.lock
#日志文件
log file = /var/log/rsyncd.log
#模块开始
#这个模块对应的是推送目录
#模块名称随便起
[backup]
#需要同步的目录
path = /backup/
#表示出现错误忽略错误
ignore errors
#表示网络权限可写(本地控制真正可写)
read only = false
#这里设置IP或让不让同步
list = false
#指定允许的网段
hosts allow = 192.168.1.0/24
#拒绝链接的地址,一下表示没有拒绝的链接。
hosts deny = 0.0.0.0/32
#不要动的东西(默认情况)
#虚拟用户
auth users = rsync_backup
#虚拟用户的密码文件
secrets file = /etc/rsync.password
#配置文件的结尾
#rsync_config_______________end

配置虚拟用户的密码文件

[root@inotify-slave /]# echo "rsync_backup:leesir" >/etc/rsync.password
[root@inotify-slave /]# cat /etc/rsync.password
rsync_backup:leesir   #注:rsync_backup为虚拟用户,leesir为这个虚拟用户的密码
[root@inotify-slave /]# chmod 600 /etc/rsync.password #为密码文件提权,增加安全性
[root@inotify-slave /]# ll /etc/rsync.password
-rw-------. 1 root root 20 4月  22 14:20 /etc/rsync.password

启动rsync 服务

[root@inotify-slave /]# rsync --daemon   #启动rsync服务
[root@inotify-slave /]# ps -ef |grep rsync
root     14871     1  0 14:24 ?        00:00:00 rsync --daemon
root     14873 14788  0 14:24 pts/0    00:00:00 grep rsync
[root@inotify-slave /]# netstat -lnutp |grep rsync
tcp        0      0 0.0.0.0:873                 0.0.0.0:*                   LISTEN      14871/rsync
tcp        0      0 :::873                      :::*                        LISTEN          14871/rsync

通过inotify-master测试推送

inotify-master配置密码文件,测试推送
[root@inotify-master ~]# echo "leesir" >/etc/rsync.password
[root@inotify-master ~]# cat /etc/rsync.password
leesir   #注意:这里只要写密码即可,切记。
[root@inotify-master ~]# chmod 600 /etc/rsync.password
[root@inotify-master ~]# ll /etc/rsync.password
-rw------- 1 root root 7 4月  22 14:32 /etc/rsync.password
[root@inotify-master ~]# echo "hello leesir">test.txt
[root@inotify-master ~]# cat test.txt
hello leesir
[root@inotify-master ~]# rsync -avz test.txt [email protected]::backup --password-file=/etc/rsync.password
sending incremental file list
test.txt
sent 82 bytes  received 27 bytes  72.67 bytes/sec
total size is 13  speedup is 0.12
inotify-slave检查:
[root@inotify-slave /]# ll /backup/
总用量 4
-rw-r--r--. 1 rsync rsync 13 4月  22 14:34 test.txt
[root@inotify-slave /]# cat /backup/test.txt
hello leesir

inotify-master部署

注: inotify是rsync客户端安装和执行的 企业场景压力测试200-300个同步限制,受网卡,磁盘,带宽等的制约。

查看当前系统是否支持inotify

[root@inotify-master ~]# ll /proc/sys/fs/inotify/
总用量 0
-rw-r--r-- 1 root root 0 4月  22 14:56 max_queued_events
-rw-r--r-- 1 root root 0 4月  22 14:56 max_user_instances
-rw-r--r-- 1 root root 0 4月  22 14:56 max_user_watches
#显示这三个文件则证明支持。

拓展:

/proc/sys/fs/inotify/max_queued_evnets      
表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。
/proc/sys/fs/inotify/max_user_instances 
表示每一个real user ID可创建的inotify instatnces的数量上限。
/proc/sys/fs/inotify/max_user_watches 
表示每个inotify instatnces可监控的最大目录数量。如果监控的文件数目巨大,需要根据情况,适当增加此值的大小。
例如: echo 30000000 > /proc/sys/fs/inotify/max_user_watches

下载inotify源码包并编译安装

root@inotify-master tools]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz  #下载inotify源码包
..................................
root@inotify-master tools]# ll inotify-tools-3.14.tar.gz
-rw-r--r-- 1 root root 358772 3月  14 2010 inotify-tools-3.14.tar.gz
[root@inotify-master tools]# tar zxf inotify-tools-3.14.tar.gz
[root@inotify-master tools]# cd inotify-tools-3.14
[root@inotify-master inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify-3.14 #配置inotify,并指定安装路径为/usr/local/inotify-3.14
................................
[root@inotify-master inotify-tools-3.14]# make && make install
................................

inotify之inotifywait命令常用参数详解

[root@inotify-master inotify-tools-3.14]# cd /usr/local/inotify-3.14/
[root@inotify-master inotify-3.14]# ./bin/inotifywait --help
-r|--recursive   Watch directories recursively. #递归查询目录
-q|--quiet      Print less (only print events). #打印监控事件的信息
-m|--monitor   Keep listening for events forever.  Without this option, inotifywait will exit after one  event is received.        #始终保持事件监听状态
--excludei <pattern>  Like --exclude but case insensitive.    #排除文件或目录时,不区分大小写。
--timefmt <fmt> strftime-compatible format string for use with %T in --format string. #指定时间输出的格式
--format <fmt>  Print using a specified printf-like format string; read the man page for more details.
#打印使用指定的输出类似格式字符串
-e|--event <event1> [ -e|--event <event2> ... ] Listen for specific event(s).  If omitted, all events are  listened for.   #通过此参数可以指定需要监控的事件,如下所示:
Events:
access           file or directory contents were read       #文件或目录被读取。
modify           file or directory contents were written    #文件或目录内容被修改。
attrib            file or directory attributes changed      #文件或目录属性被改变。
close            file or directory closed, regardless of read/write mode    #文件或目录封闭,无论读/写模式。
open            file or directory opened                    #文件或目录被打开。
moved_to        file or directory moved to watched directory    #文件或目录被移动至另外一个目录。
move            file or directory moved to or from watched directory    #文件或目录被移动另一个目录或从另一个目录移动至当前目录。
create           file or directory created within watched directory     #文件或目录被创建在当前目录
delete           file or directory deleted within watched directory     #文件或目录被删除
unmount         file system containing file or directory unmounted  #文件系统被卸载

编写监控脚本并加载到后台执行

[root@inotify-master scripts]# cat inotify.sh
#!/bin/bash
#para
host01=192.168.1.160  #inotify-slave的ip地址
src=/backup/        #本地监控的目录
dst=backup         #inotify-slave的rsync服务的模块名
user=rsync_backup      #inotify-slave的rsync服务的虚拟用户
rsync_passfile=/etc/rsync.password   #本地调用rsync服务的密码文件
inotify_home=/usr/local/inotify-3.14    #inotify的安装目录
#judge
if [ ! -e "$src" ] 
|| [ ! -e "${rsync_passfile}" ] 
|| [ ! -e "${inotify_home}/bin/inotifywait" ] 
|| [ ! -e "/usr/bin/rsync" ];
then
echo "Check File and Folder"
exit 9
fi
${inotify_home}/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write,delete,create,attrib $src 
| while read file
do
#  rsync -avzP --delete --timeout=100 --password-file=${rsync_passfile} $src $user@$host01::$dst >/dev/null 2>&1
cd $src && rsync -aruz -R --delete ./  --timeout=100 $user@$host01::$dst --password-file=${rsync_passfile} >/dev/null 2>&1
done
exit 0
[root@inotify-master scripts]# sh inotify.sh &  #将脚本加入后台执行
[1] 13438
[root@inotify-master scripts]#

实时同步测试

inotify-master操作:

[root@inotify-master scripts]# cd /backup/
[root@inotify-master backup]# ll
总用量 0
[root@inotify-master backup]# for a in `seq 200`;do touch $a;done  #创建200个文件
[root@inotify-master backup]# ll  --time-style=full-iso
总用量 0
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.141497569 +0800 1
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.172497529 +0800 10
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.235497529 +0800 100
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.236497529 +0800 101
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.237497529 +0800 102
...................................

inotify-slave检查

[root@inotify-slave backup]# ll  --time-style=full-iso
总用量 0
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 1
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 10
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 100
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 101
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 102
..........................

通过rsync+inotify实现服务器之间数据的实时备份

前言

背景:有A、B两台服务器,A为生产服务器,B为备份服务器
需求:A服务器上的目录/home/chancel一有修改,实时同步到备份服务器B上的/home/chancel_backup/目录

rsync+inotify介绍

rsync介绍

rsync是类unix系统下的数据镜像备份工具——remote sync。一款快速增量备份工具 Remote Sync,远程同步 支持本地复制,或者与其他SSH、rsync主机同步。(来自百度百科)

inotify介绍

Inotify 是一个 Linux特性,它监控文件系统操作,比如读取、写入和创建。Inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多。学习如何将 inotify 集成到您的应用程序中,并发现一组可用来进一步自动化系统治理的命令行工具。(来自百度百科)

示例图

未分类

实现

B服务器部署

  • 安装rsync
yum -y install rsync
  • 编辑/etc/rsyncd.conf文件,下面为参考示例
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:
 uid = nobody
 gid = nobody
 use chroot = no
 max connections = 10
 strict modes = no
 # pid文件,如无法再次启动可删除
 pid file = /var/run/rsyncd.pid
 lock file = /var/run/rsyncd.lock
 log file = /var/run/rsyncd.log
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
# [ftp]
#        path = /home/ftp
#        comment = ftp export area
[betterlife]
# 本地存放的目录
path = /home/chancel
comment = betterlife file
ignore errors
read only = no
write only = no
hosts allow = *
list = false
# 可自定义
uid = root
gid = root
auth users = backup
# 密码文件,内容为“账户:密码”
secrets file = /etc/server.pass
  • 增加/etc/server.pass文件,内容如下
backup:密码
  • 修改/etc/server.pass权限
chmod 600 /etc/server.pass
  • 启动rsync守护进程,并将其写入开机项中
rsync --daemonecho "rsync --daemon" >>/etc/rc.local

备份服务器设置到此完毕

A服务器部署

  • 安装rsync和inotify-tools
yum -y install rsyncyum install inotify-tools
  • 如果inotify-tools无法通过yum安装(已安装跳过此步骤),可从github下载自行编译安装,下面给出参考
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz 
tar -zxf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
# 配置inotify,并指定安装路径为/usr/local/inotify-3.14
./configure --prefix=/usr/local/inotify-tools-3.14 
make && make install
# 将inotify加入系统环境
vim /etc/profile
# 添加入如下语句
export PATH=$PATH:/usr/local/inotify-tools-3.14/bin
# 保存并退出,使环境生效
source /etc/profile
  • 创建/etc/server.pass文件,内容如下
密码
  • 修改脚本文件权限
chmod 755 /var/www/inotifyrsync.sh
  • 测试是否能够通过rsync同步文件(注意防火墙、模块名称一致、账户密码一致、密码文件读取权限设置)
rsync -vzrtopg --delete --progress --password-file=/etc/server.pass /home/chancel   [email protected]::betterlife
  • 如测试不通过,通过返回错误信息排错,注意模块名称,账户密码,权限问题,防火墙问题,测试如通过,则创建backup脚本
# 创建backup脚本并命名为backup.shvim /home/backup.sh# 写入脚本#!/bin/bashinotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,delete,create,attrib 监测目录 | while read files        do        rsync -vzrtopg --delete --progress --password-file=/etc/server.pass 同步文件目录   backup@服务器地址::模块名                echo "${files} was rsynced" >>/tmp/rsync.log 2>&1        done
  • 后台运行该脚本,并加入启动项
./backup.sh >>/var/www/backup.log &echo "./backup.sh >>/var/www/backup.log &" >>/etc/rc.local

inotify+rsync实现数据实时同步

第1章 数据实时同步介绍

1.1 什么是实时同步:如何实现实时同步

A. 要利用监控服务(inotify),监控同步数据服务器目录中信息的变化

B. 发现目录中数据产生变化,就利用rsync服务推送到备份服务器上

1.2 实现实时同步的方法

inotify+rsync 方式实现数据同步

sersync 方式实现实时数据同步

1.2.1 实时同步原理介绍

未分类

1.3 inotify+rsync 方式实现数据同步

1.3.1 Inotify简介

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

提示信息:

sersync软件实际上就是在 inotify软件基础上进行开发的,功能要更加强大些 ,多了定时重传机制,过滤机制了提供接口做 CDN,支持多线程橾作。

Inotify实际是一种事件驱动机制,它为应用程序监控文件系统事件提供了实时响应事件的机制,而无须通过诸如cron等的轮询机制来获取事件。cron等机制不仅无法做到实时性,而且消耗大量系统资源。相比之下,inotify基于事件驱动,可以做到对事件处理的实时响应,也没有轮询造成的系统资源消耗,是非常自然的事件通知接口,也与自然世界事件机制相符合。

inotify的实现有几款软件:

inotify-tools,sersync,lrsyncd

1.3.2 inotify+rsync使用方式

inotify 对同步数据目录信息的监控

rsync 完成对数据信息的实时同步

利用脚本进行结合

1.4 部署inotify软件的前提

需要2.6.13以后内核版本才能支持inotify软件。2.6.13内核之后版本,在没有安装inotify软件之前,应该有这三个文件。

[root@backup ~]# ll /proc/sys/fs/inotify/

total 0

-rw-r--r-- 1 root root 0 Oct 17 10:12 max_queued_events

-rw-r--r-- 1 root root 0 Oct 17 10:12 max_user_instances

-rw-r--r-- 1 root root 0 Oct 17 10:12 max_user_watches

1.4.1 三个重要文件的说明

未分类

1.4.2 【服务优化】可以将三个文件的数值调大,监听更大的范围

1.4.3 【官方说明】三个重要文件

[root@nfs01 ~]# man proc

/proc/sys/fs/inotify (since Linux 2.6.13)

      This  directory  contains    files    max_queued_events,

      max_user_instances, and max_user_watches, that can be used

      to limit the amount of kernel memory consumed by the  inotify interface. 

for further details, see inotify(7).

通过man手册的第7级别中查到 inotify的默认文件的详细说明。

[root@nfs01 ~]# man 7 inotify

/proc/sys/fs/inotify/max_queued_events

      The  value  in this file is used when an application calls

      inotify_init(2) to set an upper limit  on  the  number  of

      events  that  can  be  queued to the corresponding inotify

      instance.  Events in excess of this limit are dropped, but

      an IN_Q_OVERFLOW event is always generated.



/proc/sys/fs/inotify/max_user_instances

      This  specifies  an  upper  limit on the number of inotify

      instances that can be created per real user ID.



/proc/sys/fs/inotify/max_user_watches

      This specifies an upper limit on  the  number  of  watches

      that can be created per real user ID.

1.5 inotify软件介绍及参数说明

1.5.1 两种安装方式

1) yum install -y inotify-tools

2) 手工编译安装

注:

YUM 安装需要有epel源

http://mirrors.aliyun.com

手工编译安装方式需要到github上进行下载软件包

inotify软件的参考资料链接:

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

1.5.2 inotify主要安装的两个软件

inotifywait: (主要)

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

inotifywatch:

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

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

1.5.3 inotifywait命令参数说明

未分类

1.5.4 -e[参数] 可以指定的事件类型

未分类

1.5.4.1 【实例】inotifywait监控中的事件测试

1、创建事件

[root@nfs01 data]# touch test2.txt

[root@nfs01 ~]# inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e create

17-10-17 11:19 /data/test2.txt 事件信息: CREATE

2、删除事件

[root@nfs01 data]# rm -f test1.txt

[root@nfs01 ~]# inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e delete

17-10-17 11:28 /data/test1.txt 事件信息: DELETE

3、修改事件

[root@nfs01 data]# echo "132" > test.txt

[root@nfs01 ~]# inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e close_write

17-10-17 11:30 /data/test.txt 事件信息: CLOSE_WRITE,CLOSE

4、移动事件 moved_to

[root@nfs01 data]# mv /etc/hosts .

[root@nfs01 ~]# inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e moved_to

17-10-17 11:33 /data/hosts 事件信息: MOVED_TO

移动事件 moved_from

[root@nfs01 data]# mv ./hosts  /tmp/

[root@nfs01 ~]# inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e moved_from

17-10-17 11:34 /data/hosts 事件信息: MOVED_FROM

1.5.5 inotifywait 参数 –format 格式定义参数

未分类

1.5.6 inotifywait 参数–timefmt 时间格式参数

未分类

1.5.6.1 修改输出的日期格式

[root@nfs01 ~]# inotifywait -mrq  /data --timefmt "%d/%m/%y %H:%M" --format "%T %w%f"

17/10/17 11:12 /data/test1.txt

1.5.7 -e[参数] 重要监控事件参数汇总表:

未分类

1.6 对inotifywait命令的测试

对inotifywait命令测试的说明:

需要打开两个连接窗口

  • 窗口运行inotifywait

  • 窗口对文件夹进行操作,可在一窗口中查看出inotifywait的监控记录

1.6.1 创建文件的逻辑↓

[root@nfs01 ~]# inotifywait /data

Setting up watches.

Watches established.

/data/ CREATE test1.txt

/data/ OPEN test1.txt

/data/ ATTRIB test1.txt

/data/ CLOSE_WRITE,CLOSE test1.txt

创建文件,inotifywait显示创建文件的过程↑

[root@nfs01 data]# touch test1.txt

1.6.2 创建目录逻辑↓

[root@nfs01 data]# mkdir testdir

[root@nfs01 ~]#

/data/ CREATE,ISDIR testdir

1.6.3 监控子目录下的文件↓

[root@nfs01 data]# touch  testdir/test01.txt

[root@nfs01 ~]# inotifywait -mrq  /data

/data/testdir/ OPEN test01.txt

/data/testdir/ ATTRIB test01.txt

/data/testdir/ CLOSE_WRITE,CLOSE test01.txt

1.6.4 sed命令修改逻辑

[root@nfs01 data]# sed 's#132#123#g' test.txt -i



[root@nfs01 ~]# inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e moved_from

 /data/test.txt 事件信息: OPEN

 /data/sedDh5R8v 事件信息: CREATE

 /data/sedDh5R8v 事件信息: OPEN

 /data/test.txt 事件信息: ACCESS

 /data/sedDh5R8v 事件信息: MODIFY

 /data/sedDh5R8v 事件信息: ATTRIB

 /data/sedDh5R8v 事件信息: ATTRIB

 /data/test.txt 事件信息: CLOSE_NOWRITE,CLOSE

 /data/sedDh5R8v 事件信息: CLOSE_WRITE,CLOSE

 /data/sedDh5R8v 事件信息: MOVED_FROM

 /data/test.txt 事件信息: MOVED_TO

sed命令替换逻辑 :

  • 创建临时文件

  • 将原文件内容放置到临时文件中,修改替换临时文件中的内容,原有文件不做改动

  • 重命名临时文件,覆盖原文件

1.6.5 inotifywait监控中 -e 的参数使用

inotifywait -mrq /data --timefmt "%d/%m/%y %H:%M" --format "%T %w%f 事件信息: %e" -e create

说明:表示只监听create事件

inotifywait -mrq /data --timefmt "%d/%m/%y %H:%M" --format "%T %w%f 事件信息: %e"

说明:不指定-e参数,表示监听所有事件

  • 删除事件delete
    # inotifywait -mrq /data --timefmt "%F %H:%M" --format "%T %w%f 事件信息: %@e" -e delete

    2017-10-17 11:28 /data/02.txt 事件信息: DELETE

    2017-10-17 11:28 /data/03.txt 事件信息: DELETE

    2017-10-17 11:28 /data/04.txt 事件信息: DELETE
  • 修改事件close_write
    # inotifywait -mrq /data --timefmt "%F %H:%M" --format "%T %w%f 事件信息: %@e" -e delete,close_write

    2017-10-17 11:30 /data/oldgirl.txt 事件信息: CLOSE_WRITE@CLOSE

    2017-10-17 11:30 /data/.oldgirl.txt.swx 事件信息: CLOSE_WRITE@CLOSE

    2017-10-17 11:30 /data/.oldgirl.txt.swx 事件信息: DELETE

    2017-10-17 11:30 /data/.oldgirl.txt.swp 事件信息: CLOSE_WRITE@CLOSE

    2017-10-17 11:30 /data/.oldgirl.txt.swp 事件信息: DELETE

    2017-10-17 11:30 /data/.oldgirl.txt.swp 事件信息: CLOSE_WRITE@CLOSE

    2017-10-17 11:30 /data/.oldgirl.txt.swp 事件信息: DELETE
  • 移动事件moved_to
    inotifywait -mrq /data --timefmt "%F %H:%M" --format "%T %w%f 事件信息: %@e" -e delete,close_write,moved_to

    2017-10-17 11:34 /data/hosts 事件信息: MOVED_TO

1.7 实时同步命令参数示意图

未分类

第2章 inotify+rsync实时同步服务部署

2.1 第一个里程碑:部署rsync服务

2.1.1 rsync服务端部署

1)软件是否存在

[root@backup ~]# rpm -qa |grep rsync

rsync-3.0.6-12.el6.x86_64

需求:查询到某个命令非常有用。但是不知道属于哪个软件包

    yum  provides  rysnc

    provides  Find what package provides the given value

2)进行软件服务配置

[root@backup ~]# vim /etc/rsyncd.conf

uid = rsync

gid = rsync

use chroot = no

max connections = 200

timeout = 300

pid file = /var/run/rsyncd.pid

lock file = /var/run/rsync.lock

log file = /var/log/rsyncd.log

ignore errors

read only = false

list = false

hosts allow = 172.16.1.0/24

auth users = rsync_backup

secrets file = /etc/rsync.password

[backup]

comment = "backup dir by oldboy"

path = /backup

[nfsbackup]

comment = "nfsbackup dir by hzs"

path = /nfsbackup

3)创建rsync管理用户

[root@backup ~]# useradd -s /sbin/nologin -M rsync

4)创建数据备份储存目录,目录修改属主

[root@backup ~]# mkdir /nfsbackup/

[root@backup ~]# chown -R rsync.rsync /nfsbackup/

5)创建认证用户密码文件并进行授权600

echo "rsync_backup:oldboy123" >>/etc/rsync.password

chmod 600 /etc/rsync.password

6)启动rsync服务

rsync --daemon

至此服务端配置完成

[root@backup ~]# ps -ef |grep rsync

root      2076      1  0 17:05 ?        00:00:00 rsync --daemon

root      2163  1817  0 17:38 pts/1    00:00:00 grep --color=auto rsync

2.1.2 rsync客户端配置

1)软件是否存在

[root@backup ~]# rpm -qa |grep rsync

rsync-3.0.6-12.el6.x86_64

2)创建安全认证文件,并进行修改权限600

echo "oldboy123" >>/etc/rsync.password

chmod 600 /etc/rsync.password

3) 测试数据传输

[root@nfs01 sersync]# rsync -avz /data  [email protected]::nfsbackup  --password-file=/etc/rsync.password

sending incremental file list

data/

data/.hzs

data/.tar.gz

data/.txt

2.2 第二个里程碑:部署inotify服务

首先先确认是否有epel源用来安装inotify-tools软件

[root@nfs01 ~]# yum repolist

Loaded plugins: fastestmirror, security

Loading mirror speeds from cached hostfile

 * base: mirrors.aliyun.com

 * epel: mirrors.aliyun.com

 * extras: mirrors.aliyun.com

 * updates: mirrors.aliyun.com

repo id  repo name                                      status

base    CentOS-6 - Base - mirrors.aliyun.com            6,706

epel    Extra Packages for Enterprise Linux 6 - x86_64  12,401

extras  CentOS-6 - Extras - mirrors.aliyun.com              46

updates  CentOS-6 - Updates - mirrors.aliyun.com            722

repolist: 19,875

2.2.1 安装inotify软件

两种安装方式

1) yum install -y inotify-tools

2) 手工编译安装

注:

手工编译安装方式需要到github上进行下载软件包

inotify软件的参考资料链接:

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

2.2.2 查看inotify安装上的两个命令(inotifywait,inotifywatch)

[root@nfs01 ~]# rpm -ql inotify-tools

/usr/bin/inotifywait      #主要

/usr/bin/inotifywatch

2.2.2.1 inotifywait和inotifywatch的作用:

一共安装了2个工具(命令),即inotifywait和inotifywatch

inotifywait : 在被监控的文件或目录上等待特定文件系统事件(open close delete等)发生,

执行后处于阻塞状态,适合在shell脚本中使用

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

说明:yum安装后可以直接使用,如果编译安装需要进入到相应软件目录的bin目录下使用

#命令 man手册说明

# man inotifywait

inotifywait - wait for changes to files using inotify

使用inotify进行监控,等待产生变化的文件信息

# man inotifywatch

inotifywatch - gather filesystem access statistics using inotify

使用inotify进行监控,收集文件系统访问统计佶息

2.3 第三个里程碑:编写脚本,实现rsync+inotify软件功能结合

2.3.1 rsync服务命令

rsync -avz --delete /data/ [email protected]::nfsbackup --password-file=/etc/rsync.password

2.3.2 inotify服务命令:

inotifywait -mrq /data -format "%w%f"  -e create,delete,move_to,close_write

2.3.3 编写脚本

[root@nfs01 sersync]# vim /server/scripts/inotify.sh
#!/bin/bash
inotifywait -mrq /data --format "%w%f" -e create,delete,moved_to,close_write|
while read line
do
        rsync -az --delete /data/ [email protected]::nfsbackup --password-
file=/etc/rsync.password
done

脚本说明:

for循环会定义一个条件,当条件不满足时停止循环

while循环:只要条件满足就一直循环下去

2.3.4 对脚本进行优化

#!/bin/bash

Path=/data
backup_Server=172.16.1.41


/usr/bin/inotifywait -mrq --format '%w%f' -e create,close_write,delete /data  | while read line  
do
    if [ -f $line ];then
        rsync -az $line --delete rsync_backup@$backup_Server::nfsbackup --password-file=/etc/rsync.password
    else
        cd $Path &&
        rsync -az ./ --delete rsync_backup@$backup_Server::nfsbackup --password-file=/etc/rsync.password
    fi

done

2.4 第四个里程碑:测试编写的脚本

2.4.1 让脚本在后台运行

在/data 目录先创建6个文件

[root@nfs01 data]# sh  /server/scripts/inotify.sh &

[root@nfs01 data]# touch {1..6}.txt

在backup服务器上,已经时候同步过去了6个文件。

[root@backup ~]# ll /nfsbackup/

total 8

-rw-r--r-- 1 rsync rsync 0 Oct 17 12:06 1.txt

-rw-r--r-- 1 rsync rsync 0 Oct 17 12:06 2.txt

-rw-r--r-- 1 rsync rsync 0 Oct 17 12:06 3.txt

-rw-r--r-- 1 rsync rsync 0 Oct 17 12:06 4.txt

-rw-r--r-- 1 rsync rsync 0 Oct 17 12:06 5.txt

-rw-r--r-- 1 rsync rsync 0 Oct 17 12:06 6.txt

2.5 利用while循环语句编写的脚本停止方法(kill)

  1. ctrl+z暂停程序运行,kill -9杀死

  2. 不要暂停程序,直接利用杀手三剑客进行杀进程

说明:kill三个杀手不是万能的,在进程暂停时,无法杀死;kill -9 (危险)

2.5.1 查看后台都要哪些程序在运行

[root@nfs01 data]# jobs

[1]+  Running                sh /server/scripts/inotify.sh &

2.5.2 fg将后台的程序调到前台来

[root@nfs01 data]# fg 1

sh /server/scripts/inotify.sh

2.6 进程的前台和后台运行方法:

    fg    -- 前台

    bg    -- 后台

2.6.1 脚本后台运行方法

    01. sh inotify.sh &

    02. nohup sh inotify.sh &

    03. screen实现脚本程序后台运行
sh /server/scripts/inotify.sh &

nohup

nohup sh inotify.sh &

2.7 screen实现脚本程序后台运行

2.7.1 经过yum查找发现screen命令属于screen包

[root@test ~]# yum provides screen

Loaded plugins: fastestmirror, security

Loading mirror speeds from cached hostfile

 * base: mirrors.aliyun.com

 * epel: mirrors.aliyun.com

 * extras: mirrors.aliyun.com

 * updates: mirrors.aliyun.com

base                                                      | 3.7 kB    00:00   

epel                                                      | 4.3 kB    00:00   

extras                                                    | 3.4 kB    00:00   

updates                                                  | 3.4 kB    00:00   

screen-4.0.3-19.el6.x86_64 : A screen manager that supports multiple logins on

                          : one terminal

Repo        : base

Matched from:

2.7.2 安装screen软件

[root@test ~]# yum install -y  screen

2.7.3 screen命令的参数

在shell中输入 screen即可进入screen 视图

[root@test ~]# screen

Screen实现后台运行程序的简单步骤:

  screen -ls :可看screen会话

  screen -r ID :指定进入哪个screen会话

Screen命令中用到的快捷键

  Ctrl+a c :创建窗口

  Ctrl+a w :窗口列表

  Ctrl+a n :下一个窗口

  Ctrl+a p :上一个窗口

  Ctrl+a 0-9 :在第0个窗口和第9个窗口之间切换

  Ctrl+a K(大写) :关闭当前窗口,并且切换到下一个窗口 ,

(当退出最后一个窗口时,该终端自动终止,并且退回到原始shell状态)

  exit :关闭当前窗口,并且切换到下一个窗口

(当退出最后一个窗口时,该终端自动终止,并且退回到原始shell状态)

  Ctrl+a d :退出当前终端,返回加载screen前的shell命令状态

  Ctrl+a " : 窗口列表不同于w

2.8 sersync软件实现实时同步

http://www.linuxidc.com/Linux/2017-10/147899.htm

本博文中所使用的系统版本为: CentOS release 6.9 (Final) 内核版本为: 2.6.32-696.10.1.el6.x86_64 望读者注意!

从inotify机制谈FileObserver实现原理

有些情况下,我们难免需要监控一些文件的变化情况,这该如何实现呢?自然而然的我们会想要利用一个线程,每个一段时间便去看看文件的情况,这种方式本质上就是基于时间调度的轮训.虽然能够实现我们的需求,但是这种方式只适合文件经常变化的情况,其他情况下都非常低效,并且可能丢掉某些类型的变化,也就是说,这种方式无法实现实时的文件监控.

inotify简介

那还有其他的方式么?熟悉linux的童鞋应该记得从linux kernel 2.6.13开始引入inotify机制,用于通知用户相关文件变化情况:任何一个文件发生某种变化,都会产生一个相应的文件事件.

我们不仅好奇,文件的哪些事件能够被监控,也就是说inotify支持监控文件的哪些变化呢?继续往下看.

可监控事件类型

目前inotify能够监控的以下文件变化事件:

未分类

API说明

不难发现,inotify对文件监控的支持是非常全面的,足以满足我们绝大部门的需求.接下来,我们对innotify的api做个简单的说明:

未分类

事件通知

在可监控事件中,我们已经了解inotify支持的文件事件.现在来看看这些当这些文件事件产生时,其发出通知的结构.在inotify中,事件通知结构用结构体inotify_event表示:

struct inotify_event
{
  int wd;               //监控目标的watch描述符
  uint32_t mask;        //事件掩码
  uint32_t cookie;      //事件同步cookie
  uint32_t len;         //name字符串的长度
  char name __flexarr;  //被监视目标的路径名
  };

这里需要记住一点:name字段并不是什么时候都有的:只有要监控的目标是一个目录,且产生的事件与目录内部的文件或子目录相关,且与目录本身无关时才会提供相应的name字段.
cookie用于关联被观察对象的IN_MOVED_FROM事件和IN_MOVED_TO 事件.

使用流程

了解以上之后,那么该怎么用呢?要实现对文件或者目录的监控需要经过以下几个步骤:

1. 创建inotify实例

在应用程序中,首先需要创建inotify实例:

int fd=inotify_init();

该方法创建了一个inotify实例,并返回一个文件描述符以便能够通过这个描述符访问到inotify实例.

2. 添加监控

在获得inotify实例产生的文件描述符之后,我们就可以为其添加watch.另外,我们也可以使用mask(事件掩码)来设置我们想监控的事件类型.当然可以我们也可以使用IN_ALL_EVENTS监控所有事件:

int wd=inotify_add_watch(fd,path,mask)

补充:
此处的fd即inotify_init()方法返回的文件描述符.每个文件描述符都有一个排序的事件序列.path则是需要监控的文件或者目录的路径.mask则是事件掩码,它表示应用程序对哪些事件感兴趣.

文件系统产生的事件由Watch对象来管理,该方法将返回的wd就是Watch对象的句柄.

3. 等待事件与循环处理

在为inotify实例添加watch之后,接下来就是等待事件了.为了能不断的处理事件,我们将其放在循环体当中.
在循环中,通过read()方法可以一次获得多个事件.在没有事件产生时,read()被阻塞,一旦有事件产生,那么我们就可以读取事件到的我们设置的事件数组中,然后对事件数组进行处理,其简单代码如下:

//事件数组,自定义设置,这里我们设置为128
char event_buf[128];

while(true){
     int num_bytes=read(fd,event_buf,len);
     //处理事件
     handleEvent(event_buf);
     //....省略....
    }

补充

event_buf是一个事件数组,用于接受文件变化所产生的事件(inotify_event).len则指定了要读的长度.通常来说,len大于事件数组的大小,很多时候,我们也会直接取事件数组的大小来作为len.

4.停止监控

当需要停止监控的时候,需要为文件描述符删除watch:

int r=inotify_rm_watch(fd,wd);

此处的fd也是在创建inotify时返回的文件描述符,wd则是上面提到watch对象的句柄.

到现在,我们已经对inotity有了初步的理解,感兴趣的童鞋可以自行研究.我们的重点还是Android中FileObserver的实现.接下来,我们真正的开始了解FileObserver的实现.

FileObserver实现原理

我们知道Android 1.5时对应的linux内核已经是2.6.26,因此完全可以在Android上利用inotify机制来实现对文件的监控.Google很显然意识到了这一点,并且帮我们在inotify的基础上进行封装—FileObserver,以实现监听文件访问,创建,修改,删除等操作

接下来,来看一下FileObserver如何借助inotify实现文件监控的.

监控线程初始化

在FileObserver中存在一个静态内部类ObserverThread,该线程类是实现了文件监控的过程:

public abstract class FileObserver {
    //可监控的事件
    public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE
            | CLOSE_NOWRITE | OPEN | MOVED_FROM | MOVED_TO | DELETE | CREATE
            | DELETE_SELF | MOVE_SELF;

    private static class ObserverThread extends Thread {
        //....省略多行代码....
    }

    private static ObserverThread s_observerThread;

    static {
        s_observerThread = new ObserverThread();
        s_observerThread.start();
    }

       //....省略多行代码....

}

不难发现发现FileObserver通过静态代码块的方式构造了s_observerThread对象,我们来看一下其构造过程:

public ObserverThread() {
       super("FileObserver");
       m_fd = init();
   }

这里又调用natvie方法init().既然这样,我们就在深入一下,看看init()方法的实现(现在,是不是发现我们自己编译源码的好处了?)该方法的实现在/frameworks/base/core/jni/android_util_FileObserver.cpp

static jint android_os_fileobserver_init(JNIEnv* env, jobject object)
{
#if defined(__linux__)
    return (jint)inotify_init();
#else
    return -1;
#endif
}

其实现非常简单,就是调用inotify中的inotify_init()来创建一个inotify实例。回到FileObserver中来看s_ObserverThread的启动:

public void run() {
            observe(m_fd);
        }

这里同样是调用natvie方法observe(int fd):

static void android_os_fileobserver_observe(JNIEnv* env, jobject object, jint fd)
{
#if defined(__linux__)

2    //设置事件数组
    char event_buf[512];
    struct inotify_event* event;

    //循环处理读到的事件
    while (1)
    {
        int event_pos = 0;
        //读取事件
        int num_bytes = read(fd, event_buf, sizeof(event_buf));

        if (num_bytes < (int)sizeof(*event))
        {
            if (errno == EINTR)
                continue;

            ALOGE("***** ERROR! android_os_fileobserver_observe() got a short event!");
            return;
        }

        //处理事件数组
        while (num_bytes >= (int)sizeof(*event))
        {
            int event_size;
            event = (struct inotify_event *)(event_buf + event_pos);

            jstring path = NULL;

            if (event->len > 0)
            {
                path = env->NewStringUTF(event->name);
            }

           //调用ObserverThread中的onEvent方法 
            env->CallVoidMethod(object, method_onEvent, event->wd, event->mask, path);
            if (env->ExceptionCheck()) {
                env->ExceptionDescribe();
                env->ExceptionClear();
            }
            if (path != NULL)
            {
                env->DeleteLocalRef(path);
            }

            event_size = sizeof(*event) + event->len;
            num_bytes -= event_size;
            event_pos += event_size;
        }
    }

#endif
}

不难看出,此处的循环主要就是从inotity中取出事件,然后回调ObserverThread中的onEvent()方法.现在,回到ObserverThread中的onEvent()方法中:

public void onEvent(int wfd, int mask, String path) {
            // look up our observer, fixing up the map if necessary...
            FileObserver observer = null;

            synchronized (m_observers) {
                //根据wfd找出FileObserver对象
                WeakReference weak = m_observers.get(wfd);
                if (weak != null) {  // can happen with lots of events from a dead wfd
                    observer = (FileObserver) weak.get();
                    if (observer == null) {//observer已经被回收时,从m_observers中删除该对象
                        m_observers.remove(wfd);
                    }
                }
            }

            // ...then call out to the observer without the sync lock held
            if (observer != null) {
                try {
                    //回调给FileObserver中的onEvent方法进行处理
                    observer.onEvent(mask, path);
                } catch (Throwable throwable) {
                    Log.wtf(LOG_TAG, "Unhandled exception in FileObserver " + observer, throwable);
                }
            }
        }

FileObserver中的onEvent()为抽象方法,也就是要求你继承FileObserver,并实现该方法,在其中做相关的操作.
到现在为止我们已经明白了ObserverThread如何被启动,以及如何获取inotify中的事件,并回调给上层进行处理.

启动监控

上面提到m_observers表,该表维护着已经注册的FileObserver对象.接下来,我们就就来看看FileObserver中的startWatching()方法,该方法注册FileObserver对象,也是启动监控的过程:

public void startWatching() {
        if (m_descriptor < 0) {
            m_descriptor = s_observerThread.startWatching(m_path, m_mask, this);
        }
    }

具体的注册操作委托给s_observerThread中的startWatching():

public int startWatching(String path, int mask, FileObserver observer) {
            //调用native方法startWatching,并得到一个watch对象的句柄
            int wfd = startWatching(m_fd, path, mask);

            Integer i = new Integer(wfd);
            if (wfd >= 0) {
                synchronized (m_observers) {
                    //将watch对象句柄和当前FileObserver关联
                    m_observers.put(i, new WeakReference(observer));
                }
            }

            return i;
        }

该方法中同样调用了native方法,其具体实现是:

static jint android_os_fileobserver_startWatching(JNIEnv* env, jobject object, jint fd, jstring pathString, jint mask)
{
    int res = -1;
#if defined(__linux__)
    if (fd >= 0)
    {
        const char* path = env->GetStringUTFChars(pathString, NULL);

        res = inotify_add_watch(fd, path, mask);

        env->ReleaseStringUTFChars(pathString, path);
    }
#endif
    return res;
}

不难看出,这里通过inotify的inotify_add_watch()为上面生成的inotify对象添加watch对象,并将watch对象的句柄返回给ObserverThread.

停止监控

到现在我们已经了解了如何注册watch句柄到FileObserver对象.有了注册的过程,当然少不了反注册的过程.同样,FileObserver为我们提供了stopWatching()来实现反注册,即停止监控的过程:

public void stopWatching() {
       if (m_descriptor >= 0) {//已经注册过的才能反注册
           s_observerThread.stopWatching(m_descriptor);
           m_descriptor = -1;
       }
   }

具体的实现也是交给了s_observerThread的stopWatching()方法:

public void stopWatching(int descriptor) {
            stopWatching(m_fd, descriptor);
        }

接着委托给了natvie方法:

static void android_os_fileobserver_stopWatching(JNIEnv* env, jobject object, jint fd, jint wfd)
{
#if defined(__linux__)
    inotify_rm_watch((int)fd, (uint32_t)wfd);
#endif
}

这里的实现非常简单,就是调用inotify_rm_watch方法来解除inotify实例和watch实例的关系.

到现在为止我们已经弄明白了FileObserver的实现原理,为了方便理解,我们用一张简单的图来描述整个过程:

未分类

使用说明

想必你已经了解了FileObserver的实现原理,接下里我们来看看如何使用.要想实现文件监控,我们只需要继承FileObserver类,并在onEvent()处理相关事件即可,简单的用代码演示一下:

public class SDCardObserver extends FileObserver {
    public SDCardObserver(String path) {
        super(path);
    }

    @Override
    public void onEvent(int i, String s) {
        switch (i) {
            case FileObserver.ALL_EVENTS:
                //全部事件
                break;
            case FileObserver.CREATE:
                //文件被创建
                break;
            case FileObserver.DELETE:
                //文件被删除
                break;
            case FileObserver.MODIFY:
                //文件被修改
                break;
        }
    }
}

注意事项

这里我们需要注意两个问题:

  • 谨慎的选择你要处理的事件,否则可能造成死循环.

  • 当不再需要监听时,请记得停止监控

  • 需要注意FileObserver对象被垃圾回收的情况,从上面的原理中我们知道,该对象被回收后将不会再触发事件.

配置rsync Inotify进行文件实时同步

一、简介

rsync用于网络间数据备份 具备高安全性,能实现增量备份,监控的文件必须扫描 文件量大时扫描花费大量时间 所以使用inotify的异步文件系统监控

调用内核监控 检测到文件的修改 同时rsync同步文件

rpmfind.NET搜索 rsync 找到官网地址为 http://rsync.samba.org/ 可以下载源码包进行安装

二、安装过程

1、模拟环境

  • 源服务器192.168.58.142 目标服务器(可以有多台) 192.168.58.143

  • 目标服务器需要监听服务 等待源服务器(客户端)推送文件

2、演示rsync安装过程

目标服务器rsync安装和配置

yum install rsync xinetd

xinetd即extended internet daemon,xinetd是新一代的网络守护进程服务程序,可以用于管理其他的网络服务

  • 关闭selinux(不关闭有可能抛出rsync: mkstemp “/.a.txt.SqAQVm” (in test) failed: Permission denied (13))

  • 临时关闭 setenforce 0 或者编辑 etc/selinux/config 修改 SELINUX=disabled 永久关闭

编辑/etc/xinted.d/rsync

service rsync  
{  
        disable = no  #将禁用改成no  
        flags           = IPv6  
        socket_type     = stream  
        wait            = no  
        user            = root  
        server          = /usr/bin/rsync  
        server_args     = --daemon  
        log_on_failure  += USERID  
}   

通过官方文档 查看rsync的配置文件格式(http://everythinglinux.org/rsync/)

[root@ha etc]# vi rsyncd.conf  
log file = /var/log/rsyncd.log  #日志文件  
pid file = /var/run/rsyncd.pid  #进程文件  
lock file = /var/run/rsync.lock #同步锁文件  

[simple_path_name]   
   path = /data   #表示要同步的目录  
   comment = My Very Own Rsync Server #表示注释  
   uid = root   #同步有权限的用户名  
   gid = root   #同步有权限的用户组  
   port = 873   #对外监听的端口  
   read only = no  #是否文件目录是只读的  
   list = yes   # 是否显示服务端文件列表  
   auth users = mysync  需要同步的文件需要用到的内部账号 可以在下面参数文件中定义  
   secrets file = /etc/rsyncd.scrt 同步的内部通信的账号和密码文件  

创建 用户密码文件 /etc/rsyncd.scrt 格式为:用户名:密码 可以定义多个用户

mysync:123456  

给该两个文件设置600权限

chmod 600 rsyncd.conf

chmod 600 /etc/rsyncd.scrt 

启动rsync

service xinetd start |  stop |restart  

查看运行状态

[root@ha etc]# service xinetd status  
xinetd (pid  7283) is running...  

查看默认 873端口是否开放

[root@ha etc]# netstat -aon | grep 873  
    tcp        0      0 :::873                      :::*                        LISTEN      off (0.00/0/0)  

尝试在任意机器 使用 telnet 192.168.58.142 873 可以查看配置的日志文件

[root@ha run]# more /var/log/rsyncd.log  
    2017/08/03 12:13:30 [7406] connect from ha1 (192.168.58.143)  
    2017/08/03 12:14:11 [7505] connect from ha1 (192.168.58.143)  

源服务器(192.168.58.143)rsync安装和配置

yum install rsync xinetd

xinetd即extended internet daemon,xinetd是新一代的网络守护进程服务程序,可以用于管理其他的网络服务

编辑/etc/xinted.d/rsync

service rsync  
{  
        disable = no  #将禁用改成no  
        flags           = IPv6  
        socket_type     = stream  
        wait            = no  
        user            = root  
        server          = /usr/bin/rsync  
        server_args     = --daemon  
        log_on_failure  += USERID  
}  
  • 关闭selinux(不关闭有可能抛出rsync: mkstemp “/.a.txt.SqAQVm” (in test) failed: Permission denied (13))

  • 临时关闭 setenforce 0 或者编辑 etc/selinux/config 修改 SELINUX=disabled 永久关闭

编辑/etc/xinted.d/rsync

使用命令测试同步文件-v表示增量备份 -a表示传输文件 /data/ 表示当前机器需要同步到目标服务器的文件目录 :test 表示目标服务器 rsyncd.conf定义的[模块名称]

rsync -avH --port=873 --progress  /data/   [email protected]::test  要求你输入目标服务器用户名密码配置文件中的密码 输入123456即可

多次执行只有一次同步 修改文件后再次尝试

3、演示inotify安装过程

  • rpmfind.net搜索 inotify-tool 搜索到官网 https://github.com/rvoicilas/inotify-tools/wiki

  • 下载 源代码 wget https://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

  • inotify只需要在源服务器监听文件的修改状态 然后调用rsync即可 或者使用scp都行

  • 解压后 ./configure –prefix=/usr/local/inotify & make & make install 安装 (安装过rsync 一般gcc都已经安装 如果没有 yum -y install gcc)

  • 安装完成后 /usr/local/inotify/bin下的可执行文件 必须设置到环境变量中

  • vi ~/.bash_profile 添加 或者添加到/etc/rc.local文件中

PATH=$PATH:/usr/local/inotify/bin  
export PATH  

source .bash_profile 执行

查看inotify的三个内核参数是否成功配置

[root@ha1 bin]# ll /proc/sys/fs/inotify    
total 0  
-rw-r--r-- 1 root root 0 Aug  3 14:24 max_queued_events  
-rw-r--r-- 1 root root 0 Aug  3 14:24 max_user_instances  
-rw-r--r-- 1 root root 0 Aug  3 14:24 max_user_watches  

该三个参数的作用为

max_user_instances:用户创建inotify实例最大值  
max_queued_events:inotify产生的事件队列最大长度,如果值太小,会出现错误,导致监控文件不准确  
max_user_watches:监控同步的文件包含的最大目录数,  
可以用:find /data -type d|wc -l 统计,必须保证参数值大于统计结果(/home/rain为同步文件目录)。  

查看查看完整的参数名称

[root@ha1 bin]# sysctl -a | grep max_user_instances  
fs.inotify.max_user_instances = 128  #可以看出参数名 带了前缀 fs.inotify.  

可以通过sysctl -w 参数名=参数值修改 或者编辑 /etc/sysctl.conf 添加参数名=参数值键值对
查看官方教程 https://github.com/rvoicilas/inotify-tools/wiki#info 通过查看/usr/local/inotify/bin目录 发现就两个命令

inotifywait 用于等待一个事件被触发(增删改移动等)  
inotifywatch 监听某个目录后者文件的所有事件 一有事件就触发  

4、inotifywatch 演示

(-e表示监听事件(create创建 access表示读取 delete删除 modify修改) 可以通过inotifywatch –help查看 -t表示监听事件 -r 表示监听目录)

inotifywatch -v -e access -e modify -t 60 -r /data 

60s内尝试读取或者修改文件 过了60s后统计记录就会出现在一个列表中

[root@ha1 bin]# inotifywatch -v -e access -e modify -t 60 -r /data  
Establishing watches...  
Setting up watch(es) on /data  
OK, /data is now being watched.  
Total of 1 watches.  
Finished establishing watches, now collecting statistics.  
Will listen for events for 60 seconds.  
total  access  modify  filename  
4      1       3       /data/  

5、inotifywait演示

该命令 等待一个事件触发 触发后返回状态 此时根据状态调用rsync同步

测试该命令 创建一个脚本文件

vi ~/test.sh
#!/bin/sh  

EVENT=$(inotifywait --format '%e' ~/data)  
[ $? != 0 ] && exit  # 返回值0表示成功 不为0表示出现错误 就退出  
[ "$EVENT" = "MODIFY" ] && echo 'file modified!' 根据变量EVENT判断是哪个事件被触发了   
[ "$EVENT" = "DELETE" ] && echo 'file deleted!'  
chmod +x ~/test.sh
~/test.sh 

发现出现了阻塞 等待一个事件

[root@ha1 bin]# ./test.sh  
Setting up watches.  
Watches established.  

另外一个客户端上执行 删除/data下一个文件

[root@ha1 bin]# ./test.sh  
Setting up watches.  
Watches established.  
file delete  #输出了脚本中 输出的内容  

当然可以通过设置输出输出文件名等信息

  • –format表示时间输出格式 %T表示时间 时间格式–timefmt表示 %d表示天 %m月 %y年 %H 24小时制小时 %M分钟

  • -e表示事件 可以多个 %w表示目录 %f表示文件

[root@ha1 bin]# inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e create /data  
Setting up watches.  Beware: since -r was given, this may take a while!  
Watches established.  
03/08/17 15:16 /data/ a.txt  
03/08/17 15:17 /data/ b.txt  

也可以通过while循环 使用管道命令获取到对应的文件目录

inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e create /data |  
while read date time dir file  
do  
 echo $file  
done  

6、inotifywait整合rsync备份文件从源服务

有了上面 inotifywait的基础后 只需要在循环中获取到file 调用同步即可

使用 以下脚本测试 所有的时间 (通过inotifywait –help查看)

inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f %e' -e create,modify,delete,move /data |  
while read date time dir file event  
do  
 echo "$dir $file $event"  
done  

尝试去修改文件创建目录等操作 控制台输出如下 代码中根据不同的类型进行不同的处理

/data/ cc CREATE,ISDIR  创建目录  
/data/cc/ a.txt CREATE  创建文件  
/data/cc/ a.txt MOVED_FROM 从哪里移动  
/data/cc/ b.txt MOVED_TO   移动到这里  
/data/cc/ b.txt DELETE  删除文件  
/data/ cc DELETE,ISDIR 删除目录  
/data/ bb MOVED_FROM,ISDIR 从目录移动  
/data/ cc MOVED_TO,ISDIR   移动到新目录  

完整代码如下(如果有一个文件被修改就同步该文件就行了 但是实现起来较为复杂 这里直接更新整个目录)还是rsync的环境

srcDir=/data  
echo 123456 > /pass.wd  
chmod 600 /pass.wd  
inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f %e' -e create,modify,delete,move $srcDir |  
while read date time dir file event  
do  
 echo "$dir $file $event begin syncing"  
 rsync -avH --port=873 --progress --password-file=/pass.wd  $srcDir [email protected]::test   
done  

目标服务器 192.168.58.143 新建/my.sh 填写上边内容

nohup /my.sh & 运行 测试在/data目录修改数据 是否能同步到 58.142对应的/data目录。

使用inotify rsync实现linux文件批量实时更新

如果只对经常改动的目录进行同步,也可以忽略这个问题,如果每次改动的目录多较大,那么就要用到inotify了,Inotify是一种强大的、细粒度的、异步的文件系统事件监控机制,Linux内核从2.6.13起,加入了对Inotify的支持,通过Inotify可以监控文件系统中的添加、删除、修改、移动等各种事件,但inotify只提供了C语言接口,不方便调用,所以我们需要先安装inotify-tools

系统环境

CentOS_5.7-x86_64
更新源服务器:192.168.9.227
目的服务器:192.168.9.226 192.168.9.228 …

目的服务器配置

192.168.9.226 192.168.9.228(rsync服务端):

检查rsync是否安装

rpm -qa|grep rsync

如果没有发装,执以下命令进行安装

yum -y install rsync

定义rsync配置文件/etc/rsyncd.conf

192.168.9.226:

cat >> /etc/rsyncd.conf << EOF
uid = nobody 
gid = nobody 
use chroot = no 
max connections = 100 
timeout = 600 
pid file = /var/run/rsyncd.pid 
lock file = /var/run/rsyncd.lock 
log file = /var/log/rsyncd.log 
[web1] 
path = /data/www1/ 
ignore errors 
read only = no 
list = no 
hosts allow = 192.168.9.0/255.255.255.0 
auth users = www1 
secrets file = /etc/www1.pwd 
EOF

192.168.9.228:

cat >> /etc/rsyncd.conf << EOF
uid = nobody 
gid = nobody 
use chroot = no 
max connections = 100 
timeout = 600 
pid file = /var/run/rsyncd.pid 
lock file = /var/run/rsyncd.lock 
log file = /var/log/rsyncd.log 
[web2] 
path = /data/www2/ 
ignore errors 
read only = no 
list = no 
hosts allow = 192.168.9.0/255.255.255.0 
auth users = www2 
secrets file = /etc/www2.pwd 
EOF

rsyncd.conf配置文件详解

uid = nobody //运行RSYNC守护进程的用户
gid = nobody //运行RSYNC守护进程的组
use chroot = 0 //不使用chroot
max connections = 0 // 最大连接数,0为不限制
port = 873 //默认端口873
下面这些文件是安装完RSYNC服务后自动生成的文件
pid file = /var/run/rsyncd.pid //pid文件的存放位置
lock file = /var/run/rsync.lock //锁文件的存放位置.指定支持max connections参数的锁文件,默认值是/var/run/rsyncd.lock.
log file = /var/log/rsyncd.log //日志记录文件的存放位置
Timeout = 300 通过该选项可以覆盖客户指定的IP超时时间.通过该选项可以确保rsync服务器不会永远等待一个崩溃的客户端.超时单位为秒钟,0表示没有超时定义,这也是默认值.对于匿名rsync服务器来说,一个理想的数字是600.
Log format = %t %a %m %f %b 通过该选项用户在使用transfer logging可以自己定制日志文件的字段.其格式是一个包含格式定义符的字符串,可以使用的格式定义符如下所示:
%h 远程主机名
%a 远程IP地址
%l 文件长度字符数
%p 该次rsync会话的进程id
%o 操作类型:" send" 或" recv"
%f 文件名
%P 模块路径
%m 模块名
%t 当前时间
%u 认证的用户名(匿名时是null)
%b 实际传输的字节数
%c 当发送文件时,该字段记录该文件的校验码
默认log格式为:" %o %h [%a] %m (%u) %f %l" ,一般来说,在每行的头上会添加" %t [%p] " .在源代码中同时发布有一个叫rsyncstats的perl脚本程序来统计这种格式的日志文件.
#transfer logging = yes
使rsync服务器使用ftp格式的文件来记录下载和上载操作在自己单独的日志中.
syslog facility = local3 指定rsync发送日志消息给syslog时的消息级别,常见的消息级别是:uth, authpriv, cron, daemon, ftp, kern, lpr, mail, news, security, sys-log, user, uucp, local0, local1, local2, local3,local4, local5, local6和local7.默认值是daemon.
模块参数 [web1] //这里是认证的模块名,在client端需要指定
path = /data/www1/ //需要做镜像的目录,不可缺少!
comment = backup web //这个模块的注释信息
ignore errors //可以忽略一些无关的IO错误
read only = yes //该选项设定是否允许客户上载文件.如果为true那么任何上载请求都会失败,如果为false并且服务器目录读写权限允许那么上载是允许的.默认值为true.
list = no //不允许列文件
auth users = bak //认证的用户名,如果没有这行则表明是匿名,此用户与系统无关 该选项指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块.这里的用户和系统用户没有任何关系.如果" auth users" 被设置,那么客户端发出对该模块的连接请求以后会被rsync请求challenged进行验证身份这里使用的challenge/response认证协议.用户的名和密码以明文方式存放在" secrets file" 选项指定的文件中.默认情况下无需密码就可以连接模块(也就是匿名方式).
secrets file = /etc/www1.pwd //密码和用户名对比表,密码文件自己生成 该选项指定一个包含定义用户名:密码对的文件.只有在" auth users" 被定义时,该文件才有作用.文件每行包含一个username:passwd对.一般来说密码最好不要超过8个字符.没有默认的secures file名,需要限式指定一个(例如:/etc/www1.pwd).注意:该文件的权限一定要是600,否则客户端将不能连接服务器.
hosts allow = 192.168.9.0/255.255.255.0 //允许主机或网段
该选项指定哪些IP的客户允许连接该模块.客户模式定义可以是以下形式:
单个IP地址,例如:192.168.9.227
整个网段,例如:192.168.9.0/24,也可以是192.168.9.0/255.255.255.0
多个IP或网段需要用空格隔开,“*”则表示所有,默认是允许所有主机连接.
hosts deny = 0.0.0.0/0 //禁止主机

建立认证文件/etc/www1.pwd

此文件须与配置文件中指定文件名保持一致
此处格式为:username:password,安全问题,并不建议实际使用中使用root用户
192.168.9.226:

echo "www1:741852" >> /etc/www1.pwd

192.168.9.228:

echo "www2:951753" >> /etc/www2.pwd

并且我们需要设置此文件的权限为600

chmod 600 /etc/www1.pwd
chmod 600 /etc/www2.pwd
chmod 600 /etc/rsyncd.conf

建立motd文件(可有可无)

rsyncd.motd记录了rsync服务的欢迎信息,你可以在其中输入任何文本信息,如:

echo "Welcome to use the rsync services!" >> /var/rsyncd.motd

启动rsync

/usr/bin/rsync --daemon
echo "/usr/bin/rsync --daemon" >> /etc/rc.local

更新源服务器配置

192.168.9.227 (rsync客户端)

inotify 可以监视的文件系统事件包括

IN_ACCESS,即文件被访问
IN_MODIFY,文件被 write
IN_ATTRIB,文件属性被修改,如 chmod、chown、touch 等
IN_CLOSE_WRITE,可写文件被 close
IN_CLOSE_NOWRITE,不可写文件被 close
IN_OPEN,文件被 open
IN_MOVED_FROM,文件被移走,如 mv
IN_MOVED_TO,文件被移来,如 mv、cp
IN_CREATE,创建新文件
IN_DELETE,文件被删除,如 rm
IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己
IN_UNMOUNT,宿主文件系统被 umount
IN_CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
IN_MOVE,文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)

注:上面所说的文件也包括目录。

安装inotify-tools

在安装inotify-tools前请先确认你的linux内核是否打到了2.6.13,并且在编译时开启了CONFIG_INOTIFY选项,也可以通过以下命令检测

ls /proc/sys/fs/inotify

如果有 max_queued_events,max_user_instances,max_user_watches 三项就说明支持

wget http://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar xvf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure
make;make install

编写rsync监控脚本

vi /root/rsync.sh
#!/bin/bash
host1=192.168.9.226
host2=192.168.9.228
src=/data/www/
des1=web1
des2=web2
user1=www1
user2=www2
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' 
-e modify,delete,create,attrib 
${src} 
| while read file
do
rsync -vzrtopg --delete --progress ${src} ${user1}@${host1}::${des1} --password-file=/etc/www1.pwd &&
rsync -vzrtopg --delete --progress ${src} ${user2}@${host2}::${des2} --password-file=/etc/www2.pwd &&
echo "${files} was rsynced" >> /tmp/rsync.log 2>&1
echo "---------------------------------------------------------------------------"
done
-m, 即--monitor,表示始终保持事件监听状态。
-r, 即--recursive,表示递归查询目录。
-q, 即--quiet,表示打印出监控事件。
-e, 即--event,通过此参数可以指定要监控的事件,常见的事件有modify、delete、create、attrib等
--timefmt:指定时间的输出格式
--format:指定变化文件的详细信息

建立认证文件 (rsync客户端认证文件只用加入密码)

echo "741852" >> /etc/www1.pwd
echo "951753" >> /etc/www2.pwd
chmod 600 /etc/www1.pwd
chmod 600 /etc/www2.pwd
/bin/sh -n /root/rsync.sh //语法检查
chmod +x /root/rsync.sh
nohup sh /root/rsync.sh &
echo "nohup sh /root/rsync.sh &" >> /etc/rc.local

同步测试

在更新源服务器上新建一个文件,运行以下的命令,看文件是否可以正常同步,看有无报错信息

rsync -vzrtopg --delete --progress /data/www1/ [email protected]::web1 --password-file=/etc/www1.pwd

将要更新的文件提交到更新源服务器中,这样就通过inotify+rsync批量的将更新文件同步到所有的目的服务器中,相当方便快捷.