两台服务器同步数据
unison 是一款跨平台的文件同步对象,不仅支撑本地对本地同步,也支持通过SSH,RSH和Socket 等网络协议进行同步。
unison 支持双向同步,你可以同A同步到B ,也可以从B同步到A,这些都需要额外的设定。
Inotify一种强大的、细粒度的、异步文件系统监控机制,它满足各种各样的文件监控需要,可以监控文件系统的访问属性、读写属性、权限属性、删除创建、移动等操作,也就是可以监控文件发生的一切变化。
inotify-tools是一个C库和一组命令行的工作提供Linux下inotify的简单接口。
inotify-tools安装后会得到inotifywait
和inotifywatch
这两条命令:
- inotifywait命令可以用来收集有关文件访问信息,Linux发行版一般没有包括这个命令,需要安装inotify-tools,这个命令还需要将inotify支持编译入Linux内核,好在大多数Linux发行版都在内核中启用了inotify。
- inotifywatch命令用于收集关于被监视的文件系统的统计数据,包括每个 inotify 事件发生多少次。
开始之前需要检测系统内核是否支持inotify:
使用uname -r
命令检查Linux内核,如果低于2.6.13,就需要重新编译内核加入inotify的支持。
使用ll /proc/sys/fs/inotify
命令,是否有以下三条信息输出,如果没有表示不支持
/web1> ll /proc/sys/fs/inotify 总计 0 -rw-r--r-- 1 root root 0 07-26 12:44 max_queued_events -rw-r--r-- 1 root root 0 07-26 12:44 max_user_instances -rw-r--r-- 1 root root 0 07-26 12:44 max_user_watches
安装篇
下载ocaml组件并安装:
wget http://caml.inria.fr/pub/distrib/ocaml-4.02/ocaml-4.02.1.tar.gz
下载unison :
wget http://www.seas.upenn.edu/~bcpierce/unison//download/releases/beta/unison-2.48.1.tar.gz
下载inotify:
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
两台服务器都编译安装这三个源码包,在此只写在一台服务器上的编译安装的过程
安装ocaml组件:
tar zxvf ocaml-4.02.1.tar.gz; cd ocaml-4.02.1; ./configure; make world opt make install
安装inotify:
./configure --prefix=/usr/local/inotify && make && make install [root@localhost inotify-tools-3.14]# cd /usr/local/inotify/ ##修改PATH 环境变量: [root@localhost inotify]# echo "PATH=/usr/local/inotify/bin:$PATH" > /etc/profile.d/inotify.sh [root@localhost inotify]# source /etc/profile.d/inotify.sh ##添加库文件到系统识别的路径: [root@localhost inotify]# echo "/usr/local/inotify/lib" > /etc/ld.so.conf.d/inotify.conf [root@localhost inotify]# ldconfig -v | grep inotify /usr/local/inotify/lib: libinotifytools.so.0 -> libinotifytools.so.0.4.1 ##链接库文件到系统识别的路径: [root@localhost inotify]# ln -sv /usr/local/inotify/include/ /usr/include/inotify `/usr/include/inotify' -> `/usr/local/inotify/include/'
安装unison程序:
[root@localhost ocam]# cd /usr/src/unison/ [root@localhost unison]# yum -y install ctags-etags [root@localhost unison]# make UISTYLE=text [root@localhost unison]# make install mv /root/bin//unison /tmp/unison-29781 mv: 无法获取"/root/bin//unison" 的文件状态(stat): 没有那个文件或目录 make: [doinstall] 错误 1 (忽略) cp unison /root/bin/ cp: 无法创建普通文件"/root/bin/": 是一个目录 make: *** [doinstall] 错误 1 报错信息,依据提示操作:此错误就是要把unison 复制到/usr/local/bin下 cp /usr/src/unison/unison /usr/local/bin/ mkdir -p /root/bin/ //在次执行 make install mv /root/bin//unison /tmp/unison-29807 cp unison /root/bin/ cp unison /root/bin/unison
在服务器B 上的安装同上。
配置服务器A和B ssh互信关系
# ssh-keygen -t rsa [root@localhost ~]# scp ~/ .ssh/id_rsa.pub 10.1.204.16:/root/ ##在服务器B 上移动公钥并重命名 [root@localhost ~]# mv id_rsa.pub ./.ssh/authorized_keys ##公钥授权为600 [root@localhost ~]# chmod 600 .ssh/authorized_keys ## 服务器B 重启sshd服务 [root@localhost ~]# service sshd restart
测试两台服务器免密钥登陆
## 服务器A 登陆服务器B [root@localhost ~]# ssh root@10.1.204.16 Last login: Wed Nov 29 13:47:07 2017 from 10.1.204.15 [root@localhost ~]# exit logout Connection to 10.1.204.16 closed.
编辑unison 同步的脚本进行测试
A服务器(A-B):
#!/bin/bash ipB="10.1.204.16" srcA="/home/x/web1/" dstB="/home/x/web1/" /usr/local/inotify/bin/inotifywait -mrq -e create,delete,modify,move $srcA | while read line; do /usr/local/bin/unison -batch $srcA ssh://$ipB//$dstB echo -n "$line " >> /var/log/inotify.log echo `date | cut -d " " -f1-4` >> /var/log/inotify.log done
B服务器(B-A):
ipA="10.1.204.15" srcB="/home/x/web1" dstA="/home/x/web1" /usr/local/inotify/bin/inotifywait -mrq -e create,delete,modify,move $srcB | while read line; do /usr/local/bin/unison -batch $srcB ssh://$ipA/$dstA echo -n "$line " >> /var/log/inotify.log echo `date | cut -d " " -f1-4` >> /var/log/inotify.log done
测试webA webB 上传代码同步
A-B
启动webA脚本 [root@localhost scripts]# sh -x serA.sh 在webA上在开个终端,创建{1-5}.txt [root@localhost web1]# touch {1..5}.txt 在webB上查看:目标文件都已经同步过来 [root@localhost web1]# ls 1.txt 2.txt 3.txt 4.txt 5.txt
B-A
a .启动webB上的脚本 [root@localhost scripts]# sh -x serB.sh 在webB上创建{a..e}.txt, 在web1上查看 [root@localhost web1]# touch {a..e}.txt [root@localhost web1]# ls 1.txt 2.txt 3.txt 4.txt 5.txt a.txt b.txt c.txt d.txt e.txt 在webA上查看: 目标文件都已同步过来 [root@localhost web1]# ls 1.txt 2.txt 3.txt 4.txt 5.txt a.txt b.txt c.txt d.txt e.txt
模式匹配:
unison 工具支持排除指定目录功能,比如排除log目录和.log文件
如下参数 ignore/ignorenot, follow, sortfirst/sortlast, backup, merge 定义各自的匹配模式。 例如: ignore = pattern pattern 的语法格式
● Regex regexp 即常规表达式。
● Name name 路径的最后一部分与 “name" 匹配。可以使用通配符,见下面描述。
● Path path 全路径与 "path" 匹配。可以使用通配符,见下面描述。
以下通配符可以用在 Path 和 Name 中:
● ? 匹配除了 "/" 之外,任意单个字符;
● * 匹配除了 "/" 之外的任意字符;如果用在 "Name" 中,则不和以 "."开始的文件匹配,而用在 "Path" 中,可以和 "." 开始的向匹配。
● [xyz] 匹配 {x,y,z} 中任一字符;
● {a,bb,ccc} 匹配 a, bb, ccc 中任何一个;
示例:
● 忽略 CVS 目录以及以 .cmo 结尾的文件: ignore = Name {CVS,*.cmo}
● 忽略路径 a/b: ignore = Path a/b
● 忽略路径 */tmp。当 * 用在 Path 中,可以和以 "." 开始的文件、目录名匹配,如下面的和 ".foo/tmp" 匹配; ignore = Path */tmp
● 忽略 a/b/ 开始,结尾是 .ml 的文件。 ignore = Regex a/b/.*.ml
生产环境要求忽略log目录和.log文件
ignore=Name {log,*.log}
webA上创建log 日志文件 [root@localhost web1]# touch x.log webB上查询: x.log 日志文件没有同步过来,验证成功 [root@localhost web1]ls
[root@localhost scripts]# chmod +x serA.sh [root@localhost scripts]# ll 总用量 8 -rwxr-xr-x. 1 root root 406 11月 30 13:48 serA.sh [root@localhost scripts]# nohup ./serA.sh & [root@localhost scripts]# echo "/root/scripts/serA.sh" >> /etc/rc.local [root@localhost scripts]# cat /etc/rc.local #!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local /root/scripts/serA.sh
附录:
inotifywait命令使用
path=$1 /usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y/%H:%M' --format '%T %w %f' -e modify,delete,create,attrib $path
inotifywait命令参数
-m
是要持续监视变化。-r
使用递归形式监视目录。-q
减少冗余信息,只打印出需要的信息。-e
指定要监视的事件列表。--timefmt
是指定时间的输出格式。--format
指定文件变化的详细信息。
可监听的事件
事件 | 描述 |
---|---|
access | 访问,读取文件。 |
modify | 修改,文件内容被修改。 |
attrib | 属性,文件元数据被修改。 |
move | 移动,对文件进行移动操作。 |
create | 创建,生成新文件 |
open | 打开,对文件进行打开操作。 |
close | 关闭,对文件进行关闭操作。 |
delete | 删除,文件被删除。 |
/root/.unison/default.prf配置参数
# Unison preferences file root = /tmp/www.91town.xxx #本地文件夹 root = ssh://root@192.168.0.230//tmp/www.91town.xxx #远程文件夹 batch = true #表示全自动模式,接受并执行默认动作。 owner = true #表示保持同步的文件属主信息。 group = true #表示保持同步的文件属组信息。 perms = -1 #表示保持同步的文件读写权限。 #fastcheck = false fastcheck = true #true表示同步时通过文件的创建时间来比较两地文件;false表示同步时通过比较两地文件内容。 rsync = false #默认值是true,用于激活rsync传输模式。 sshargs = -C #使用ssh的压缩传输方式。 xferbycopying = true #优化传输参数,默认值为true。 confirmbigdel = false #默认值为true,表示当需要同步的两个目录有一个为空时,unison将停止。设置为false可以保证当需要同步的某个目录为空时,unison不会停止运转。 log = true #表示在终端输出运行信息。 logfile = /var/log/unison.log #指定同时输出写入log文件。 maxthreads = 300 #指定同步时最大线程数。 #repeat = 1 #表示间隔1秒后开始一次新的同步检查 #retry = 3 #指定失败重试次数 #path = www #同步指定的子目录及文件,而非整个目录。可以写多个path,如在下面再写一个path = wwwbak。 #ignore = Path WEB-INF/tmp #忽略/wwwroot下面的WEB-INF/tmp目录,即同步时不同步它。注意,这里是”Path”,而不是”path”。 force表示会以本地所指定文件夹为标准,将该目录同步到远端。这里需要注意,如果指定了force参数,那么Unison就变成了单项同步了,也就是说会以force指定的文件夹为准进行同步,类似与rsync force和prefer需要一起配置 -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 可以多次出现。 PS:Windows下的unison配置文件默认位于C:Documents and Settingscurrentuser.unison目录,默认的配置文件名是default.prf。
举例:
# Unison preferences file ignore=Name {log,*.log} batch=true force=/home/x/web1/ prefer = ssh://10.1.208.16///home/x/web1/ maxthreads=300 repeat = 60 retry = 3 owner = true group = true perms = -1 sshargs = -C log = true logfile = /home/x/unison.log