将rsync与linux内核中的Inotify功能复用,达到实时监控同步数据,附带脚本

一直以来不想用rsync,之前dongnan向我推荐过一次,后来查了查感觉那会也用不上,自己安装一下,试了试感觉没啥太好的地方,而主要是当你文件比较多的时候会在速度很资源上有多余浪费,所以一直也没用(就好比,你拷贝1G的文件,如果里面有上万个小文件。那这个速度肯定比不上一个1G的大文件一次性传输快了。这时候谁管你用的是固态还是高速硬盘)。
但这次实在没办法,同机备份,我也懒得自己写脚本了,干脆就整个目录每次备份吧。这次有些事情,没办法如果用脚本的话会很不方便,所以跟linux内核内的inotify配合达到实时备份的作用

什么是rsync
Rsync,Remote Synchronize,意思很明显就是远程同步软件。该软件能够在同步文件的同时,保持文件的权限、时间、软硬链接等一些信息。
地址:http://rsync.samba.org/

windows下请转战cwRsync

rsync 包括如下的一些特性:

能更新整个目录和树和文件系统;
有选择性的保持符号链链、硬链接、文件属于、权限、设备以及时间等(它只更新那里不一样的文件,相同的文件它会直接跳过去的<大量时如上面提到的~~慢死你>);
对于安装来说,无任何特殊权限要求;
对于多个文件来说,内部流水线减少文件等待的延时;
能用rsh、ssh 或直接端口做为传输入端口;
支持匿名rsync 同步文件,是理想的镜像工具;
加密传输数据,保证了数据的安全性;

rsync 的一些不足:

当文件数量达到了十万甚至千万量级,扫描所有文件将是非常耗时(谁让它是进行差量比对传输呢);
不能实时的去监测、同步数据,当然可以通过一些方式进行触发让其进行数据同步(但你觉得两次难道不会有有时间差吗?这个差值大小原因,请看看上一条后自行分析);

本文不讲解同步到其他服务器,仅仅本地同步(到服务器端其实操作差不多,唯一就是添加标签以及一些参数等)

#创建配置文件{(rsync.conf:服务的主要配置文件),(rsyncd.secrets:存储rsync服务的用户名和密码的,它是一个明文的文本文件,权限仅所有者可写),(rsyncd.motd:服务的欢迎信息)}

启动一下下

修改rsync服务文件

什么是Inotify

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

而inotify-tools则是 inotify 的一个简单接口。同时还提供了一系列的命令行工具,这些工具可以用来监控文件系统的事件。 inotify-tools是用c编写的,除了要求内核支持inotify外,不依赖于其他。inotify-tools提供两种工具,一是inotifywait,它是用来监控文件或目录的变化,二是inotifywatch,它是用来统计文件系统访问的次数。现在介绍一下它的使用方法。

具体参数,请检索文中的【inotify-tools工具的语法参数】部分

下载、安装

安装正确后,会有如下两个二进制文件 inotifywait(监控) inotifywatch(统计)

实验一下

如果你是64位,会有如下错误提示

inotifywatch: error while loading shared libraries: libinotifytools.so.0: cannot open shared object file: No such file or directory

通过软连接到lib64里

然后正常执行(你人工对home目录下做任意操作,连接、修改、创建),会有如下提示access、 modify、 create分别操作几次

执行监控命令inotifywait,并且我使用linux系统帐号再次重新登陆,发现home下的变化如下,如果想一直监控就把-t换为-m即可。

不管是inotifywait还是inotifywatch都有-e参数,-e有以下事件动作

access 文件读取
modify 文件更改。
attrib 文件属性更改,如权限,时间戳等。
close_write 以可写模式打开的文件被关闭,不代表此文件一定已经写入数据。
close_nowrite 以只读模式打开的文件被关闭。
close 文件被关闭,不管它是如何打开的。
open 文件打开。
moved_to 一个文件或目录移动到监听的目录,即使是在同一目录内移动,此事件也触发。
moved_from 一个文件或目录移出监听的目录,即使是在同一目录内移动,此事件也触发。
move 包括moved_to和 moved_from
move_self 文件或目录被移除,之后不再监听此文件或目录。
create 文件或目录创建
delete 文件或目录删除
delete_self 文件或目录移除,之后不再监听此文件或目录
unmount 文件系统取消挂载,之后不再监听此文件系统。



有个问题是,我发现中文的文件会提示错误,字符类型什么,我也懒得查明了。估计是因为我的rsync目标盘是挂载的windows ntfs硬盘的原因。使用–iconv=utf8,iso88591 –protect-args 等等都不行 起了个怪了!

下面写了个脚本,用来监控有变动的文件

需要配置_rsync_bin、_info、_source、_object、_parameter、_log四个变量即可

后台执行:

