inotify、rsync同步引起的cpu load过高的问题

2014-11-10 14:55:41
在用rsync做同步方案的时候遇到的问题, 当要同步的目录中文件太多的时候,会消耗很大的资源。

最近发现服务器的cpu负载越来越高,使用Linux命令“top”查看达到了20多,一些操作明显变慢,
比如ssh登录要停顿好几秒钟才能进入shell。
经过运维部门同事的查看,发现是rsync同步占用的负载过高。

我们是多台服务器做的负载均衡,其中的一台服务器要把新的内容不断同步到其它几台服务器上。
采用的是Inotify-tools 和rsync结合的工作方式。
 inotify-tools负责监控一个目录是否有文件变化,包括新增文件、文件删除、文件修改,甚至是所有者等属性的更改,
然后,每当有变动的时候,就调用rsync做一次同步操作,把变化的文件同步到其他服务器。

关于rsync和inotify-tools的文章,网上有很多,这里就不做详细的介绍,大体的代码像下面这个样子

/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e close_write,modify,delete,create,attrib $src\
| while read DATE TIME DIR FILE; do
       /usr/bin/rsync -avH --delete --progress $src rsyncuser@$host::$module  
done

rsync同步一次,是要遍历一遍目录,找到变化的文件,然后再同步,
对于小数据量的文件同步没有什么问题,但是当文件数量过多的话,rsync遍历一遍目录需要花费很长的时间,
同时也比较消耗资源。

我们也很难给出一个具体的量值,多少文件算少,多少文件算多,我们的文件数量大约在六七十万。

知道了问题所在,就很好想到解决办法,
就是每当inotify-tools监控到文件的改变时,只同步这一个发生变化的文件,而不是遍历整个文件夹。
rsync也有同步单个文件的功能,正好派上用场。

大体的脚本如下:


#!/bin/bash
monitor_folder="/data/hutuseng/"
desc="root@192.168.37.133://data/hutuseng/"
rsync_log="/root/rsync.log"
close="CLOSE_WRITE,CLOSE"
/usr/local/bin/inotifywait -mrq  --format '%w%f %e' --excludei "swpx$|sw(p|x)$|~$|/$|4913"\
  -e move,create,modify,delete,close,attrib  $monitor_folder | while read files stat
do
        if [[ "$stat" == "$close" ]];then
                echo "$(date +%F) \t $files"  > $rsync_log
                #file_relative=`echo $files|sed  "s:$monitor_folder::g"`
                file_relative=${files//$monitor_folder/}
                cd $monitor_folder
                rsync -R -aze ssh $file_relative $desc
        fi
done

为了保证文件的一致性,我们每天晚上利用空闲时间,进行一次全量的rsync同步,基本解决了这个cpu负载过高的问题。