用Unison+inotify实现数据的双向实时同步

一、Unison简介
Unison是windows和unix平台下都可以使用的文件同步工具,它能使两个文件夹(本地或网络上的)保持内容的一致。unison拥有其它一些同步工具或文件系统的相同特性,但也有自己的特点:
       1.跨平台使用;
       2.对内核和用户权限没有特别要求;
       3. unison是双向的,它能自动处理两分拷贝中更新没有冲突的部分,有冲突的部分将会显示出来让用户选择更新策略;
       4.只要是能连通的两台主机,就可以运行unison,可以直接使用socket连接或安全的ssh连接方式,对带宽的要求不高,使用类似rsync的压缩传输协议。

Unison有文字界面和图形界面,这里只介绍如何在文字界面下使用.

二、配置双机ssh信任(两台服务器的ssh端口必须是默认的22号端口)

参考:http://wushuaishuai.blog.51cto.com/3432229/1021911


三、安装unison
unison各种版本下载地址:
http://www.seas.upenn.edu/~bcpierce/unison//download.html
unison编译器下载地址:
http://caml.inria.fr/pub/distrib/ocaml-3.10
从以上地址可以下载各种平台,各种版本的unison,有基于源码安装的,有二进制的,我下载的是二进制的,可以直接使用.这里介绍源码安装:

1:源码安装unison
Linux下从源码包编译安装,需要一个叫做Objective Caml compiler的工具,版本至少3.0.7,可以从这里下载:http://caml.inria.fr/
Ocaml安装脚本如下:
# tar zxvf ocaml-3.09.3.tar.gz
# cd ocaml-3.09.3
# ./configure
# make world opt
# make install
Unison对版本要求很高,进行同步的两台主机需要相同版本的unison,所以这里使用和windows一致的版本2.13.16,unison-2.13.16.tar.gz
安装脚本如下:
# tar zxvf unison-2.13.16.tar.gz
# cd unison-2.13.16
# make UISTYLE=text THREADS=true STATIC=true
# cp ./unison /usr/local/bin/
之后将生成可执行文件unison,将其cp到系统PATH即可。


四、unison配置

1.首次配置先运行一次使其生成配置文件

/usr/local/bin/unison

vi /root/.unison/default.prf

#unison服务端配置文件
root = $dir
#本地文件夹
root = ssh://root@$unisonclient/$clientdir
#远程文件夹
batch = true
#表示全自动模式,接受并执行默认动作。
owner = true
#表示保持同步的文件属主信息。
group = true
#表示保持同步的文件属组信息。
perms = -1
#表示保持同步的文件读写权限。
fastcheck = false
#true表示同步时通过文件的创建时间来比较两地文件;false表示同步时通过比较两地文件内容。
rsync = false
#默认值是true,用于激活rsync传输模式。
sshargs = -C
#使用ssh的压缩传输方式。
xferbycopying = true
#优化传输参数,默认值为true。
confirmbigdel = false
#默认值为true,表示当需要同步的两个目录有一个为空时,unison将停止。设置为false可以保证当需要同步的某个目录为空时,unison不会停止运转。
log = true
#表示在终端输出运行信息。
logfile = /root/.unison/unison.log
#指定同时输出写入log文件。
maxthreads = 300
#指定同步时最大线程数。
#repeat = 1
#表示间隔1秒后开始一次新的同步检查
retry = 3
#指定失败重试次数
#force = /wwwroot
#指定force表示以本地/wwwroot为标准,指定了则变成单项同步了,所以在这里不指定。
#path = www
#同步指定的子目录及文件,而非整个目录。可以写多个path,如在下面再写一个path = wwwbak。
#ignore = Path WEB-INF/tmp
#忽略/wwwroot下面的WEB-INF/tmp目录,即同步时不同步它。注意,这里是"Path",而不是"path"。

 五、 安装inotify工具inotify-tools
 由于inotify特性需要Linux内核的支持,在安装inotify-tools前要先确认Linux系统内核是否达到了2.6.13以上,如果Linux内核低于2.6.13版本,就需要重新编译内核加入inotify的支持,也可以用如下方法判断,内核是否支持inotify:
