服务器双向同步( 可实时 ) unison + inotify

一. Unison简介

Unison是Windows、Linux以及其他Unix平台下都可以使用的文件同步工具,它能使两个文件夹(本地或网络上的)保持内容的一致。
1. 跨平台使用;对内核和用户权限没有特别要求; 

2. Unison是双向的,它能自动处理两分拷贝中更新没有冲突的部分,有冲突的部分将会显示出来让用户选择更新策略;

3. 只要是能连通的两台主机,就可以运行unison,可以直接使用socket连接或安全的ssh连接方式,对带宽的要求不高,使用类似rsync的压缩传输协议。

二. 如何使用unison

本次操作环境:  两台centos服务器    服务器A        服务器B  

1. 安装 ocaml 

Linux下通过源码包编译安装Unison时,需要用到Objective Caml compiler 这个东西.  

[root@centos-A data]# rpm -qa |grep ocaml   ##可以先检查下是否安装过. 图方便本次我直接yum了
ocaml-runtime-3.11.2-5.el6.x86_64
ocaml-3.11.2-5.el6.x86_64

下载地址  http://caml.inria.fr/pub/distrib/    或者 http://ocaml.org/docs/install.html   

可以这样编译安装, 其实yum安装也可以. 版本至少为3.07或更高  yum install ocaml

wget http://caml.inria.fr/pub/distrib/ocaml-4.02/ocaml-4.02.0.tar.gz

tar xf ocaml-4.02.0.tar.gz

cd ocaml-4.02.0

./configure

make world opt

make install

ocaml -version   #看版本是否安装成功

2. 安装unison

下载地址:  https://www.seas.upenn.edu/~bcpierce/unison/download/releases/   

找stable稳定版本, 这个东西配置epel源可以yum安装, 但版本不高,当前时间多为 unison240  或者  unison227 

之前安装2.48.3时如下操作

wget http://www.seas.upenn.edu/~bcpierce/unison//download/releases/unison-2.48.3/unison-2.48.3.tar.gz

tar xf unison-2.48.3.tar.gz

cd unison-2.4

make UISTYLE=text

mkdir /root/bin/

cp unison /root/bin/

make install

cp ./unison /usr/bin/

现在最新稳定版为 2.48.4

[root@admin opt]# wget https://www.seas.upenn.edu/~bcpierce/unison/download/releases/unison-2.48.4/unison-2.48.4.tar.gz
[root@admin opt]# tar xf unison-2.48.4.tar.gz 
[root@admin opt]# ll
total 1184
drwxr-xr-x. 2 root root 4096 Mar 26 2015 rh
drwxrwxr-x. 9 root root 4096 May 24 2016 src
-rw-r--r--. 1 root root 1200861 May 24 2016 unison-2.48.4.tar.gz
[root@admin opt]# cd src/
[root@admin src]# make UISTYLE=text
File "/opt/src/fsmonitor/linux/watcher.ml", line 55, characters 5-10:
Error: Syntax error
make: *** [fsmonitor/linux/watcher.cmx] Error 2

[root@admin src]# make install
mv /root/bin//unison /tmp/unison-2903
mv: cannot stat `/root/bin//unison': No such file or directory
make: [doinstall] Error 1 (ignored)
cp unison /root/bin/
cp: cannot create regular file `/root/bin/': Is a directory
[root@admin src]# cp ./unison  /usr/local/bin/
[root@admin ~]# which unison
/usr/local/bin/unison

3. ssh免密认证

最好是用普通用户做认证. root有风险

