多台服务器间的文件实时同步问题,解决方案:rsync+inotify
## Inotify 工具
Inotify ,它是一个内核用于通知用户空间程序文件系统变化的机制。众所周知, Linux 桌面系统与 MAC 或 Windows 相比有许多不如人意的地方,为了改善这种状况,开源社区提出用户态需要内核提供一些机制,以便用户态能够及时地得知内核或底层硬件设备发生了什么,从而能够更好地管理设备,给用户提供更好的服务,如 hotplug 、 udev 和 inotify 就是这种需求催生的。Hotplug 是一种内核向用户态应用通报关于热插拔设备一些事件发生的机制,桌面系统能够利用它对设备进行有效的管理, udev 动态地维护 /dev 下的设备文件, inotify 是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户态得知,该机制是著名的桌面搜索引擎项目 beagle 引入的,并在 Gamin 等项目中被应用。
## rsync 工具
它是类 unix 系统下的数据镜像备份工具,实现远程同步 remote sync ,它的特性如下:
(1) ,可以镜像保存整个目录树和文件系统。
(2) ,可以很容易做到保持原来文件的权限、时间、软硬链接等等。
(3) ,无须特殊权限即可安装。
(4) ,快速:第一次同步时 rsync 会复制全部内容,但在下一次只传输修改过的文件。 rsync 在传输数据的过程中可以实行压缩及解压缩操作,因此可以使用更少的带宽。
(5) ,安全:可以使用 scp 、 ssh 等方式来传输文件,当然也可以通过直接的 socket 连接。
(6) ,支持匿名传输,以方便进行网站镜象。
## 环境部署
1、下载所需的安装包:
a、rsync下载路径:http://rsync.samba.org/ftp/rsync/src/rsync-3.0.9.tar.gz/
b、inotify下载路径:http://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
先把两个包放在/usr/src/下。
2、第一台服务器(192.168.1.100)配置(不分主次):
a、安装rsync:
[root@nginx ~]# cd /usr/src/ [root@nginx src]# tar zxvf rsync-3.0.9.tar.gz [root@nginx src]# cd rsync-3.0.9 [root@nginx rsync-3.0.9]# ./configure --prefix=/usr/local/rsync [root@nginx rsync-3.0.9]# make [root@nginx rsync-3.0.9]# make install
b、创建密码认证文件:
[root@nginx rsync-3.0.9]# cd /usr/local/rsync/ [root@nginx rsync-3.0.9]# vim rsync1.passwd nginxpasspd # 密码 nginx:nginxpasswd # 用户名:密码
c、给密码文件赋予600权限:
[root@nginx rsync]# chmod 600 rsync1.passwd
d、安装inotify:
[root@nginx rsync]# cd /usr/src/ [root@nginx src]# tar zxvf inotify-tools-3.14.tar.gz [root@nginx src]# cd inotify-tools-3.14 [root@nginx inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify [root@nginx inotify-tools-3.14]# make [root@nginx inotify-tools-3.14]# make install
e、创建监控脚本:
#!/bin/bash host=192.168.1.101 src=/root/test/ des=web user=nginx /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src | while read files do /usr/bin/rsync -vzrtopg --delete --progress --password-file=/usr/local/rsync/rsync1.passwd $src $user@$host::$des echo "${files} was rsynced" >>/tmp/rsync.log 2>&1 done
注意:host为第二台服务器IP,src为要监控的路径,web是认证模块名称,最后把监控脚本命名为rsync1.sh放在要监控的路径下。此处应是/root/test/
f、给监控脚本赋予764权限:
[root@nginx tmp]# chmod 764 rsync1.sh
g、创建rsync配置文件:
uid = root gid = root use chroot = no max connections = 10 strict modes = yes pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log [web] path = /root/test/ comment = web file ignore errors read only = no write only = no hosts allow = 192.168.1.101 hosts deny = * list = false uid = root gid = root auth users = nginx secrets file = /usr/local/rsync/rsync1.passwd
该配置文件是用来接收另一台服务器的文件。其中web是server服务端(90服务器)的认证模块名称,需要与90服务器里的一致。把配置文件命名为rsync1.conf,放到/usr/local/rsync/目录里
h、启动该配置文件
[root@nginx-backup rsync]# /usr/local/rsync/bin/rsync --daemon --config=/usr/local/rsync/rsync1.conf
需要开机启动的话:
[root@nginx-backup rsync]# echo "/usr/local/rsync/bin/rsync --daemon --config=/usr/local/rsync/rsync1.conf" >> /etc/rc.local
3、第二台服务器(192.168.1.101)配置(不分主次):
a、安装rsync:
[root@nginx ~]# cd /usr/src/ [root@nginx src]# tar zxvf rsync-3.0.9.tar.gz [root@nginx src]# cd rsync-3.0.9 [root@nginx rsync-3.0.9]# ./configure --prefix=/usr/local/rsync [root@nginx rsync-3.0.9]# make [root@nginx rsync-3.0.9]# make install
b、创建密码认证文件:
[root@nginx rsync-3.0.9]# cd /usr/local/rsync/ [root@nginx rsync-3.0.9]# vim rsync2.passwd nginxpasspd # 密码 nginx:nginxpasswd # 用户名:密码
c、给密码文件赋予600权限:
[root@nginx rsync]# chmod 600 rsync2.passwd
d、安装inotify:
[root@nginx rsync]# cd /usr/src/ [root@nginx src]# tar zxvf inotify-tools-3.14.tar.gz [root@nginx src]# cd inotify-tools-3.14 [root@nginx inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify [root@nginx inotify-tools-3.14]# make [root@nginx inotify-tools-3.14]# make install
e、创建监控脚本:
#!/bin/bash host=192.168.1.100 src=/root/test/ des=web user=nginx /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src | while read files do /usr/bin/rsync -vzrtopg --delete --progress --password-file=/usr/local/rsync/rsync2.passwd $src $user@$host::$des echo "${files} was rsynced" >>/tmp/rsync.log 2>&1 done
注意:host为第一台服务器IP,src为要监控的路径,web是认证模块名称,最后把监控脚本命名为rsync2.sh放在要监控的路径下。此处应是/root/test/
f、给监控脚本赋予764权限:
[root@nginx tmp]# chmod 764 rsync2.sh
g、创建rsync配置文件:
uid = root gid = root use chroot = no max connections = 10 strict modes = yes pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log [web] path = /root/test/ comment = web file ignore errors read only = no write only = no hosts allow = 192.168.1.100 hosts deny = * list = false uid = root gid = root auth users = nginx secrets file = /usr/local/rsync/rsync2.passwd
该配置文件是用来接收另一台服务器的文件。其中web是server服务端(90服务器)的认证模块名称,需要与90服务器里的一致。把配置文件命名为rsync2.conf,放到/usr/local/rsync/目录里
h、启动该配置文件
[root@nginx-backup rsync]# /usr/local/rsync/bin/rsync --daemon --config=/usr/local/rsync/rsync2.conf
需要开机启动的话:
[root@nginx-backup rsync]# echo "/usr/local/rsync/bin/rsync --daemon --config=/usr/local/rsync/rsync2.conf" >> /etc/rc.local
4、最后启动两台服务器的监控脚本:
a、在90服务器:
[root@nginx tmp]# sh /root/test/rsync1.sh &
需要开机启动的话:
[root@nginx tmp]# echo "/root/test/rsync1.sh" >> /etc/rc.local
b、在89服务器:
[root@nginx tmp]# sh /root/test/rsync2.sh &
需要开机启动的话:
[root@nginx tmp]# echo "/root/test/rsync2.sh" >> /etc/rc.local
补充:
1. 检测安装命令
[root@localhost ~]# rsync -h rsync version 3.0.6 protocol version 30 Copyright (C) 1996-2009 by Andrew Tridgell, Wayne Davison, and others. Web site: http://rsync.samba.org/
看来已经安装好,命令可以直接使用。
2.启动后,查看后台运行的进程:
[root@localhost inotify-tools-3.14]# ps -eaf|grep ino root 17842 17594 0 20:15 pts/1 00:00:00 sh /usr/local/inotify-tools-3.14/inotify_web.sh root 17843 17842 0 20:15 pts/1 00:00:00 /usr/local/inotify-tools-3.14/bin/inotifywait -mrq --timefmt %d/%m/%y/%H:%M --format %T%w%f -e close_write,move,delete,create /usr/local/nginx/web root 17844 17842 0 20:15 pts/1 00:00:00 sh /usr/local/inotify-tools-3.14/inotify_web.sh root 17872 17594 0 20:16 pts/1 00:00:00 tail -f /tmp/inotify_rsync.log nginx 17882 17848 0 20:18 pts/0 00:00:00 grep ino
## Rsync常见问题解决方法
附录一:Rsync常见问题解决方法
问题一:
@ERROR: chroot failed
rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver= 3.0.3 ]
原因:
服务器端的目录不存在或无权限。创建目录并修正权限可解决问题。
问题二:
@ERROR: auth failed on module tee
rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver= 3.0.3 ]
原因:
服务器端该模块(tee)需要验证用户名密码,但客户端没有提供正确的用户名密码,认证失败。提供正确的用户名密码解决此问题。
问题三:
@ERROR: Unknown module ‘tee_nonexists’
rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver= 3.0.3 ]
原因:
服务器不存在指定模块。提供正确的模块名或在服务器端修改成你要的模块以解决问题。
问题四:
password file must not be other-accessible
continuing without password file
Password:
原因:
这是因为rsyncd.pwd rsyncd.secrets的权限不对,应该设置为600。如:chmod 600 rsyncd.pwd
问题五:
rsync: failed to connect to 218.107.243.2: No route to host (113)
rsync error: error in socket IO (code 10) at clientserver.c(104) [receiver= 2.6.9 ]
原因:
对方没开机、防火墙阻挡、通过的网络上有防火墙阻挡,都有可能。关闭防火墙,其实就是把tcp udp的873端口打开。
实施方案:
1、防火墙的启动与停止
service iptables start / stop
2、允许rsync通过防火墙
为防重启将规则清除,我将规则直接加到规则配置文件里边了(/etc/sysconfig/iptables),如下:
-A INPUT -p tcp -s X.X.X.X –dport 873 -j ACCEPT
注意,这条规则要加在REJECT规则前。
加好后,重启下 iptables(# service iptables restart)。
问题六:
rsync error: error starting client-server protocol (code 5) at main.c(1524) [Receiver= 3.0.7 ]
原因:
/etc/rsyncd.conf配置文件内容有错误。请正确核对配置文件。
问题七:
rsync: chown “” failed: Invalid argument (22)
原因:
权限无法复制。去掉同步权限的参数即可。(这种情况多见于Linux向Windows的时候)
问题八:Log日志里面写name lookup failed for 192.168.1.136: Name or service not known
问题是在需要在服务端这台机上上的/etc/hosts里面添加客户端机的ip和机器名,如果有配DNS的话,那就不会有这样的问题了。
/etc/hosts下设置一下你的IP 要不然每次服务器都会解释你的ip地址寻找一个域名,所以会拖慢时间。如果你不是固定IP,那就只能忍了。
问题九:Log日志里面写params.c:Parameter() – Ignoring badly formed line in configuration file: ignore errors
如果出现下面的错误,把ignore errors注释掉即可。网上有很多人问,因为很多人的配置文件里都写了这个忽略错误,结果反而会产生一个错误提示。不过倒不影响同步。不管它也行,可以去掉配置文件中的ignore errors。
附录二:rsyncd.onf文件注释
全局参数
uid = root//运行RSYNC守护进程的用户
gid = root//运行RSYNC守护进程的组
use chroot = no //不使用chroot
max connections = 4 // 最大连接数为4
strict modes =yes//是否检查口令文件的权限
port = 873//默认端口873
模块参数
[backup] //这里是认证的模块名,在client端需要指定 path = /home/backup///需要做镜像的目录,不可缺少! comment = This is a test //这个模块的注释信息 ignore errors//可以忽略一些无关的IO错误 read only = yes// 只读 list = no //不允许列文件 auth users = hening //认证的用户名,如果没有这行则表明是匿名,此用户与系统无关 secrets file = /etc/rsync.pas //密码和用户名对比表,密码文件自己生成 hosts allow = 192.168.1.1, 10.10.10 .10//允许主机 hosts deny = 0.0.0 .0/0 //禁止主机 #transfer logging = yes
注释:下面这些绿色文件是安装完RSYNC服务后自动生成的文件
pid file = /var/run/rsyncd.pid//pid文件的存放位置
lock file = /var/run/rsync.lock //锁文件的存放位置
log file = /var/log/rsyncd.log//日志记录文件的存放位置