[root@localhost webdata]# uname -r
2.6.18-164.11.1.el5PAE
[root@localhost webdata]# ll /proc/sys/fs/inotify
总计 0
-rw-r--r-- 1 root root 0 04-13 19:56 max_queued_events
-rw-r--r-- 1 root root 0 04-13 19:56 max_user_instances
-rw-r--r-- 1 root root 0 04-13 19:56 max_user_watches
如果有上面三项输出,表示系统已经默认支持inotify,接着就可以开始安装inotify-tools了。
可以到http://inotify-tools.sourceforge.net/下载相应的inotify-tools版本,然后开始编译安装:
[root@localhost  ~]# tar zxvf inotify-tools-3.14.tar.gz
root@localhost  ~]# cd inotify-tools-3.14
[root@localhost inotify-tools-3.14]# ./configure
[root@localhost inotify-tools-3.14]# make
[root@localhost inotify-tools-3.14]# make install
[root@localhost inotify-tools-3.14]# ll /usr/local/bin/inotifywa*
-rwxr-xr-x 1 root root 37264 04-14 13:42 /usr/local/bin/inotifywait
-rwxr-xr-x 1 root root 35438 04-14 13:42 /usr/local/bin/inotifywatch
inotify-tools安装完成后,会生成inotifywait和inotifywatch两个指令,其中,inotifywait用于等待文件或文件集上的一个特定事件,它可以监控任何文件和目录设置,并且可以递归地监控整个目录树。
inotifywatch用于收集被监控的文件系统统计数据,包括每个inotify事件发生多少次等信息。

inotify相关参数
inotify定义了下列的接口参数,可以用来限制inotify消耗kernel memory的大小。由于这些参数都是内存参数,因此,可以根据应用需求,实时的调节其大小。下面分别做简单介绍。
    /proc/sys/fs/inotify/max_queued_evnets     
       表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。
    /proc/sys/fs/inotify/max_user_instances
        表示每一个real user ID可创建的inotify instatnces的数量上限。
    /proc/sys/fs/inotify/max_user_watches
        表示每个inotify instatnces可监控的最大目录数量。如果监控的文件数目巨大,需要根据情况,适当增加此值的大小,例如:
echo 30000000 > /proc/sys/fs/inotify/max_user_watches

inotifywait相关参数
Inotifywait是一个监控等待事件,可以配合shell脚本使用它,下面介绍一下常用的一些参数:
 -m, 即--monitor,表示始终保持事件监听状态。
 -r, 即--recursive,表示递归查询目录。
 -q, 即--quiet,表示打印出监控事件。
 -e, 即--event,通过此参数可以指定要监控的事件,常见的事件有modify、delete、create、attrib等。
更详细的请参看man  inotifywait。

六、两台服务器双向同步实例

服务端执行上面五步操作,然后写脚本

vi /root/inotifyunison.sh

#!/bin/bash
host=$unisonclient
src=$dir
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,delete,create,attrib  \$src \
| while read files
        do
        /usr/local/bin/unison
                echo "\${files} was unisoned" >>/tmp/unison.log 2>&1
         done

chmod 755 /root/inotifyunison.sh

screen -S unison

/root/inotifyunison.sh &

为防止一些大文件没有及时同步,在服务端设置计划任务每天晚上3点左右同步一次。

crontab -e

00 3 * * * /usr/local/bin/unison

客户端上只安装inotify和unison,不需要配置。然后写脚本

vi /root/inotifyunison.sh

#!/bin/bash
host=$unisonserver
src=$dir
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,delete,create,attrib  \$src \
| while read files
        do
        ssh root@$unisonserver /usr/local/bin/unison
                echo "\${files} was unisoned" >>/tmp/unison.log 2>&1
         done

chmod 755 /root/inotifyunison.sh

screen -S unison

/root/inotifyunison.sh &

我写好的技术文档和脚本下载地址:

http://down.51cto.com/data/643900

通过脚本在10分钟之内让你搭建完成Unison+inotify

七、unison使用方法

 

1:本地使用
使用方法:
#unison  ixdba ixdba1  #同步本地的ixdba和ixdba1文件夹
Contacting server...
Looking for changes
Warning: No archive files were found for these roots.  This can happen either
because this is the first time you have synchronized these roots,
or because you have upgraded Unison to a new version with a different
archive format. 
Update detection may take a while on this run if the replicas are
large.
Unison will assume that the 'last synchronized state' of both replicas
was completely empty.  This means that any files that are different
will be reported as conflicts, and any files that exist only on one
replica will be judged as new and propagated to the other replica.
If the two replicas are identical, then no changes will be reported.
Press return to continue.[<spc>] Reconciling changes
ixdba          ixdba1             
         <---- file       readme.txt  [f] ?
