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