项目有个新的需求,在多台APP服务器随机上传图片/资源文件,其中一台APP需要读取上传的图片,这样之前做的rsync+inotify的设置就无法应对了。
所以研究了下多向触发式实时同步机制,大家可以实验一下,如果有不妥的地方,请联系我修正,多谢了。
以下开始正题
一、 简介
Unison是Windows、Linux以及其他Unix平台下都可以使用的文件同步工具,它能使两个文件夹(本地或网络上的)保持内容的一致。Unison拥有与其它一些同步工具或文件系统的相同的特性,但也有自身的特点:
1.跨平台使用;
2.对内核和用户权限没有特别要求;
3.Unison是双向的,它能自动处理两分拷贝中更新没有冲突的部分,有冲突的部分将会显示出来让用户选择更新策略;
4.只要是能连通的两台主机,就可以运行unison,可以直接使用socket连接或安全的ssh连接方式,对带宽的要求不高,使用类似rsync的压缩传输协议
5.Unison双向同步基本原理是:假如有A B两个文件夹,A文件夹把自己的改动同步到B,B文件夹也把自己的改动同步到A,最后A B两文件夹的内容相同,是AB文件夹的合集。
6.Unison双向同步不适用于对在两个同步文件夹中同一个文件,在同一时刻被修改时,unison是不会去同步的,因为unison无法判断以那个为准。Unison将创建文件锁,并由用户来手动解锁。
二、 测试环境
A机 ubuntu 12.04 10.8.12.35 ssh:22
B机 RHEL6.2 10.8.12.201 ssh:22
三、 部署结果
实现A,B机的 /home/test/reward/目录双向同步。
四、 测试结果
a) A,B机对应的目录实现了双向同步,基于文件级别,有验证措施,有日志,如果传输失败,会再次传输。
b) 有清空保护机制:如有出现 rm -rf ./* 操作会自动停止同步,并再日志中报错。但此时再有文件级别变化,执行 清空 的同步操作,然后同步有变化的文件
c) 日志文件/home/test/inotify_unison/unison.log不能删除,一旦删除,unison程序报错。
d) 注意对文件的操作是那台机器上进行的,日志就会打在那台机器上。
五、 配置步骤
a) 安装软件
A机,ubuntu系统
[email protected]:~$ sudo apt-get install ocaml unison inotify-tools –y [email protected]:~$ dpkg -l | grep ocaml ii ocaml 3.12.1-2ubuntu2 ML language implementation with a class-based object system ii ocaml-base 3.12.1-2ubuntu2 Runtime system for OCaml bytecode executables ii ocaml-base-nox 3.12.1-2ubuntu2 Runtime system for OCaml bytecode executables (no X) ii ocaml-interp 3.12.1-2ubuntu2 OCaml interactive interpreter and standard libraries ii ocaml-nox 3.12.1-2ubuntu2 ML implementation with a class-based object system (no X) [email protected]:~$ dpkg -l | grep unison ii unison 2.40.65-1ubuntu1 file-synchronization tool for Unix and Windows [email protected]:~$ dpkg -l | grep inotify-tools ii inotify-tools 3.13-3 command-line programs providing a simple interface to inotify
B机 RHEL系统
[[email protected] ~]# yum install unison240.x86_64 inotify-tools -y Installed: unison240-gtk.x86_64 0:2.40.102-5.el6 inotify-tools.x86_64 0:3.14-1.el6 Dependency Installed: unison240.x86_64 0:2.40.102-5.el6
b) 配置A,B机 SSH互信 账号为test
略
c) 检查A,B机器时间同步机制,确保AB机器时间一致。
略
d) 配置A机上unison服务
1) 执行unison命令生成配置文件
[email protected]:~$ unison abc
2) 创建日志文件夹(此步骤可以忽略,已添加到脚本中)
[email protected]:~$ mkdir /home/test/inotify_unison
3) 配置unison服务
[email protected]:~$ vim /home/test/.unison/default.prf
# Unison preferences file
#表示全自动模式,接受并执行默认动作。
batch = true
#表示保持同步的文件属组信息。
group = true
#表示保持同步的文件属主信息。
owner = true
#同步指定的子目录及文件,而非整个目录。可以写多个path。
#path = wwwbak
#指定同步忽略的子目录或者文件,支持正则。
#ignore = Name *.tmp
#表示保持同步的文件读写权限。
perms = -1
#安静模式
silent = true
#同步修改时间
times = true
#force参数表示会以本地所指定文件夹为标准,将该目录同步到远端。这里需要注意,如果指定了force参数,那么Unison就变成了单项同步了,也就是说会以force指定的文件夹为准进行同步,类似与rsync。
#force =
#true表示同步时通过文件的创建时间来比较两地文件;false表示同步时通过比较两地文件内容。
fastcheck = false
#links = true
#打开日志记录,指定日志路径。
log = true
logfile = /home/test/inotify_unison/unison.log
#间隔1秒后,开始新的一次同步检查
repeat = 1
#失败重试次数
retry = 10
#指定同步时最大线程数。
maxthreads = 300
#默认值是true,用于激活rsync传输模式,false将使用SSH传输
rsync = false
#使用ssh的压缩传输方式。
sshargs = -C
#stream = true
#优化传输参数,默认值为true。
xferbycopying = true
e) 配置B机上unison服务
[email protected]:~$ vim /home/test/.unison/default.prf # Unison preferences file batch = true group = true owner = true #path = wwwbak #ignore = Name *.tmp perms = -1 silent = true times = true #force = fastcheck = false links = true log = true logfile = /home/test/inotify_unison/unison.log repeat = 1 retry = 10 maxthreads = 300 rsync = false sshargs = -C stream = true xferbycopying = true
f) 配置A机上功能脚本
[[email protected] scripts]$ vim /home/test/scripts/inotify_unison.sh #!/bin/bash # inotify_unison tools # create by [email protected] # 2014/11/29 UNISON="/usr/bin/unison" LOCAL_DIR="/home/test/reward_to_sm/" REMOTE_DIR="/home/test/reward_to_sm/" REMOTE_USER="test" ATTRIBUTES="modify,delete,create,attrib" # mkdir unison log dir LOGDIR="/home/test/inotify_unison" # sync file to many servers IP_LIST="10.8.12.201,10.8.9.9,10.8.12.20" IP_LIST="10.8.12.201" IP_LIST_FILE="/tmp/${USER}_inotify_unison_iplist" echo $IP_LIST > $IP_LIST_FILE sed -i ‘s/,/\n/g‘ $IP_LIST_FILE [ -d /home/test/inotify_unison ] || mkdir -p /home/test/inotify_unison # create /tmp/test_inotify_unison.bin echo "#!/bin/bash inotifywait -mrq --timefmt ‘%d/%m/%y %H:%M‘ --format ‘%T %w%f‘ -e ${ATTRIBUTES} ${LOCAL_DIR} | while read files do for IPADDR in \`sed ‘/^$/p‘ $IP_LIST_FILE\` do $UNISON default "${LOCAL_DIR}" "ssh://${REMOTE_USER}@\$IPADDR/${REMOTE_DIR}" done done " > /tmp/${USER}_inotify_unison.bin chmod +x /tmp/${USER}_inotify_unison.bin start() { if [ -f /tmp/${USER}_inotify_unison_lock ] then echo -e " $USER inotify_unison had started !\n" && exit 1 fi echo "$USER inotify_unison start ..." nohup /tmp/${USER}_inotify_unison.bin > /tmp/${USER}_inotify_unison_nohup.out 2>&1 & echo -e "${USER}\n${LOCAL_DIR}\n${REMOTE_DIR}\n${IP_LIST}" > /tmp/${USER}_inotify_unison_lock } stop() { echo "$USER inotify_unison stop ... " rm -f /tmp/${USER}_inotify_unison_lock ps -ef | grep unison | grep -v grep | grep -v $$ | grep $USER | awk ‘{print $2}‘ | xargs kill -9 } restart() { stop start } reload() { stop start } case "$1" in start) $1 ;; stop) $1 ;; restart) $1 ;; reload) $1 ;; status) if [ -f /tmp/${USER}_inotify_unison_lock ] then echo -e " $USER inotify_unison had started !\n" exit 0 else echo -e " $USER inotify_unison not started !\n" exit 0 fi ;; *) echo $"Usage: $0 {start|stop|status|restart|reload}" exit 2 esac exit $?
PS:Windows下的unison配置文件默认位于C:\Documents and Settings\currentuser\.unison目录,默认的配置文件名是default.prf。
g) 配置B机上功能脚本
与A机上功能脚本一致
将IP_LIST参数修改为A机IP
六、 启动与关闭inotify_unison服务
启动命令:
su - test /home/test/scripts/inotify_unison.sh start 关闭命令: su - test /home/test/scripts/inotify_unison.sh stop