Commands:
  <ret> or f or <spc>   follow unison's recommendation (if any)
  I                     ignore this path permanently
  E                     permanently ignore files with this extension
  N                     permanently ignore paths ending with this name
  m                     merge the versions
  d                     show differences
  x                     show details
  l                     list all suggested changes
  p or b                go back to previous item
  g                     proceed immediately to propagating changes
  q                     exit unison without propagating any changes
  /                     skip
  > or .                propagate from left to right
  < or ,                propagate from right to left

<---- file       readme.txt [f] f

Proceed with propagating updates? [] y
Propagating updates

UNISON started propagating changes at 15:06:08 on 27 Aug 2007
[BGN] Copying readme.txt

 from /ixdba1
  to /ixdba
[END] Copying readme.txt

UNISON finished propagating changes at 15:06:08 on 27 Aug 2007
Saving synchronizer state
Synchronization complete  (1 item transferred, 0 skipped, 0 failures)
如果检测到两个文件夹有所不同,unison会提示,让你选择相应的操作。如上例所示.
表示右边ixdba1的文件夹有新的文件,是否同步到左边的ixdba文件夹,f表示force,然后将确认,进行更新,如果输入?会有更详细的介绍。

2: unison远程使用
使用方法:
# unison <本地目录> ssh://remotehostname(IP)/<远程目录的绝对路径>
例如:
# unison /home/AAA ssh://username@remotehostname(ip)//DB/path/BBB
表示将本机的目录/home/AAA和远端主机的/DB/path/BBB进行同步。一般的,需要两台机能ssh连接。
注意 在主机和目录间又多加了一个 "/"

3:unison参数说明
Unison有很多参数,这里只介绍经常使用的几个,详细的请参看unison手册:
• -testserver
测试连通性,连接到服务器即退出。示例:
$ unison / ssh://opensou1@bluehost/    -servercmd=~/bin/unison -testserver
如果服务器端 unison 可执行文件不在默认目录下,甚至没有 unison 命令(需要你编译一个上传到服务器),则需要使用 -servercmd 参数告诉要执行的服务器 unison 命令位置。
使用 -testserver 参数,则成功链接即退出,也不会去执行目录的比较等后续操作。
• -servercmd xxx
告诉 unison, 服务器端的 unison 命令是什么。参见上面的示例。
• -auto
接受缺省的动作,然后等待用户确认是否执行。
• -batch
batch mode, 全自动模式,接受缺省动作,并执行。
• -ignore xxx
增加 xxx 到忽略列表中
• -ignorecase [true|false|default]
是否忽略文件名大小写
• -follow xxx
是否支持对符号连接指向内容的同步
• owner = true (保持同步过来的文件属主)
• group = true (保持同步过来的文件组信息)
• perms = -1   (保持同步过来的文件读写权限)
• repeat = 1   (间隔1秒后,开始新的一次同步检查)
• retry = 3    (失败重试)
• sshargs = -C (使用ssh的压缩传输方式)
• xferbycopying = true

• -immutable xxx
不变目录,扫描时可以忽略
• -silent
安静模式
• -times
同步修改时间
• -path xxx 参数
只同步 -path 参数指定的子目录以及文件,而非整个目录。-path 可以多次出现,例如
  unison /home/username ssh://remotehost//home/username \
 -path shared \
 -path pub \
 -path .netscape/bookmarks.html

4:通过配置文件来使用unison
尽管可以完全通过命令行的方式来指定unison运行所需要的参数,但我们还是推荐使用配置文件来进行配置使用unison,原因很简单,看配置文件比看命令行容易理解,而且可管理性更强。
默认的配置文件夹位于~currentuser/.unison,即当前用户的home目录下,windows则位于C:\Documents and Settings\currentuser\.unison,默认的配置文件名是default.prf.
运行这样的命令:
#unison exitgogo
Unison将默认读取~currentuser/.unison/exitgogo.prf文件里的配置信息.我的配置信息在/root/.unison/exitgogo.prf,因此我们可以根据上面参数的介绍,把所有的参数配置信息写入到一个.prf的文件中.
注意事项:

如何在和远程服务器同步大量数据,上传一部分数据后,超时:
9%  559:15 ETARead from remote host bluehost: Connection reset by peer
Fatal error: Lost connection with the server
实际操作中,最好的方法是,第一次先把要上传的文件打成包,用 ftp 上传,然后展开到服务器中,之后执行一次 unison 同步即可。 

 

Unison可以在一台主机上使用,同步两个文件夹,也可以在网络上是用。

你可能感兴趣的:(linux,同步,unison,文件双向同步)