> CentOS > CentOS服务器 > 文件同步 >

linux中inotify+unison实现数据双向实时同步

前言:

在网上搜寻了很多方案,在liux下做文件同步,有如下几种方式:
1、nfs实现web数据共享
2、rsync +inotify实现web数据同步
3、rsync+sersync更快更节约资源实现web数据同步
4、unison+inotify实现web数据双向同步
在这里详细介绍第四种方案,前几种各有不足。只有第四种方案支持双向实时同步,且当其中一台服务器宕机,也不会影响web的访问。

 

1.环境介绍
服务器分别为:
服务器A:192.168.20.200,同步目录:/usr/local/nginx/html
服务器B:192.168.20.201,同步目录:/usr/local/nginx/html

2.安装unison(A、B都安装)
首先安装ocaml,版本至少为3.07或更高
下载地址:http://caml.inria.fr
例:http://caml.inria.fr/pub/distrib/ocaml-3.10/ocaml-3.10.2.tar.gz
将文件上传到home目录,并且切换到home目录执行如下命令:
tar xvf ocaml-3.10.2.tar.gz
cd ocaml-3.10.2
./configure
make world opt
make install
cd ..

然后安装unison(A、B都安装)
下载地址:www.seas.upenn.edu/~bcpierce/unison/
例:http://www.seas.upenn.edu/~bcpierce/unison//download/releases/unison-2.32.52/unison-2.32.52.tar.gz
tar xvf unison-2.32.52.tar.gz
cd unison-2.32.52
make UISTYLE=text THREADS=true STATIC=true
cp unison /usr/local/bin
cd ..
注:
UISTYLE=text THREADS=true STATIC=true表示使用命令行方式,加入线程支持以静态模式编译

3.安装inotify
下载地址:http://inotify-tools.sourceforge.net
例:https://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar xvf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure
make
make install
cd ..

4.配置双机ssh信任(除以下方法外,也可以在A中生成密钥后,把A上的.ssh目录全SCP到B服务器/root/.ssh,这样方便些)
以root用户登陆(A和B机器上都操作)
在服务器A上创建.ssh目录
mkdir ~/.ssh
chmod 700 ~/.ssh
生成RSA密钥
ssh-keygen -t rsa
(然后连续三次回车)

添加密钥到授权密钥文件中
在192.168.20.200服务器A上操作(22是ssh端口号)
cd ~/.ssh
ssh "-p 22" 192.168.20.200 cat /root/.ssh/id_rsa.pub >> authorized_keys  #小写p
ssh "-p 22" 192.168.20.201 cat /root/.ssh/id_rsa.pub >> authorized_keys
scp  -P 22 authorized_keys 192.168.20.201:/root/.ssh/  #大写P
chmod 600 /root/.ssh/authorized_keys

在192.168.20.201服务器B上操作
chmod 600 /root/.ssh/authorized_keys
分别在两台机器上执行如下测试(第一次执行时,会要求输入密码,以后执行则不需要说明信任成功)
ssh -p 22 192.168.20.200 date
ssh -p 22 192.168.20.201 date

5.添加脚本
在192.168.20.200服务器A上添加脚本:
mkdir /script
vim /script/inotify.sh
#/bin/bash
UNISON=`ps -ef |grep -v grep|grep -c inotifywait`
if [ ${UNISON} -lt 1 ]
then
ip2="192.168.20.201"
src2="/usr/local/nginx/html/"
dst2="/usr/local/nginx/html/"
/usr/local/bin/inotifywait -mrq -e create,delete,modify,move $src2 | while read line
do
/usr/local/bin/unison -batch $src2 ssh://$ip2/$dst2
echo -n "$line " >> /var/log/inotify/inotify$(date +%u).log
echo ` date +%F %T " " -f1-4` >> /var/log/inotify/inotify$(date +%u).log
done
fi
在192.168.20.201服务器上添加脚本:
mkdir /script
vim /script/inotify.sh
#/bin/bash
UNISON=`ps -ef |grep -v grep|grep -c inotifywait`
if [ ${UNISON} -lt 1 ]
then
ip2="192.168.20.200"
src2="/usr/local/nginx/html/"
dst2="/usr/local/nginx/html/ "
/usr/local/bin/inotifywait -mrq -e create,delete,modify,move $src2 | while read line
do
/usr/local/bin/unison -batch $src2 ssh://$ip2/$dst2
echo -n "$line " >> /var/log/inotify/inotify$(date +%u).log
echo ` date +%F %T " " -f1-4` >> /var/log/inotify/inotify$(date +%u).log
done
fi

6.在二台服务器上修改脚本权限:
chmod a+x /script/inotify.sh
在计划任务中添加任务(原本在/etc/rc.local下添加开机启动的,但出问题,脚本并不执行)
crontab -e
#unison+inotify
* * * * * /bin/sh /script/inotify.sh > /dev/null 2>&1 &
重启电脑,测试二台服务器中/var/www的内容是否能同步
不重启电脑,手动执行脚本也可以测试
/bin/sh /script/inotify.sh或/script/inotify.sh
在其中一台/var/www目录中添加,或修改,或删除文件的时候,可以看到脚本状态,同时另一台服务器也应该会跟随操作。

注:
如果/var/log/inotify目录没有则需要手工创建,用来存放inotify的日志;
如果需要可以指定某几种后缀的文件不同步,例:
打开/root/.unison/default.prf,添加:
ignore = Name *.txt
ignore = Name *.mdb
意思就是不同步txt和mdb格式的文件,修改完之后重新执行一下/bin/sh /script/inotify.sh即可生效。
我的是直接指定名称:
ignore = Name .bash_profile
ignore = Name .viminfo
ignore = Name .bash_history

以上步骤操作完成基本上都不会有问题,如果有问题那你接着往下看。

7.如果有问题,请手动修改下脚本:
在某些公司中,是禁止禁用root远程登陆,只能使用普通用户进行同步方案
等待同步目录(二台电脑不能使用一样的待同步目录名,否则报错)
192.168.20.200: /usr/local/nginx/html1
192.168.20.201: /usr/local/nginx/html2
 
安装过程如下
useradd –g apache unison
passwd unison
(输入新密码)
chown –R unison. /var/www
mkdir /home/unison/.ssh
chmod 700 /home/unison/.ssh
su – unison
ssh-keygen -t rsa
(然后连续三次回车)
添加密钥到授权密钥文件中
在192.168.20.200服务器A上操作(22是端口号)
cd /home/unison/.ssh
ssh "-p 22" 192.168.20.200 cat /home/unison/.ssh/id_rsa.pub >> authorized_keys  #小写p
ssh "-p 22" 192.168.20.201 cat /home/unison /.ssh/id_rsa.pub >> authorized_keys
scp  -P 22 authorized_keys 192.168.20.201:/home/unison/.ssh/  #大写P
chmod 600 /home/unison/.ssh/authorized_keys
 
在192.168.20.201服务器B上操作
chmod 600/home/unison/.ssh/authorized_keys
分别在两台机器上执行如下测试(第一次执行时,会要求输入密码,以后执行则不需要说明信任成功)
ssh -p 22 unison@192.168.20.200 date
ssh -p 22 unison@192.168.20.201 date
su - root

A脚本:
#/bin/bash
UNISON=`ps -ef |grep -v grep|grep -c inotifywait`
if [ ${UNISON} -lt 1 ]
then
ip2="unison@192.168.20.201:22"
src2="/usr/local/nginx/html1/"
dst2="/usr/local/nginx/html2/"
/usr/local/bin/inotifywait -mrq -e create,delete,modify,move $src2 | while read line
do
/usr/local/bin/unison -batch -sshargs "-i /home/unison/.ssh/id_rsa" $src2 ssh://$ip2
/$dst2
echo -n "$line " >> /var/umelook-log/inotify/inotify$(date +%u).log
echo ` date +%F %T` >> /var/umelook-log/inotify/inotify$(date +%u).log
done
fi

B脚本:
#/bin/bash
UNISON=`ps -ef |grep -v grep|grep -c inotifywait`
if [ ${UNISON} -lt 1 ]
then
ip2="unison@192.168.20.200:22"
src2="/usr/local/nginx/html2/"
dst2="/usr/local/nginx/html1/"
/usr/local/bin/inotifywait -mrq -e create,delete,modify,move $src2 | while read line
do
/usr/local/bin/unison -batch -sshargs "-i /home/unison/.ssh/id_rsa" $src2 ssh://$ip2
/$dst2
echo -n "$line " >> /var/umelook-log/inotify/inotify$(date +%u).log
echo ` date +%F %T` >> /var/umelook-log/inotify/inotify$(date +%u).log
done
fi

8.结束语
这种文件的双向复制有个好处,例:
服务器A和服务器B,当B宕机之后不影响A的使用,且当B恢复之后如果A发生了文件变化,在下次文件同步事件触发(A、B都可以触发)时则会把B宕机这段时间A中文件的变化同步到B。
可以说整个安装配置过程都很简单,关键是我们要懂得它的原理,否则出了故障则会手足无措。

 

参考:

http://www.111cn.net/sys/linux/63966.htm

http://blog.csdn.net/heidou_2016/article/details/52001756

http://blog.sina.com.cn/s/blog_720a943301017gvk.html

http://www.cnblogs.com/MYSQLZOUQI/p/5184642.html



(责任编辑:IT)