rsync+inotify实时精准文件同步,实现真正的文件实时同步!

有个空闲的云服务器,就想着给网站做个容灾备份(网站可以没量,但是骚操作不能少),第一个想到的就是用rsync来同步文件,有两个方案:1、rsync+任务计划;2、rsync+inotify。我想做到实时同步,任务计划方式的就pass掉了,只剩下个inotify可以选择。

我这个博客站现在就是用的这个实时同步方案配合MySQL主从复制做的容灾备份的。

源机器:CentOS 192.168.221.151

备份机器:Ubuntu 192.168.221.150

安装rsync

CentOS:yum -y install rsync

Ubuntu:apt-get -y install rsync

安装inotify

先安装编译工具

CentOS:yum -y install make gcc gcc-c++

Ubuntu:sudo apt-get -y install make gcc gcc-c++

然后下载编译安装inotify

cd /tmp
wget -c http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar -zxvf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure
make
sudo make install

安装完执行:inotifywait

如果返回No files specified to watch!就说明安装成功。

测试inotify安装状态
测试inotify安装状态

配置免密码登录

在源服务器上执行:ssh-keygen

一路回车就行。

使用 ssh-copy-id 将公钥上传到目标机器(192.168.221.150):

ssh-copy-id -i ~/.ssh/id_rsa root@192.168.221.150

按提示输入目标服务器密码就可以。

配置ssh免密码登录
配置免密码登录

接下来测试下免密码登录是否正常。

rsync -avzP /home/rsync/ -e "ssh -p 22" root@192.168.221.150:/home/rsync/
rsync+inotify实时精准文件同步,实现真正的文件实时同步!
测试免密码登录

可以看到现在不需要输入密码直接就传输数据了(没有录成gif,将就看)。

脚本实现实时同步

网上查到的方法基本都是

inotifywait -mrq -e modify,delete,create,attrib,move,close_write --format "%w%f %e" ./ | while read files
do
	rsync -avzP --delete --password-file=${password} $src_path $dest@$ip:$desc_path
done

这虽然能做到实时同步,但是有个坑,就是每修改一个文件都是全目录扫描一遍,文件少还好,文件多了不占用资源,还做不到实时同步。

所以只能自己动手,查了不少资料,最后参考了某位大佬的优化方案(由于当时没有记录,忘记出处了)再做了一点修改。

这脚本能实现精准实时同步,不会每次都全目录扫描一遍。

#!/bin/bash
src=/home/rsync/	#同步源目录
destIP=192.168.221.150	#目标服务器ip
destPort=22	#目标服务器ssh端口
destUser=root	#登录目标服务器的账号
destDir=/home/rsync/	#目标服务器同步目录

cd $src #先进入到源目录,才能做到目录结构一致
inotifywait -mrq -e modify,delete,create,attrib,move,close_write --format "%w%f %e" ./ | while read files
do
	SYNC_FILE=$(echo $files | awk '{print $1}')	#文件路径
	SYNC_EVENT=$(echo $files | awk '{print $2}')	#触发事件
	#编辑、添加、移动事件
	if [[ $SYNC_EVENT =~ "CREATE" ]] || [[ $SYNC_EVENT =~ "MODIFY" ]] || [[ $SYNC_EVENT =~ "CLOSE_WRITE" ]] || [[ $SYNC_EVENT =~ "MOVED_TO" ]]
	then
		rsync -gorvpzRP $SYNC_FILE -e "ssh -p $destPort" $destUser@$destIP:$destDir

		#删除事件
	elif [[ $SYNC_EVENT =~ "DELETE" ]] || [[ $SYNC_EVENT =~ "MOVED_FROM" ]]
	then
		rsync -dvpzRP --delete $(dirname $SYNC_FILE)"/" -e "ssh -p $destPort" $destUser@$destIP:$destDir
		#删除事件要使用上级目录,不然会导致报错。

		#修改属性事件
	elif [[ $SYNC_EVENT =~ "ATTRIB" ]]
	then
		if [ -f "$SYNC_FILE" ] #排除目录,只处理文件
		then
			rsync -gorvpzRP $SYNC_FILE -e "ssh -p $destPort" $destUser@$destIP:$destDir
		fi
	fi
done

把代码保存到 /home/inotify_rsync.sh

给执行权限:chmod +x /home/inotify_rsync.sh

测试脚本效果

创建一个screen会话来测试脚本效果:

screen -S test
/home/inotify_rsync.sh

ctrl+a+d 退出当前会话

在同步源目录(/home/rsync/)创建、删除、修改文件(目录)测试效果

这里图片没有录成gif,看起来没那么直观,各位看官大老爷将就看。

测试rsync+inotify同步效果
测试同步效果

可以看到创建、删除、修改文件都能正常同步到目标服务器上。

执行 screen -r test 恢复到test会话

可以看到rsync输出的日志。

rsync日志
rsync日志

配置开机启动

使用supervisor做进程守护跟开机启动

安装supervisor

CentOS:

yum -y install epel-release
yum -y install supervisor

Ubuntu:

sudo apt-get -y install supervisor

设置supervisord开机启动

Ubuntu服务名是supervisor,CentOS服务名是supervisord,下面操作以源机器(CentOS)为例。

systemctl enable supervisord

启动supervisord:

systemctl start supervisord

创建个supervisor启动inotify_rsync.sh脚本的配置文件

Centos默认保存在 /etc/supervisord.d/*.ini

Ubuntu默认保存在 /etc/supervisor/con.d/*.conf

vim /etc/supervisord.d/inotify_rsync.ini

把下面代码复制进去保存

[program:laravel-worker]
process_name=%(program_name)s
command=/home/inotify_rsync.sh
autostart=true
autorestart=true
numprocs=1
redirect_stderr=true

重启supervisor服务:systemctl restart supervisord

然后进入源目录测试同步是否正常

supervisor启动inotify_rsync.sh脚本成功
supervisor启动inotify_rsync.sh脚本成功

因为需要脚本运行的时候才能监控到文件改动触发同步操作,为了避免漏掉一些文件,再创建个任务计划,每天1点执行一次全量同步。

crontab -e

输入

* 1 * * * rsync -avzP /home/rsync/ -e "ssh -p 22" root@192.168.221.150:/home/rsync/

crontab其他参数说明可以查看这篇文章

原创文章,作者:小哆啦,如若转载,请注明出处:https://www.notevm.com/a/5949.html

(0)
上一篇 2022年5月30日 10:18
下一篇 2022年5月31日 22:30

相关推荐