25

inotify-rsync实时同步脚本 - Limboy's HQ

 3 years ago
source link: https://limboy.me/2010/12/13/inotify-rsync/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

inotify-rsync实时同步脚本

2010-12-13

为什么要写这个脚本

rsync是linux下一款非常强大的同步工具,采用差异同步的方法,只上传文件/文件夹的不同部分,同时可以对上传部分先进行压缩,所以rsync的传输效率是很高的。

但rsync也有缺点,最大的问题就是每次执行rsync命令都会遍历目标目录,当文件不多时,这没什么问题,一旦文件数到了一定规模,那么每次遍历都会消耗很多资源。但事实上改动的文件并不多,如果可以只sync改动的文件,问题就迎刃而解了。

这时就得请出本文的另一个主角:inotify。inotify是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户态得知。要使用inotify,linux的内核版本不能低于2.6.13

~$ uname -a
Linux lzyy-laptop 2.6.32-26-generic #48-Ubuntu SMP Wed Nov 24 09:00:03 UTC 2010 i686 GNU/Linux

但inotify只提供了C语言接口,不方便调用,所以我们需要先安装inotify-tools,大多数的linux发行版应该都可以直接通过apt-get或yum来安装。

脚本说明与使用

其实前人已经做了类似的工作,不过有些地方尚未完善(如删除文件的同步),于是我改进和简化了一下。

以下是服务端脚本,运行这段脚本后,这个机器上对应的文件夹将会同步到其他机器上

#!/bin/bash

###########################
# 在这里配置本地文件夹,目标host,目标的rsync_module。rsync_module在同步机器的/etc/rsyncd.conf文件中配置
# 逗号前后不要有空格
sync[0]='/path/to/local/dir,1.2.3.4,test' # localdir,host,rsync_module
# sync[1]='/path/to/local/dir,host,rsync_module'
###########################

for item in ${sync[@]}; do

dir=`echo $item | awk -F"," '{print $1}'`
host=`echo $item | awk -F"," '{print $2}'`
module=`echo $item | awk -F"," '{print $3}'`

inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format  '%T %w%f %e' \
 --event CLOSE_WRITE,create,move,delete  $dir | while read  date time file event
	do
		echo $event'-'$file
		case $event in
			MODIFY|CREATE|MOVE|MODIFY,ISDIR|CREATE,ISDIR|MODIFY,ISDIR)
				if [ "${file: -4}" != '4913' ]  && [ "${file: -1}" != '~' ]; then
					cmd="rsync -avz --exclude='*' --include=$file $dir $host::$module"
					# echo $cmd
					$cmd
				fi
				;;

			MOVED_FROM|MOVED_FROM,ISDIR|DELETE|DELETE,ISDIR)
				if [ "${file: -4}" != '4913' ]  && [ "${file: -1}" != '~' ]; then
					cmd="rsync -avz --delete-excluded --exclude="$file" $dir $host::$module"
					# echo $cmd
					$cmd
				fi
				;;
		esac
	done &
done
cd /path/to/inotify-rsync
chmod +x inotify-rsync.sh
./inotify-rsync

可以把这个脚本设置为开机启动,这样就可以自动同步了。

同步机器上要做两件事

1. 设置/etc/rsyncd.conf文件

# vim /etc/rsyncd.conf

uid=root
gid=root
# 这个test就是上面脚本中用到的rsync_module名
# path指定同步过来的文件存放的路径
# 如果只允许部分ip的机器进行同步的话,设置allow为 192.168.1.1/100 类似的格式
[test]
path=/path/to/your/dir
allow *

2. 启动rsync daemon

rsync --daemon

金山的周洋同学用C++写了个Sersync,也是利用的inotify+rsync来实现实时同步,有兴趣的可以关注一下


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK