一、Inotify介绍:

      Inotify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如删除、读、写和卸载操作等。您还可以跟踪活动的源头和目标等细节。

使用 inotify 很简单:创建一个文件描述符,附加一个或多个监视器(一个监视器 是一个路径和一组事件),然后使用 read 方法从描述符获取事件。read 并不会用光整个周期,它在事件发生之前是被阻塞的。

       内核版本不低于 2.6.13,系统就支持 inotify。  同时可以查看内核参数


[root@localhost inotify]# cd /proc/sys/fs/inotify/
[root@localhost inotify]# ll
total 0
-rw-r--r-- 1 root root 0 Aug 29 17:20 max_queued_events
-rw-r--r-- 1 root root 0 Aug 29 17:20 max_user_instances
-rw-r--r-- 1 root root 0 Aug 29 17:20 max_user_watches
[root@localhost inotify]# cat *
16384
128
8192


      

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


      查看notify-tools信息:  https://github.com/rvoicilas/inotify-tools/wiki


      结合rsync进行测试,脚本如下:


#!/bin/sh

cmd=`which inotifywait`
$cmd -mrq --timefmt "%F %T" --format "%T %f"  -e create,close_write,attrib /data  | while read date time file
do
  cd /data && rsync -azv $file [email protected]::data --password-file=/etc/rsyncd.pass
done

注:加上delete事件会导致删除同步错误,提示文件不存在,故删除事件单独启个脚本进程。




      性能测试:

           针对大量的小文件 ,同步小文件太慢,直接同步目录

           10-100k的小文件,并发达到200-300,需要对内核三个参数进行调优

           max_queued_events: 320000  max_user_watches:5000000


在对一个大磁盘进行inotify监听时,爆出如下错误:

Failed to watch /home/;

upper limit on inotify watches reached!

Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches’.


cat一下这个文件,默认值是8192,echo 8192000 > /proc/sys/fs/inotify/max_user_watches即可



二、sersync介绍:

sersync利用inotifyrsync对服务器进行实时同步,其中inotify用于监控文件系统事件,rsync是目前广泛使用的同步算法,其优点是只对文件不同的部分进行操作,所以其优势大大超过使用挂接文件系统的方式进行镜像同步。由金山的周洋开发完成,是目前使用较多的文件同步工具之一。该工具和其他的工具相比有如下优点:

  • sersync是使用c++编写,由于只同步发生更改的文件,因此比其他同步工具更节约时间、带宽;

  • 安装方便、配置简单;

  • 使用多线程进行同步,能够保证多个服务器实时保持同步状态;

  • 自带出错处理机制,通过失败队列对出错的文件重新出错,如果仍旧失败,则每10个小时对同步失败的文件重新同步;

  • 自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次;

  • 自带sockethttp协议扩展,你可以方便的进行二次开发;


    线程组线程是等待线程队列的守护线程,当队列中有数据的时候,线程组守护线程逐个唤醒,当队列中inotify事件交多的时候就会被全部唤醒一起工作。这样设计的目的是能够同时处理多个inotify事件,重发利用服务器的并发能力(核数*2+2)。

      之所以称之为线程组线程,是因为每个线程在工作的时候,会根据服务器的数量建立子线程,子线程可以保证所有的文件与各个服务器同时同步,当要同步的文件较大的时候,这样设计可以保证各个远程服务器可以同时获得要同步的文件。

       服务线程的作用有三个,首先是处理同步失败的文件,将这些文件 再次同步,对于再次同步失败的文件会生成rsync_fail_log.sh脚本,记录失败的事件。同时每隔10个小时执行脚本一次,同时清空脚本。服务 线程的第三个作用是crontab功能,可以每隔一定时间,将所有路径整体同步一次。

    过滤队列的建立是为了过滤短时间内产生的重复的inotify信息,例如在删除文件夹得时候,inotify就会同时产生删除文件夹里的文件与删除文件夹 得事件,通过过滤队列当删除文件夹事件产生的时候,会将之前加入队列的删除文件的事件全部过滤掉,这样只产生一条事件减轻了同步的负担。同时对于修改文件 的操作的时候,会产生临时文件与重复操作。

   

配置文件说明:

下面做逐行的进行解释说明:
1、
hostip与port是针对插件的保留字段,对于同步功能没有任何作用,保留默认即可。

2、filter文件过滤功能
对于sersync监控的文件,会默认过滤系统的临时文件(以“.”开头,以“~”结尾),除了这些文件外,可以自定义其他需要过滤的文件。
   
       
       
       
       
       
       
   

