原文:https://segmentfault.com/a/1190000002427568html
1. rsynclinux
1.1 什么是rsyncnginx
rsync是一个远程数据同步工具,可经过LAN/WAN快速同步多台主机间的文件。它使用所谓的“Rsync演算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不一样部分,而不是每次都整份传送,所以速度至关快。因此一般能够做为备份工具来使用。正则表达式
运行Rsync server的机器也叫backup server,一个Rsync server可同时备份多个client的数据;也能够多个Rsync server备份一个client的数据。Rsync能够搭配ssh甚至使用daemon模式。Rsync server会打开一个873的服务通道(port),等待对方rsync链接。链接时,Rsync server会检查口令是否相符,若经过口令查核,则能够开始进行文件传输。第一次连通完成时,会把整份文件传输一次,下一次就只传送二个文件之间不一样的部份。算法
基本特色:shell
命令语法:
rsync的命令格式能够为如下六种:
rsync [OPTION]… SRC DEST
rsync [OPTION]… SRC [USER@]HOST:DEST
rsync [OPTION]… [USER@]HOST:SRC DEST
rsync [OPTION]… [USER@]HOST::SRC DEST
rsync [OPTION]… SRC [USER@]HOST::DEST
rsync [OPTION]… rsync://[USER@]HOST[:PORT]/SRC [DEST]segmentfault
对应于以上六种命令格式,咱们能够总结rsync有2种不一样的工做模式:安全
rsync --daemon
使用独立进程的方式,或者经过xinetd超级进程来管理rsync后台进程。当rsync做为daemon运行时,它须要一个用户身份。若是你但愿启用chroot,则必须以root的身份来运行daemon,监听端口,或设定文件属主;若是不启用chroot,也能够不使用root用户来运行daemon,但该用户必须对相应的模块拥有读写数据、日志和lock file的权限。当rsync以daemon模式运行时,它还须要一个配置文件——rsyncd.conf。修改这个配置后没必要重启rsync daemon,由于每一次的client链接都会去从新读取该文件。bash
咱们通常把DEST远程服务器端成为rsync Server,运行rsync命令的一端SRC称为Client。服务器
安装:
rsync在CentOS6上默认已经安装,若是没有则可使用yum install rsync -y
,服务端和客户端是同一个安装包。
# rsync -h
关于rsync
命令的诸多选项说明,见另一篇文章rsync与inotifywait命令和配置选项说明。
# rsync -auvrtzopgP --progress /root/ /tmp/rsync_bak/
会看到从/root/
传输文件到/tmp/rsync_bak/
的列表和速率,再运行一次会看到sending incremental file list下没有复制的内容,能够在/root/下touch
某一个文件再运行看到只同步了修改过的文件。
上面须要考虑如下问题:
--delete
选项在服务器间rsync传输文件,须要有一个是开着rsync的服务,而这一服务须要两个配置文件,说明当前运行的用户名和用户组,这个用户名和用户组在改变文件权限和相关内容的时候有用,不然有时候会出现提示权限问题。配置文件也说明了模块、模块化管理服务的安全性,每一个模块的名称都是本身定义的,能够添加用户名密码验证,也能够验证IP,设置目录是否可写等,不一样模块用于同步不一样需求的目录。
** /etc/rsyncd.conf: **
#2014-12-11 by Sean uid=root gid=root use chroot=no max connections=10 timeout=600 strict modes=yes port=873 pid file=/var/run/rsyncd.pid lock file=/var/run/rsyncd.lock log file=/var/log/rsyncd.log [module_test] path=/tmp/rsync_bak2 comment=rsync test logs auth users=sean uid=sean gid=sean secrets file=/etc/rsyncd.secrets read only=no list=no hosts allow=172.29.88.204 hosts deny=0.0.0.0/32
这里配置socket方式传输文件,端口873,[module_test]开始定义一个模块,指定要同步的目录(接收)path,受权用户,密码文件,容许哪台服务器IP同步(发送)等。关于配置文件中选项的详细说明依然参考rsync与inotifywait命令和配置选项说明。
经测试,上述配置文件每行后面不能使用#
来来注释
** /etc/rsyncd.secrets: **
sean:passw0rd
一行一个用户,用户名:密码。请注意这里的用户名和密码与操做系统的用户名密码无关,能够随意指定,与/etc/rsyncd.conf
中的auth users
对应。
修改权限:chmod 600 /etc/rsyncd.d/rsync_server.pwd
。
修改/etc/xinetd.d/rsync
文件,disable 改成 no
# default: off # description: The rsync server is a good addition to an ftp server, as it \ # allows crc checksumming etc. service rsync { disable = no flags = IPv6 socket_type = stream wait = no user = root server = /usr/bin/rsync server_args = --daemon log_on_failure += USERID }
执行service xinetd restart
会一块儿重启rsync后台进程,默认使用配置文件/etc/rsyncd.conf
。也可使用/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
。
为了以防rsync写入过多的无用日志到/var/log/message
(容易塞满从而错太重要的信息),建议注释掉/etc/xinetd.conf
的success:
# log_on_success = PID HOST DURATION EXIT
若是使用了防火墙,要添加容许IP到873端口的规则。
# iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 873 -j ACCEPT # iptables -L 查看一下防火墙是否是打开了 873端口 # netstat -anp|grep 873
建议关闭selinux
,可能会因为强访问控制致使同步报错。
单向同步时,客户端只须要一个包含密码的文件。
/etc/rsync_client.pwd:
passw0rd
chmod 600 /etc/rsync_client.pwd
命令:
将本地/root/
目录同步到远程172.29.88.223的/tmp/rsync_bak2目录(module_test指定):
/usr/bin/rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd /root/ sean@172.29.88.223::module_test
固然你也能够将远程的/tmp/rsync_bak2目录同步到本地目录/root/tmp:
/usr/bin/rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd sean@172.29.88.223::module_test /root/
从上面两个命令能够看到,其实这里的服务器与客户端的概念是很模糊的,rsync daemon都运行在远程172.29.88.223上,第一条命令是本地主动推送目录到远程,远程服务器是用来备份的;第二条命令是本地主动向远程索取文件,本地服务器用来备份,也能够认为是本地服务器恢复的一个过程。
与传统的cp、tar备份方式相比,rsync具备安全性高、备份迅速、支持增量备份等优势,经过rsync能够解决对实时性要求不高的数据备份需求,例如按期的备份文件服务器数据到远端服务器,对本地磁盘按期作数据镜像等。
随着应用系统规模的不断扩大,对数据的安全性和可靠性也提出的更好的要求,rsync在高端业务系统中也逐渐暴露出了不少不足,首先,rsync同步数据时,须要扫描全部文件后进行比对,进行差量传输。若是文件数量达到了百万甚至千万量级,扫描全部文件将是很是耗时的。并且正在发生变化的每每是其中不多的一部分,这是很是低效的方式。其次,rsync不能实时的去监测、同步数据,虽然它能够经过crontab方式进行触发同步,可是两次触发动做必定会有时间差,这样就致使了服务端和客户端数据可能出现不一致,没法在应用故障时彻底的恢复数据。基于以上缘由,rsync+inotify组合出现了!
inotify是一种强大的、细粒度的、异步的文件系统事件监控机制,Linux内核从2.6.13开始引入,容许监控程序打开一个独立文件描述符,并针对事件集监控一个或者多个文件,例如打开、关闭、移动/重命名、删除、建立或者改变属性。
CentOS6天然已经支持:
使用ll /proc/sys/fs/inotify
命令,是否有如下三条信息输出,若是没有表示不支持。
total 0
-rw-r--r-- 1 root root 0 Dec 11 15:23 max_queued_events -rw-r--r-- 1 root root 0 Dec 11 15:23 max_user_instances -rw-r--r-- 1 root root 0 Dec 11 15:23 max_user_watches
/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可监控的最大目录数量。若是监控的文件数目巨大,须要根据状况,适当增长此值的大小。inotify-tools:
inotify-tools是为linux下inotify文件监控工具提供的一套C的开发接口库函数,同时还提供了一系列的命令行工具,这些工具能够用来监控文件系统的事件。 inotify-tools是用c编写的,除了要求内核支持inotify外,不依赖于其余。inotify-tools提供两种工具,一是inotifywait
,它是用来监控文件或目录的变化,二是inotifywatch
,它是用来统计文件系统访问的次数。
下载inotify-tools-3.14-1.el6.x86_64.rpm,经过rpm包安装:
# rpm -ivh /apps/crm/soft_src/inotify-tools-3.14-1.el6.x86_64.rpm warning: /apps/crm/soft_src/inotify-tools-3.14-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 4026433f: NOKEY Preparing... ########################################### [100%] 1:inotify-tools ########################################### [100%] # rpm -qa|grep inotify inotify-tools-3.14-1.el5.x86_64
监控/root/tmp目录文件的变化:
/usr/bin/inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f' \ -e modify,delete,create,move,attrib /root/tmp/
上面的命令表示,持续监听/root/tmp
目录及其子目录的文件变化,监听事件包括文件被修改、删除、建立、移动、属性更改,显示到屏幕。执行完上面的命令后,在/root/tmp
下建立或修改文件都会有信息输出:
2014/12/11-15:40:04 /root/tmp/ new.txt 2014/12/11-15:40:22 /root/tmp/ .new.txt.swp 2014/12/11-15:40:22 /root/tmp/ .new.txt.swx 2014/12/11-15:40:22 /root/tmp/ .new.txt.swx 2014/12/11-15:40:22 /root/tmp/ .new.txt.swp 2014/12/11-15:40:22 /root/tmp/ .new.txt.swp 2014/12/11-15:40:23 /root/tmp/ .new.txt.swp 2014/12/11-15:40:31 /root/tmp/ .new.txt.swp 2014/12/11-15:40:32 /root/tmp/ 4913 2014/12/11-15:40:32 /root/tmp/ 4913 2014/12/11-15:40:32 /root/tmp/ 4913 2014/12/11-15:40:32 /root/tmp/ new.txt 2014/12/11-15:40:32 /root/tmp/ new.txt~ 2014/12/11-15:40:32 /root/tmp/ new.txt ...
这一步的核心其实就是在客户端建立一个脚本rsync.sh
,适用inotifywait
监控本地目录的变化,触发rsync
将变化的文件传输到远程备份服务器上。为了更接近实战,咱们要求一部分子目录不一样步,如/root/tmp/log
和临时文件。
排除不须要同步的文件或目录有两种作法,第一种是inotify监控整个目录,在rsync中加入排除选项,简单;第二种是inotify排除部分不监控的目录,同时rsync中也要加入排除选项,能够减小没必要要的网络带宽和CPU消耗。咱们选择第二种。
这个操做在客户端进行,假设/tmp/src/mail/2014/
以及/tmp/src/mail/2015/cache/
目录下的全部文件不用同步,因此不须要监控,/tmp/src/
下的其余文件和目录都同步。(其实对于打开的临时文件,能够不监听modify
时间而改为监听close_write
)
inotifywait排除监控目录有--exclude <pattern>
和--fromfile <file>
两种格式,而且能够同时使用,但主要前者能够用正则,然后者只能是具体的目录或文件。
# vi /etc/inotify_exclude.lst: /tmp/src/pdf @/tmp/src/2014
使用fromfile
格式只能用绝对路径,不能使用诸如*
正则表达式去匹配,@
表示排除。
若是要排除的格式比较复杂,必须使用正则,那只能在inotifywait
中加入选项,如--exclude '(.*/*\.log|.*/*\.swp)$|^/tmp/src/mail/(2014|201.*/cache.*)'
,表示排除/tmp/src/mail/如下的2014目录,和全部201*目录下的带cache的文件或目录,以及/tmp/src目录下全部的以.log或.swp结尾的文件。
使用inotifywait排除监控目录的状况下,必须同时使用rsync排除对应的目录,不然只要有触发同步操做,必然会致使不应同步的目录也会同步。与inotifywait相似,rsync的同步也有--exclude
和--exclude-from
两种写法。
我的仍是习惯将要排除同步的目录卸载单独的文件列表里,便于管理。使用--include-from=FILE
时,排除文件列表用绝对路径,但FILE里面的内容请用相对路径,如:/etc/rsyncd.d/rsync_exclude.lst
:
mail/2014/ mail/201*/201*/201*/.??* mail??* src/*.html* src/js/ src/ext3/ src/2014/20140[1-9]/ src/201*/201*/201*/.??* membermail/ membermail??* membermail/201*/201*/201*/.??*
排除同步的内容包括,mail下的2014目录,相似2015/201501/20150101/下的临时或隐藏文件,等。
rsync.sh
下面是一个完整的同步脚本,请根据须要进行裁剪,rsync.sh
:
#rsync auto sync script with inotify #2014-12-11 Sean #variables current_date=$(date +%Y%m%d_%H%M%S) source_path=/tmp/src/ log_file=/var/log/rsync_client.log #rsync rsync_server=172.29.88.223 rsync_user=sean rsync_pwd=/etc/rsync_client.pwd rsync_module=module_test INOTIFY_EXCLUDE='(.*/*\.log|.*/*\.swp)$|^/tmp/src/mail/(2014|20.*/.*che.*)' RSYNC_EXCLUDE='/etc/rsyncd.d/rsync_exclude.lst' #rsync client pwd check if [ ! -e ${rsync_pwd} ];then echo -e "rsync client passwod file ${rsync_pwd} does not exist!" exit 0 fi #inotify_function inotify_fun(){ /usr/bin/inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f' \ --exclude ${INOTIFY_EXCLUDE} -e modify,delete,create,move,attrib ${source_path} \ | while read file do /usr/bin/rsync -auvrtzopgP --exclude-from=${RSYNC_EXCLUDE} --progress --bwlimit=200 --password-file=${rsync_pwd} ${source_path} ${rsync_user}@${rsync_server}::${rsync_module} done } #inotify log inotify_fun >> ${log_file} 2>&1 &
--bwlimit=200
用于限制传输速率最大200kb,由于在实际应用中发现若是不作速率限制,会致使巨大的CPU消耗。
在客户端运行脚本# ./rsync.sh
便可实时同步目录。
其余功能:双向同步、sersync2实时同步多远程服务器