Rsync、Inotify实现服务器间文件实时同步
July 6, 2011 – 9:24 pm写在前面
rsync对做系统运维的人来说,是个熟悉的名词,服务器间数据同步就靠它。但是rsync也有缺点,如果待同步文件数量巨大,那么光遍历目录的耗时就非常多,可实际上被改动待传输的文件可能只是很小的一部分。
系统运维中,用rsync实现备份服务器功能是经常遇到的。集群中程序的备份好说,一般程序文件不到升级版本,是不会改动的,所以我们每次上传后,在集群中建立信任关系,然后rsync同步下就完事了。但是用户上传图片备份呢?一般是选择定时传输文件到备份机,但是如果出现问题切换备份服务器,总会有部分数据丢失,无法做到实时备份。再举个例子,网站要跨机房进行迁移,一般的做法是在新机房放好机器后,传输程序和部分图片附件过去,然后切换DNS,数据库先用replication读写分离,远程写入撑着。老机房定时用rsync往新机房传,新机房的404页面做点手脚,如果访问的图片附件找不到,那么去旧IP地址下载新图片。这些事情说起来是几句话,做起来可很费劲,费劲之余,我们想想,如果新旧机房的附件能实现实时同步,那么是不是就等于节省了一半的力气呢?答案是肯定的。那么如何实现实时同步呢?哈哈!我们可以使用rsync和inotify来配套实现。
实验思路
假设机房里有一个web集群,我们上传程序的步骤是先上传文件到集群中某台服务器,此服务器作为集群的rsync inotify服务端,当服务端觉察到(由inotify实现)程序文件发生改变后,开始同步新文件到集群中其他服务器上(由rsync实现传输,各服务器之间先建立好信任关系)。
同理,当我们跨机房迁移网站时,由于DNS缓存导致各地访问的机房位置不同,附件图片也会上传到不同的机房里。这个时候,两个机房可以互相进行实时同步,rsync去掉–delete参数就好了。哈哈!举一反三,能学到很多东西。
测试环境
两台服务器均安装CentOS 5.5 x86_64,安装开发工具和开发库。
两台服务器IP地址、HOSTNAME和待同步目录分别为:
10.0.0.7 server2 /data/web (客户端)
10.0.0.8 server3 /data/web (客户端)
10.0.0.9 server4 /data/web (客户端)
服务端服务器配置
安装inotify工具
cd /usr/local/src
wget -c ftp://10.0.0.3/Linux/inotify-tools-3.14.tar.gz
tar zxf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure --prefix=/usr/local/inotify314
make
make install
建立从服务端到客户端的信任关系。
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
8c:6f:12:b1:cd:f7:c1:0d:48:98:d5:bb:b1:45:f0:52
保护认证文件
拷贝认证文件到集群中其他服务器上
scp /root/.ssh/id_rsa.pub root@10.0.0.8:/root/.ssh/authorized_keys
scp /root/.ssh/id_rsa.pub root@10.0.0.9:/root/.ssh/authorized_keys
测试一下,把服务端的/data/web同步到集群中各个机器上。
building file list ... done
./
sent 83 bytes received 26 bytes 218.00 bytes/sec
total size is 0 speedup is 0.00
[root@server1 .ssh]# rsync -av /data/web/ root@10.0.0.8:/data/web/
building file list ... done
./
sent 83 bytes received 26 bytes 218.00 bytes/sec
total size is 0 speedup is 0.00
[root@server1 .ssh]# rsync -av /data/web/ root@10.0.0.9:/data/web/
building file list ... done
./
sent 83 bytes received 26 bytes 218.00 bytes/sec
total size is 0 speedup is 0.00
编写脚本
vi /srv/rsync_inotify.sh
dir="/data/web/"
ip="10.0.0.7 10.0.0.8 10.0.0.9"
user=root
/usr/local/inotify314/bin/inotifywait -mrq --timefmt '%d/%m/%y-%H:%M' --format '%T %w%f' -e modify,delete,create,attrib ${dir} \
| while read file
do
for i in $ip
do
/usr/bin/rsync -av ${dir} ${user}@${i}:${dir} --delete --progress
done
done
配置开机自启动,服务器不能随便启动,第一次安装可以先放到screen里运行脚本。
sh /srv/rsync_inotify.sh
" >> /etc/rc.local
测试
我们在服务端计算机的/data/web目录下创建文件夹,创建文件,创建软连接,在客户端计算机上都可以看到,从而实现了实时文件同步。
5 Responses to “Rsync、Inotify实现服务器间文件实时同步”
有意思哦
By 水宝宝防晒 on Jul 8, 2011
Ruby的忠实支持者飘过。
By 杭州 on Sep 16, 2011
多谢博主的分享精神,赞一个哦。
By cewodi on Sep 20, 2011
回去试验下看看。
请问如果文件数量巨大,同步频率大,是否会造成负载过高?
By yxf2008 on Oct 8, 2011
试验成功了,初步看来可以实施。
By yxf2008 on Oct 8, 2011