start设置为 true, 在exclude标签中,填写正则表达式,默认给出两个例子分别是过滤以".gz"结尾的文件与过滤监控目录下的info路径(监控路径/info /*),可以根据需要添加,但开启的时候,自己测试一下,正则表达式如果出现错误,控制台会有提示。相比较使用rsync 的exclude功能,被过滤的路径,不会加入监控,大大减少rsync的通讯量。


3、inotify监控参数设定(优化)
对于inotify监控参数可以进行设置,根据您项目的特点优化srsync。
   
       
       
       
       
       
       
       
       
   

对于大多数应用,可以尝试把createFile(监控文件事件选项)设置为false来提高性能,减少 rsync通讯。因为拷贝文件到监控目录会产生create事件与close_write事件,所以如果关闭create事件,只监控文件拷贝结束时的事 件close_write,同样可以实现文件完整同步。
注意:强将createFolder保持为true,如果将createFolder设为false,则不会对产生的目录进行监控,该目录下的子文件与子目录也不会被监控。所以除非特殊需要,请开启。
默认情况下对创建文件(目录)事件与删除文件(目录)事件都进行监控,如果项目中不需要删除远程目标服务器的文件(目录),则可以将delete 参数设置为false,则不对删除事件进行监控。


4、失败日志脚步配置

对于失败的传输,会进行重新传送,再次失败就会写入rsync_fail_log,然后每隔一段时间(timeToExecute进行设置)执行该脚本再次重新传送,然后清空该脚本。可以通过path来设置日志路径。


5、Crontab定期整体同步功能

       
           
               
               
           

       

crontab可以对监控路径与远程目标主机每隔一段时间进行一次整体同步,可能由于一些原因两次失败重传都失败了,这个时候如果开启了crontab功能,还可以进一步保证各个服务器文件一致,如果文件量比较大,crontab的时间间隔要设的大一些,否则可能增加通讯开销。schedule这个参数是设置crontab的时间间隔,默认是600分钟
如果开启了filter文件过滤功能,那么crontab整体同步也需要设置过滤,否则虽然实时同步的时候文件被过滤了,但crontab整体同步的时候如果不单独设置crontabfilter,还会将需过滤的文件同步到远程,crontab的过滤正则与filter过滤的不同,也给出了两个实例分别对应与过滤文件与目录。总之如果同时开启了filter与crontab,则要开启crontab的crontabfilter,并按示例设置使其与filter的过滤一一对应。


6、插件相关


       
   

   
         
       
           
           
       

   


   
       
           
       

   


   
       
           
           
           
       

   


如上面的xml所示,其中plugin标签设置为true时候,在同步文件或路径到远程之后后,调用插件。通过name参数指定需要执行的插件。目前支持的有command refreshCDN socket http四种插件。http插件目前由于兼容性原因去除,以后会重新加入。

command插件当文件同步完成后,会调用command插件,如同步文件是test.php,则test.php文件在改动之后,调用rsync同步到远程服务器后,调用command插件,执行

/bin/sh test.php  suffix>/dev/null 2>&1

如果
suffix
设置了,则会放在inotify事件test.php之后
如果ignoreError为true,则会添加>/dev/null 2>&1
当然还可以设置command的filter,当filter为ture,include可以只对正则匹配到的文件,调用command。


刷新CDN插件“refreshCDN”,就在同步过程中将文件发送到目的服务器后刷新cdn接口。如果不想使用,则将start属性设为false即可。如果需要使用其他插件,则查看其他plugin标签,将插件名称改为 xml中其它插件的名称即可。

       以下模块(refreshCDN http socket)可以单独使用,只需在命令行下使用-m 参数即可。如果需要作为插件与同步程序一起使用,见同步程序说明的插件配置。

      该模块根据chinaCDN的协议,进行设计,当有文件产生的时候,就向cdn接口发送需要刷新的路径位置。刷新CDN模块需要配置的xml文件如下。


其中 localpath watch 是需要监控的目录。

cdnifo标签制定了cdn接口的域名,端口号,以及用户名与密码。

sendurl标签是需要刷新的url的前缀。

regexurl标签中的,regex属性为true时候,使用match属性的正则语句匹配inotify返回的路径信息,并将正则匹配到的部分作为url一部分,

举例:

如果产生文件事件为:/data0/htdoc/cms.88181.com/site/jx3.88181.com/p_w_picpath/a/123.txt

经过上面的match正则匹配后,最后刷新的路径是:

http://pic.88181.com/cms/jx3/a/123.txt;

如果regex属性为false,最后刷新的路径是

http://pic.88181.com/cms/jx3.88181.com/p_w_picpaths/a/123.txt;


三、inotify及sersync压力测试

环境介绍:

   172.16.171.100    测试客户机、nfs客户端

   172.16.171.110    inotify、sersync端 、nfs服务端

   172.16.171.120    rsync服务端

   均为CentOS release 6.6 64位系统,4核2G


1、测试脚本介绍:


[root@openstack-nova test]# ll
total 61680
-rw-r--r--. 1 root root  1024000 Aug 30 11:27 1000k.txt
-rw-r--r--. 1 root root   102400 Aug 30 11:27 100k.txt
-rw-r--r--. 1 root root    10240 Aug 30 10:28 10k.txt
-rw-r--r--. 1 root root 10240000 Aug 30 11:39 10m.txt
-rw-r--r--. 1 root root   512000 Aug 30 11:27 500k.txt
-rw-r--r--. 1 root root    51200 Aug 30 10:28 50k.txt
-rw-r--r--. 1 root root 51200000 Aug 30 11:39 50m.txt
-rwxr-xr-x. 1 root root      313 Aug 30 11:09 test.sh



cat test.sh


#!/bin/sh

count=20
a=1

name=$1
num=$2
file=$3
while [ "$a" -le "$num" ]
do
   for ((i=1;i<=$count;i++))
    do
       [ ! -e /cms/$name/$i ] &&  /bin/mkdir /cms/$name/$i
       /bin/cp ${file}.txt /cms/$name/$i/${file}_`echo $(date)$RANDOM | md5sum | cut -c 1-8`.txt
    done
   a=`expr $a + 1`

   sleep 1

done



2、针对sersync目录进行10K、500K、1000K、10M测试,测试命令如下:

sh test.sh sersync 20 10k

sh test.sh sersync 20 500k

sh test.sh sersync 20 1000k

sh test.sh sersync 20 10m

172.16.171.110(sersync端)和172.16.171.120(rsync)端查看统计命令:

while true; do tree sersync/ | wc -l; sleep 1 ;done | tee -a sersync.log

结果如下:


id s(10k) r(10k) s(500k) r(500k) s(1m) r(1m) s(10m) r(10m)
1 3 3 3 3 3 3 3 3
2 43 36 43 39 43 14 21 11
3 63 53 63 54 43 43 43 30
4 78 63 78 63 63 63 45 43
5 83 83 83 83 83 83 59 51
6 103 103 103 103 103 98 63 63
7 123 123 123 123 123 110 70 64
8 143 143 143 143 125 123 74 69
9 163 153 163 153 143 143 74 71
10 182 163 172 163 163 163 75 73
11 183 183 183 183 183 183 77 73
12 203 203 203 203 203 193 77 76
13 223 223 223 223 214 203 78 77
14 243 243 243 235 223 223 80 83
15 263 253 259 247 243 243 82 83
16 283 263 263 263 263 258 83 84
17 284 283 283 283 281 266 88 85
18 303 303 303 303 283 283 90 88
19 323 323 323 323 303 303 94 90
20 343 343 343 333 323 323 99 95
21 363 359 348 343 343 333 100 96
22 383 372 363 363 352 343 100 99
23 392 383 383 383 363 363 102 100
24 403 403 403 403 383 383 103 103
25 423 423 423 416 403 399 109 103
26


423 421 408 112 106
27



423 423 115 107


从统计结束来看:

在172.16.171.110上直接生成文件

文件大小在1M之内的小文件,同步效率在秒级。

10M的大文件sersync端使用了126秒,rsync端同步完成共使用了161秒。


在172.16.171.100上以nfs挂载,并批量生成文件进行测试。

10K文件使用28-29秒,500K文件使用45秒,1M文件使用70秒,10M文件使用279秒,同步完成使用281秒



3、针对inotify目录进行10K、500K、1000K、10M测试,测试命令如下:

sh test.sh inotify 20 10k

sh test.sh inotify 20 500k

sh test.sh inotify 20 1000k

sh test.sh inotify 20 10m

172.16.171.110(inotify端)和172.16.171.120(rsync)端查看统计命令:

while true; do tree inotify/ | wc -l; sleep 1 ;done | tee -a inotify.log

结果如下:


id s(10k) r(10k) s(500k) r(500k) s(1m) r(1m) s(10m) r(10m)
1 3 3 3 3 3 3 3 3
2 43 43 43 43 43 37 43 8
3 63 63 63 56 63 54 48 29
4 83 82 80 63 83 66 63 32
5 83 83 83 83 84 83 77 37
6 103 103 103 103 103 103 80 42
7 123 123 123 123 123 123 83 43
8 143 143 143 143 143 137 103 43
9 163 163 163 156 163 150 110 44
10 183 172 171 166 176 166 115 47
11 186 183 183 183 183 183 117 47
12 203 203 203 203 203 203 123 47
13 223 223 223 223 223 223 123 48
14 243 243 243 241 243 236 124 54
15 263 263 263 247 259 245 125 58
16 283 271 264 263 263 263 136 63
17 288 286 283 283 283 283 136 64
18 303 303 303 303 303 301 139 64
19 323 323 323 323 323 313 140 64
20 343 343 343 336 333 323 143 64
21 363 363 355 346 343 343 143 66
22 383 383 363 363 363 363 143 71
23 394 393 383 383 383 378 150 72
24 403 403 403 403 403 391 158 72
25 423 423 423 421 414 405 160 72
26


423 423 423 163 72


从统计结束来看:

在172.16.171.110上直接生成文件

文件大小在1M之内的小文件,同步效率在秒级,和sersync效率不相上下。

10M的大文件inotify端使用了103秒,rsync端同步完成使用了410秒,要远远超过sersync。


在172.16.171.100上以nfs挂载,并批量生成文件进行测试。

10K文件使用28-29秒,500K文件使用41秒,1M文件使用50秒,10M文件使用210秒,同步完成使用216秒


总结:当并发大量生成大文件时,sersync因多线程效率会高点,当并发量一般时,感觉inotify效率更高点。