[root@admin ~]# useradd admin
[root@admin ~]# echo bszh****|passwd --stdin admin
Changing password for user admin.
passwd: all authentication tokens updated successfully.
[root@admin ~]# su - admin
[admin@admin ~]$ pwd
/home/admin
[admin@admin ~]$ ssh-keygen -t rsa   #### 不用 -t 指定加密方式默认就是rsa  关于加密方式可参考  ssh-keygen -t ecdsa     非交互生成密钥 :  ssh-keygen -t dsa -f /root/.ssh/id_dsa -P ""
Generating public/private rsa key pair.
Enter file in which to save the key (/home/admin/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/admin/.ssh/id_rsa.
Your public key has been saved in /home/admin/.ssh/id_rsa.pub.
The key fingerprint is:
14:e9:57:7c:7f:5b:42:2f:64:30:6d:85:8a:9e:60:6e admin@admin
The key's randomart image is:
+--[ RSA 2048]----+
|        .. .oo o.|
|        ..  o.O  |
|       ..  o B o |
|       .+ o . o =|
|       oS+ .   o+|
|        E o    . |
|       .         |
|                 |
|                 |
+-----------------+

 [admin@admin ~]$ ssh-copy-id -i .ssh/id_rsa.pub '-p 22 admin@192.168.0.11'
admin@192.168.0.11's password:
Now try logging into the machine, with "ssh '-p 22 admin@192.168.0.11'", and check in:

.ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

 双方做好ssh认证后就可以测试unison可用不可用了.

  unison -batch /home/admin/test/ ssh://admin@192.168.0.11//home/admin/test

unison同步时, 如果ssh不是默认的22端口,需要指定特定端口时 

  unison -batch /data/unisontest ssh://admin@111.198.29.223:2211//data/unisontest

4. 修改配置做同步

只附上一个的配置文件吧, 另一个和这个除了地址路径外都一样

[admin@VM_0_15_centos test]$ cat /home/admin/.unison/default.prf

# Unison preferences file
root = /data/test
root = ssh://admin@111.198.29.223:2211//data/test/
batch = true
owner = true
group = true
perms = -1
fastcheck = false
rsync = false
sshargs = -C
xferbycopying = true
log = true
logfile = /home/admin/.unison/unison.log

好了. 基本能用了. 可以结合定时任务用,但是效果不好, 尤其是需要同步的目录里文件频繁更新和过大时. 

三. unison常见问题处理

1. Fatal error: Warning: inconsistent state   ==>   Archive ***** on host   should be DELETED

[admin@VM_0_15_centos ~]$ unison -batch /data/test ssh://admin@111.198.29.223:2211//data/test
Contacting server...
Connected [//VM_0_15_centos//data/test -> //centos-A//data/test]
Looking for changes
Fatal error: Warning: inconsistent state.
The archive file is missing on some hosts.
For safety, the remaining copies should be deleted.
Archive arfab143f600338a088d5a48b8eb04b701 on host VM_0_15_centos is MISSING
Archive ar2a565bcf1cefb35d97b1813caeda9557 on host centos-A should be DELETED
Please delete archive files as appropriate and try again
or invoke Unison with -ignorearchives flag.

[root@centos-A data]# su - admin
[admin@centos-A ~]$ cd .unison/
[admin@centos-A .unison]$ ll
total 184
-rw------- 1 admin admin   1144 Mar 14 13:15 ar2a565bcf1cefb35d97b1813caeda9557
-rw------- 1 admin admin    581 Mar 12 14:15 ar8714267eb7e6ade26891aefe9bcfb48a
-rw------- 1 admin admin    677 Mar 13 16:00 ar9b59ffdaa0a611b441fd0fa73b15649e
-rw------- 1 admin admin    260 Mar 12 15:32 default.prf
-rw------- 1 admin admin     34 Mar 12 15:21 fp2a565bcf1cefb35d97b1813caeda9557
-rw------- 1 admin admin     34 Mar 12 14:23 fp8714267eb7e6ade26891aefe9bcfb48a
-rw------- 1 admin admin     34 Mar 13 16:00 fp9b59ffdaa0a611b441fd0fa73b15649e
-rw------- 1 admin admin 156303 Mar 14 13:15 unison.log
[admin@centos-A .unison]$ ll ar2a565bcf1cefb35d97b1813caeda9557
-rw------- 1 admin admin 1144 Mar 14 13:15 ar2a565bcf1cefb35d97b1813caeda9557
[admin@centos-A .unison]$ rm ar2a565bcf1cefb35d97b1813caeda9557

 2. Permission denied

[admin@centos-A test]$ unison
Contacting server...
Connected [//VM_0_15_centos//data/test -> //centos-A//data/test]
Looking for changes
Waiting for changes from server
Reconciling changes
props <-?-> props /
local : dir props changed modified on 2019-03-15 at 10:33:43 size 0 --rwxr-xr-x user=admin group=admin
VM_0_15_c... : dir props changed modified on 2019-03-14 at 19:18:58 size 0 --rwxr-xr-x user=0 group=0
new file ----> oo.txt
local : new file modified on 2019-03-15 at 10:33:43 size 0 --rw-rw-r-- user=admin group=admin
VM_0_15_c... : absent
Propagating updates
UNISON 2.48.4 started propagating changes at 10:36:25.31 on 15 Mar 2019
[CONFLICT] Skipping
properties changed on both sides
[BGN] Copying oo.txt from /data/test to //VM_0_15_centos//data/test
Failed: Error in processing a transfer instruction:
Permission denied [open(/data/test/.unison.oo.txt.fab143f600338a088d5a48b8eb04b701.unison.tmp)]
100% 00:00 ETAFailed [oo.txt]: Error in processing a transfer instruction:
Permission denied [open(/data/test/.unison.oo.txt.fab143f600338a088d5a48b8eb04b701.unison.tmp)]
UNISON 2.48.4 finished propagating changes at 10:36:25.34 on 15 Mar 2019
Saving synchronizer state
Synchronization incomplete at 10:36:25 (0 items transferred, 1 skipped, 1 failed)
skipped: (properties changed on both sides)
failed: oo.txt

解决方法 : 检查服务器需要同步的文件目录的属主权限是否正确. root用户的目录普通用户默认是没有权限的

四. 配合inotify可实时

Inotify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如删除、读、写和卸载操作等。您还可以跟踪活动的源头和目标等细节。

Inotify 是一个 Linux特性,它监控文件系统操作,比如读取、写入和创建。Inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多。

inotify是强大的, 细粒度的, 可异步的文件系统/目录 事件监控机制(软件)    内核2.6.13之后版本支持inotity

对文件或目录的 添加、删除,修改、移动 操作都可以通过 inotify监控

软件名称:  inotify-tools

1. 检查系统是否支持

[admin@admin test]$ uname -r
2.6.32-696.el6.x86_64
[admin@admin test]$ ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Mar 13 17:22 max_queued_events
-rw-r--r-- 1 root root 0 Mar 13 17:22 max_user_instances
-rw-r--r-- 1 root root 0 Mar 13 17:22 max_user_watches
[admin@admin test]$ ###显示上面这三个文件代表支持

在/proc/sys/fs/inotify日录下有三个文件,对inotify机制有一定的限制

max_user_watches   设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)

max_user_instances  设置每个用户可以运行的inotifywait或inotifywatch命令的进程数。

max_queued_events:设置inotify实例事件(event)队列可容纳的事件数量。

2. 安装 inotify-tools

[root@admin ~]# # yum install inotify-tools 
[root@admin ~]# rpm -qa |grep inotify
inotify-tools-3.14-1.el6.x86_64

 其实一共安装了2个命令. 即 inotifywait inotifywatch

  inotifywait :  在被监控的文件或目录上等待特定的文件系统事件( open , close, delete 等)发生, 执行后处于阻塞状态, 适合在脚本中使用

  inotifywatch : 收集被监视的文件系统使用度统计数据, 指文件系统事件发生的次数统计

 inotifywait参数

-r     --recursive      #递归查询目录

-q    --quiet            #打印很少的信息,仅仅打印监控事件的信息

-m   --monitor        #始终保持事件监听状态

--timefmt  <fmt>    #打印使用指定的输出类似格式字符串

-e                        #通过此参数可以指定需要监控的事件,如下所示:

 

moved_to            #有文件或目录被移动至这个目录。

create                #文件或目录被创建在当前目录

delete                #文件或目录被删除

close_write         #修改文件或目录的内容

-h,–help
输出帮助信息
@
排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile 
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-m, –monitor
接收到一个事情而不退出,无限期地执行。默认的行为是接收到一个事情后立即退出。
-d, –daemon
跟–monitor一样,除了是在后台运行,需要指定–outfile把事情输出到一个文件。也意味着使用了–syslog。
-o, –outfile 
输出事情到一个文件而不是标准输出。
-s, –syslog
输出错误信息到系统日志
-r, –recursive
监视一个目录下的所有子目录。
-q, –quiet
指定一次,不会输出详细信息,指定二次,除了致命错误,不会输出任何信息。
–exclude 
正则匹配需要排除的文件,大小写敏感。
–excludei 
正则匹配需要排除的文件,忽略大小写。
-t , –timeout 
设置超时时间,如果为0,则无限期地执行下去。
-e , –event 
指定监视的事件。
-c, –csv
输出csv格式。
–timefmt 
指定时间格式,用于–format选项中的%T格式。
–format 
指定输出格式。
%w 表示发生事件的目录
%f 表示发生事件的文件
%e 表示发生的事件
%Xe 事件以“X”分隔
%T 使用由–timefmt定义的时间格式
inotifywait参数

inotifywatch参数

参数:
-h, –help
输出帮助信息
-v, –verbose
输出详细信息
@
排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile 
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-z, –zero
输出表格的行和列,即使元素为空
–exclude 
正则匹配需要排除的文件,大小写敏感。
–excludei 
正则匹配需要排除的文件,忽略大小写。
-r, –recursive
监视一个目录下的所有子目录。
-t , –timeout 
设置超时时间
-e , –event 
只监听指定的事件。
-a , –ascending 
以指定事件升序排列。
-d , –descending 
以指定事件降序排列。
inotifywatch参数

 

3. 可监听的事件

access

文件读取

modify

文件更改。

attrib

文件属性更改,如权限,时间戳等。

close_write

以可写模式打开的文件被关闭,不代表此文件一定已经写入数据。

close_nowrite

以只读模式打开的文件被关闭。

close

文件被关闭,不管它是如何打开的。

open

文件打开。

moved_to

一个文件或目录移动到监听的目录,即使是在同一目录内移动,此事件也触发。

moved_from

一个文件或目录移出监听的目录,即使是在同一目录内移动,此事件也触发。

move

包括moved_to和 moved_from

move_self

文件或目录被移除,之后不再监听此文件或目录。

create

文件或目录创建

delete

文件或目录删除

delete_self

文件或目录移除,之后不再监听此文件或目录

unmount

文件系统取消挂载,之后不再监听此文件系统。

4. 数据实时复制

 监视目录变动后执行同步的脚本

[admin@VM_0_15_centos .unison]$ cat /script/inotify-unison.sh#!/bin/bash
##########################################
inotifywait -mrq  /data/test/ --format "%w%f"  -e create,delete,close_write,moved_to|while read line
  do
    echo `date +%F' '%T'  '%A`
    unison
    echo -e ' \n \n '
done

 为监视脚本写个简单服务

[root@VM_0_15_centos ~]# cat /etc/init.d/unison_inotify
#!/bin/bash
# intofitywait watch /data/test/
# unison ---  sync from /data/test to //remote//data/test

. /etc/rc.d/init.d/functions
use_username=admin
log_path=/home/$use_username/.unison/unison-diy.log
procID=`ps aux |grep inotify-unison.sh |grep -v grep|awk '{print $2}'`

start() {
        echo -n $"Starting unison_inotify... "
        su - $use_username -c "nohup  /script/inotify-unison.sh  >>$log_path 2>&1 &"
    RETVAL=$?
        [ $RETVAL = 0 ] && action
}

stop() {
    #echo  $"Stopping unison_inotify ... "
    kill $procID  >/dev/null 2>&1
    RETVAL=$?
    [ $RETVAL = 0 ] && echo  "Stopping unison_inotify...  `action`" || echo 'unison_inotify(PID) is not run'
}
status() {
    check_proc=`ps aux |grep inotify-unison.sh |grep -v grep|awk '{print $2}'|wc -l`    
    if [ $check_proc -ne 0 ]
      then
       echo 'unison_inotify is running'
    else
       echo 'unison_inotify is not run'
    fi
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  restart)
    stop
    start
    ;;
  *)
    echo $"Usage: $prog {start|stop|status}"
    RETVAL=2
esac

exit $RETVAL

[root@VM_0_15_centos ~]# 

服务脚本使用效果

5. inotify优缺点

优点:   监控文件系统事件变化, 通过同步工具实现实时数据同步.

缺点:

1.  并发如果大于200个文件 ( 10-100K ), 同步就会有延迟.

2. 待续...

 

posted @ 2019-03-08 11:08  mingetty  阅读(867)  评论(0编辑  收藏  举报