rsyncinotify.Monitor脚本内容 下载

参考资料:

rsync部分

核心算法介绍:
假定在名为α和β的两台计算机之间同步相似的文件 A 与 B ,其中α对文件 A 拥有访问权,β对文件 B 拥有访问权。并且假定主机α与β之间的网络带宽很小。那么 rsync 算法将通过下面的五个步骤来完成:
1. β将文件 B 分割成一组不重叠的固定大小为 S 字节的数据块。最后一块可能会比 S 小。
2. β对每一个分割好的数据块执行两种校验:一种是 32 位的滚动弱校验,另一种是 128 位的 MD4 强校验。
3. β将这些校验结果发给α。
4. α通过搜索文件 A 的所有大小为 S 的数据块 ( 偏移量可以任选,不一定非要是 S 的倍数 ) ,来寻找与文件 B 的某一块有着相同的弱校验码和强校验码的数据块。这项工作可以借助滚动校验的特性很快完成。
5. α发给β一串指令来生成文件 A 在β上的备份。这里的每一条指令要么是对文件 B 经拥有某一个数据块而不须重传的证明,要么是一个数据块,这个数据块肯定是没有与文件 B 的任何一个数据块匹配上的。
–此算法参考自http://www.iteye.com/topic/604436

Rsync的命令格式可以为以下六种:

Rsync 参数选项说明:

rsync.conf配置中log format的参数

log format

This parameter allows you to specify the format used for logging file transfers when transfer logging is enabled. The format is a text string containing embedded single-character escape sequences prefixed with a percent (%) character. An optional numeric field width may also be specified between the percent and the escape letter (e.g. "%-50n %8l %07p").

The default log format is "%o %h [%a] %m (%u) %f %l", and a "%t [%p] " is always prefixed when using the "log file" parameter. (A perl script that will summarize this default log format is included in the rsync source code distribution in the "support" subdirectory: rsyncstats.)

The single-character escapes that are understood are as follows:

%a the remote IP address 远程IP地址
%b the number of bytes actually transferred 传输字节数
%B the permission bits of the file (e.g. rwxrwxrwt) 该文件的权限位
%c the total size of the block checksums received for the basis file (only when sending) 为基础的块校验接收文件的总大小,仅发送成功
%f the filename (long form on sender; no trailing "/") 文件名字
%G the gid of the file (decimal) or "DEFAULT" 文件gid
%h the remote host name 远程主机名
%i an itemized list of what is being updated 被更新的详细列表
%l the length of the file in bytes 该文件的长度(以字节为单位)
%L the string " -> SYMLINK", " => HARDLINK", or "" (where SYMLINK or HARDLINK is a filename)
%m the module name 该模块的模块名
%M the last-modified time of the file 文件的最后修改时间
%n the filename (short form; trailing "/" on dir)
%o the operation, which is "send", "recv", or "del." (the latter includes the trailing period) 操作,是 “发送”,“接收”,或“删除”。
%p the process ID of this rsync session 会话id
%P the module path 该模块的路径
%t the current date time 当前的日期时间
%u the authenticated username or an empty string 认证的用户名或留空
%U the uid of the file (decimal) 该文件的UID(十进制)

inotify-tools工具的语法参数

inotifywait
语法:
inotifywait [-hcmrq] [-e ] [-t ] [–format ] [–timefmt ] [ … ]
参数:
-h,–help
输出帮助信息
@
排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-m, –monitor
接收到一个事情而不退出,无限期地执行。默认的行为是接收到一个事情后立即退出。
-d, –daemon
跟–monitor一样,除了是在后台运行,需要指定–-outfile把事情输出到一个文件。也意味着使用了–syslog。
-o, –outfile
输出事情到一个文件而不是标准输出。
-s, –syslog
输出错误信息到系统日志
-r, –recursive
监视一个目录下的所有子目录。
-q, –quiet
指定一次,不会输出详细信息,指定二次,除了致命错误,不会输出任何信息。
–exclude
正则匹配需要排除的文件,大小写敏感。
–excludei
正则匹配需要排除的文件,忽略大小写。
-t , –timeout
设置超时时间,如果为0,则无限期地执行下去。
-e , –event
指定监视的事件。
-c, –csv
输出csv格式。
–timefmt
指定时间格式,用于–format选项中的%T格式。
–format
指定输出格式。
%w 表示发生事件的目录
%f 表示发生事件的文件
%e 表示发生的事件
%Xe 事件以“X”分隔
%T 使用由–timefmt定义的时间格式

