inotify + rsync 文件同步

说明

  • rsync 是 Linux 上使用 ssh 进行文件同步的工具,支持后台运行模式,但同步不是实时同步,且每次变更都会对目录下所有文件进行扫描,开销较大切有延迟。
  • inotify 是一个监控目录下文件变更的工具,当目录下我呢见发生变更时,可以获得对应的变更时间。
  • inotify + rsync 可以实现目录下文件发生变更实时同步到其他节点,当两节点均部署 inotify + rsync 将变更推送到对端后,可实现文件的双向同步

安装

rsync(两节点均安装)

  • 安装
1
yum -y install rsync

inotify(两节点均安装)

  • 安装系统依赖
1
yum -y install gcc
  • 下载安装包
1
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz --no-check-certificate
  • 安装
1
2
3
4
5
6
7
8
tar -zxvf inotify-tools-3.13.tar.gz
cd inotify-tools-3.14
./configure --prefix=/usr/local/inotify
make
make install
ls -alh /usr/local/inotify/bin/inotify*
ln -s /usr/local/inotify/bin/inotifywait /usr/bin/inotifywait
ln -s /usr/local/inotify/bin/inotifywatch /usr/bin/inotifywatch

配置 ssh 免密(两台机器均需配置)

  • 两节点用于数据同步的用户均生成 ssh key
1
sudo -u tomcat ssh-keygen
  • 两节点信任对节点生成的 ssh key
    • 用户名和 ip 配置为对端节点的 用户名和 ip
1
sudo -u tomcat ssh-copy-id tomcat@172.16.2.181

第一次手动同步

  • 如果目录下已经存在文件,第一次需先手动执行一次以同步文件
  • 参数说明
    • -z:压缩传输
    • -r:对子目录递归
    • -t:保持文件原有时间
    • -o:保持文件原有属主
    • -p:保持文件原有权限
    • -g:保持文件原有用户组
    • –delete:删除那些目标位置有而原始位置没有的文件
1
rsync -vzrtopg /home/tomcat/install_jre_tomcat/ tomcat@172.16.2.182:/home/tomcat/install_jre_tomcat

同步脚本

  • 两节点 /home/tomcat/scripts/sync.sh 文件下存储同步脚本
    • 注意 dest_ip 需为对端 ip
    • 同步目录文件需正确
    • 目录最后 / 要保留,否则认为要同步的是目录本身而不是目录下文件
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ cat /home/tomcat/scripts/sync.sh
#!/bin/bash
src_path="/home/tomcat/install_jre_tomcat/"
dest_path="/home/tomcat/install_jre_tomcat/"
dest_user="tomcat"
dest_ip="172.16.2.182"
log_path="/home/tomcat/scripts/sync.log"

if [ ! -e "$(dirname $log_path)" ]; then
	mkdir -p "$(dirname $log_path)"
fi

/usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M:%S' --format '%T|%w%f|%e' -e close_write,delete,create,attrib $src_path | while read file; do
	f_name="$(echo $file | awk -F '|' '{print $2}')"
	if [[ $(basename "$f_name") =~ ^\..* ]]; then
		continue
	fi

	if [ -f "$f_name" ]; then
		file_dest_path="$(dirname $f_name)/"
		rsync -vzrtopg --progress "$f_name" $dest_user@$dest_ip:$file_dest_path >>"$log_path" 2>&1
		echo "file ${file} was rsynced" >>"$log_path"
	else
		rsync -vzrtopg --progress "$src_path" $dest_user@$dest_ip:$dest_path >>"$log_path" 2>&1
		echo "dir ${file} was rsynced" >>"$log_path"
	fi
done
  • 启动
1
nohup sudo -u tomcat bash /home/tomcat/scripts/sync.sh &
  • 设置开机自启动
1
2
3
4
5
chmod +x /home/tomcat/scripts/sync.sh
cat >> /etc/rc.local <<EOF
nohup sudo -u tomcat bash /home/tomcat/scripts/sync.sh &
EOF
chmod u+x /etc/rc.local
  • 保险起见,添加定时任务,每两个小时进行一次全量同步
1
0 */2 * * * rsync -vzrtopg --progress "/home/tomcat/install_jre_tomcat/" tomcat@172.16.2.182:/home/tomcat/install_jre_tomcat/ >>"$log_path" 2>&1

系统参数(如果遇到报错,可调整配置)

  • max_queued_events: inotify队列最大长度,如果值太小,会出现”** Event Queue Overflow **”错误,导致监控文件不准确
  • max_user_watches: 要同步的文件包含多少目录,可以用:find /root/ceshi -type d | wc -l 统计,必须保证
  • max_user_watches值大于统计结果(这里/root/ceshi为同步文件目录)
  • max_user_instances:每个用户创建inotify实例最大值
1
2
3
4
5
6
7
8
sysctl -w fs.inotify.max_queued_events="99999999"
sysctl -w fs.inotify.max_user_watches="99999999"
sysctl -w fs.inotify.max_user_instances="65535"
vi /etc/sysctl.conf #添加以下代码
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535
:wq! #保存退出