inotifywatch
语法:
inotifywatch [-hvzrqf] [-e ] [-t ] [-a ] [-d ] [ … ]
参数:
-h, –help
输出帮助信息
-v, –verbose
输出详细信息
@
排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-z, –zero
输出表格的行和列,即使元素为空
–exclude
正则匹配需要排除的文件,大小写敏感。
–excludei
正则匹配需要排除的文件,忽略大小写。
-r, –recursive
监视一个目录下的所有子目录。
-t , –timeout
设置超时时间
-e , –event
只监听指定的事件。
-a , –ascending
以指定事件升序排列。
-d , –descending
以指定事件降序排列。

UTC、GMT与DST

目前世界上常见的计时方式主要有:太阳时(MT)和原子时。GMT(格林尼治时间)的正午是指当太阳横穿格林尼治子午线时的时间,由于地球的自转呈现不规则性,并且正在缓慢减速,因此格林威治时间目前已经不再作为标准时间使用,取而代之的是协调时间时(UTC),它是由原子钟提供,它是基于标准的GMT提供的准确时间,若在不需要精确到秒的前提下,通常也将GMT与UTC视作等同。

DST(daylight saving time)也称为夏令时,它是以节约能源为目的而人为规定的一种制度,它规定某段时间作为夏令时间,并在标准时间的基础上提前多长时间(通常是一个小时),同时DST还规定了规定生效的起始时间和末尾时间,详细规则会在tzset函数中介绍,值得注意的是目前只是部分国家实施了夏令时制度。

标准时间是相对于UTC/GMT时间而言的,它在UTC/GMT之上增加了时区信息,比如中国标准时间是GMT+8,即在UTC时间上增加8个小时。

参考资料:

http://rsync.samba.org/

http://www.samba.org/ftp/rsync/rsyncd.conf.html

- THE END -
版权声明:
转载原创文章请注明,文章出处://kinggoo.com
原文地址:https://kinggoo.com/rsync-inotify.htm
发表评论?

13 条评论。

  1. 同步大文件后 文件的MD5变了
    http://blog.sina.com.cn/s/blog_71261a2d0100xslx.html
    使用modify 可以解决

  2. #标记开始
    ## inotifywait 这一行是监控 变量_for_source所设置文件夹内文件信息是否有modify,delete,move,create,attrib变动 然后将变动信息交给while循环
    inotifywait -mrq –timefmt ‘%Y-%m-%d %H:%M’ –format ‘%T %w%f %e ‘ -e modify,delete,move,create,attrib ${_for_source} | \
    while read _date _time _dirpath _status
    ## while 是来读取inotifywait 监控每个每次变动信息,给_date _time _dirpath _status
    do
    ## 对已配置源文件夹路径数组循环匹配 _dirpath 数据是否相同
    for(( i=0;$i<${#_source[@]};i++ )) do ## 监控数据是否含有同步源的路径(当_source数据内添加多个监控路径,而只有其中一个被监控路径下有变化时执行对应同步\ 为了减少无用同步次数) echo ${_dirpath} |grep -P -o -i "^${_source[$i]}?" >/dev/null && _go=1 || _go=0
    if(( ${_go} ));then
    ## 因为汉字编码问题,如果是用后台执行rsync的话,可能会比较暂用cpu等资源,所以建议使用(同步完一个后在去下一个)
    ## 我自己服务器上用的是下面这串,多了–iconv ,需要安装iconv支持
    ## ${_rsync} ${_parameter} –iconv=”UTF-8″,GB18030 ${_source[$i]} ${_object[$i]} &>> ${_log} &&
    ${_rsync} ${_parameter} ${_source[$i]} ${_object[$i]} &>> ${_log} &&
    ## ${_rsync} ${_parameter} ${_source[$i]} ${_object[$i]} &>> ${_log} &
    #—
    ## 以一定格式记录日志
    echo “${_date} ${_time} ${_dirpath} ${_status}” >> ${_log}
    break 1
    fi
    done
    # 等3秒,让数据飞一会
    sleep 3
    done

  3. ‘: not a valid identifierncinotify.Monitor: line 2: declare: _object
    'syncinotify.Monitor: line 21: syntax error near unexpected token

    ‘syncinotify.Monitor: line 21: `for(( i=0;$i<${_source[@]};i++ ))
    脚本运行出错,请教下是什么问题呢

    • _object=( “/mnt/windows/RSYNC/” “/mnt/windows/RSYNC/” “/mnt/windows/RSYNC/” )
      应该是这里 你设置有问题,请检查,或者把你脚本内容发送到邮件。标题不要直接写文章地址,会被拉黑的

  4. 博主,你好。谢谢你的分享,让我很受启发。不过还有点问题小女子想要请教你,能否加个qq请教一下。QQ:914855723

  5. 楼主辛苦了,你搜索下 sersync

  6. 拜访,谢谢博主分享!欢迎来小站坐坐!

  7. 拜访,谢谢博主分享!欢迎来小站坐坐!

  8. 博主辛苦,谢谢分享!

发表评论


此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据