rsync(remote sync)是类unix系统中的一款远程数据同步工具,使用所谓的“rsync算法”来使本地和远程主机之间的文件达到同步(也可在同一主机内部实现数据同步),这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度很快。
rsync同步数据时,需要扫描所有文件后对比,进行差量传输,因此不适宜同步海量小文件,因为这个扫描对比的过程将会非常耗时。
一、rsync的特性
①可以镜像保存整个目录树或文件系统;
②较高的数据传输效率;
③可以借助于ssh实现安全数据传输;
④支持匿名传输;
二、rsync命令的工作模式
⑴shell模式,也称作本地模式,同一主机内实现数据同步
rsync [OPTION...] SRC... [DEST]
例:rsync -avz /etc/httpd/ /tmp/test
⑵远程shell模式,可以利用ssh协议承载其远程传输过程;
rsync [OPTION...] SRC... [USER@]HOST:DEST
rsync [OPTION...] [USER@]HOST:SRC... [DEST]
例:rsync -avz -e 'ssh -p 7788' tesla@192.168.30.10:/etc/fstab /tmp/test
⑶列表模式,仅列出源中的内容,-nv
⑷服务模式,此时rsync工作为守护进程,能接收客户端的数据同步请求;
①从服务端拉取数据(pull):
rsync [OPTION...] [USER@]HOST::SRC... [DEST] #守护进程模式中服务器的路径以模块名打头
rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
例:rsync -avz tom@192.168.30.20::tools/test.txt /tmp/
②向服务端推送数据(push):
rsync [OPTION...] SRC... [USER@]HOST::DEST
rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST
例:rsync -avz /mydata rsync://tom@192.168.30.20/tools/
注意:远程shell模式使用单冒号,守护进程模式使用双冒号
三、rsync命令的选项:
-n:同步测试,不执行真正的同步过程;
-v:详细输出模式
-q:静默模式
-c:checksum,开启校验功能
-r:递归复制 #源路径若为目录,需要指定该选项(或-a)
-a:归档,保留文件的原有属性;相当于-rptlgoD
-p:保留文件的权限
-t:保留文件的时间戳
-l:保留符号链接
-g:保留属组
-o:保留属主
-D:保留设备文件
-e ssh:使用ssh作为传输承载,更安全
如 -e 'ssh -p 2345'
-z:压缩后传输
--delete:删除那些DST中SRC没有的文件,此选项能使源和目标完全一致,常用于快速删除大量数据
--existing:仅仅更新那些已经存在于DST的文件
--exclude=PATTERN:指定排除不需要传输的文件模式
如 --exclude=a --exclude={b,c} --exclude={d..g} --exclude=*.txt
--exclude-from=FILE:排除FILE中指定模式的文件,FILE中的内容要使用相对路径
--password-file=FILE:从FILE中得到密码,仅能应用于rsync服务模式中
--bwlimit=KBPS #实际环境中应限制速率,以免导致巨大的CPU消耗
例:--bwlimit=100(不用带单位)
--progress:显示进度条
--stats:显示如何执行压缩和传输
说明:
①rsync命令中,如果源路径是目录,且其末尾有“/”,则会复制目录中的内容,而非目录本身;如果末尾没有“/”,则会同步目录本身及目录中的所有文件;目标路径末尾是否有“/”无关紧要;
②文件访问时间等属性、读写等权限、文件内容等有任何变动,都会被认为修改
③目标目录下如果文件比源目录还新,则不会同步
[root@node2 ~]# rpm -ql rsync
/etc/xinetd.d/rsync #rsync若工作于守护进程,可接受超级守护进程管理
/usr/bin/rsync
/usr/share/doc/rsync-3.0.6
/usr/share/doc/rsync-3.0.6/COPYING
/usr/share/doc/rsync-3.0.6/NEWS
/usr/share/doc/rsync-3.0.6/OLDNEWS
/usr/share/doc/rsync-3.0.6/README
/usr/share/doc/rsync-3.0.6/support
...
/usr/share/man/man5/rsyncd.conf.5.gz #可参考该文档创建配置文件
[root@node2 ~]# ls /etc/httpd
conf conf.d logs modules run ssl
[root@node2 ~]# rsync /etc/httpd/ /tmp/test
skipping directory . #源路径若为目录,需要指定-r或-a选项,否则不予同步
[root@node2 ~]# rsync -av /etc/httpd/ /tmp/test
sending incremental file list
./
logs -> ../../var/log/httpd
modules -> ../../usr/lib64/httpd/modules
run -> ../../var/run/httpd
conf.d/
conf.d/README
conf.d/php.conf
conf.d/ssl.conf
conf.d/welcome.conf
conf.d/welcome.conf.back
conf/
conf/.htpasswd
conf/httpd.conf
conf/magic
ssl/
ssl/httpd.crt
ssl/httpd.csr
ssl/httpd.key
sent 67856 bytes received 245 bytes 136202.00 bytes/sec
total size is 66998 speedup is 0.98
[root@node2 ~]# ls /tmp/test
conf conf.d logs modules run ssl
[root@node2 ~]# touch /etc/httpd/abc
[root@node2 ~]# rsync -av /etc/httpd/ /tmp/test
sending incremental file list
./
abc #只会复制变动的部分
sent 481 bytes received 37 bytes 1036.00 bytes/sec
total size is 66998 speedup is 129.34
[root@node2 ~]# rsync -av /etc/httpd /tmp/test #源目录不带/会连同复制目录本身
sending incremental file list
httpd/
httpd/abc
httpd/logs -> ../../var/log/httpd
httpd/modules -> ../../usr/lib64/httpd/modules
httpd/run -> ../../var/run/httpd
httpd/conf.d/
httpd/conf.d/README
...
sent 67924 bytes received 265 bytes 136378.00 bytes/sec
total size is 66998 speedup is 0.98
[root@node2 ~]# ls /tmp/test
abc conf conf.d httpd logs modules run ssl
[root@node2 ~]# mkdir /tmp/empty #创建一个空目录
[root@node2 ~]# rsync -av --delete /tmp/empty/ /tmp/test #这种用法可用于快速清除大量数据
sending incremental file list
./
deleting ssl/httpd.key
deleting ssl/httpd.csr
deleting ssl/httpd.crt
deleting ssl/
deleting httpd/ssl/httpd.key
...
total size is 0 speedup is 0.00
[root@node2 ~]# ls /tmp/test #test目录已被清空
[root@node2 ~]# rsync /etc/fstab root@192.168.30.10:/tmp/ceshi #远程shell模式
root@192.168.30.10's password:
[root@node2 ~]# rsync -a tesla@192.168.30.10:/etc/selinux/config /tmp/test
tesla@192.168.30.10's password:
[root@node2 ~]# ls /tmp/test
config
[root@node1 ~]# ls /tmp/ceshi
fstab
四、rsync的Client-Server模式:
1、rsync服务端
⑴为rsync提供配置文件
/etc/rsyncd.conf #修改该配置文件后无须重启守护进程,每一次客户端连接都会读取该文件
配置文件分两段:
全局配置段:一个
模块配置段:多个
配置示例:
# Global Settings
uid = rsync #以什么用户身份存取模块目录
gid = rsync
use chroot = no #chroot为yes时必须使用root身份
max connections = 10
timeout = 300 #该选项可以确保rsync服务器不会永远等待一个崩溃的客户端
strict modes = yes
pid file = /var/run/rsyncd.pid
[lock file = /var/run/rsyncd.lock]
log file = /var/log/rsyncd.log
log format = %t %a %m %f %b
motd file = /etc/rsyncd/rsyncd.motd #该文件定义客户端连接时所看到的信息,非必须
# Directory to be synced
[tools] #模块名
path = /data #需要做镜像的目录
comment = some important software #可给模块指定描述信息
ignore errors = yes
read only = no
write only = no
hosts allow = 172.16.0.0/16 #可以是ip、网段、可解析的主机名、域名
hosts deny = * #表示所有
list = false(或no) #当客户请求列出可以使用的模块列表时,该模块是否应该被列出
uid = root #进程以什么身份对该模块进行存取;若不指定,则继承全局配置段中的设定
gid = root
exclude = DIR1 DIR2 FILE1... #排除不要同步的文件或目录,多个文件或目录用空格隔开
⑵服务端可启用用户认证的功能
①在全局或模块配置段中添加:
auth users = USERNAME LIST
secrets file = /etc/rsyncd.passwd
说明:USERNAME LIST为以逗号分隔的在rsyncd.passwd中存在的用户名的列表
②创建用户密码文件/etc/rsyncd.passwd
格式:username:password
这里的用户名和密码与操作系统的用户名密码无关,可任意指定
此文件不能允许其它用户有访问权限(将其权限设置为600),且密码不能超过8个字符
⑶创建存取用户和模块目录
useradd -M -s /sbin/nologin rsync
mkdir -p /data
chown -R rsync.rsync /data
⑷启动服务
①当rsync服务器负载较低时,可交由超级守护进程xinetd管理,这也是默认方式
chkconfig rsync on(或编辑/etc/xinetd.d/rsync文件,将disable 改为 no)
service xinetd start #默认监听于873/tcp
②当rsync服务器负载较高时,可启动为独立守护进程
rsync --daemon [--config=FILE] [--port=PORT]
有时还需要在防火墙上开放端口:
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 873 -j ACCEPT
[root@node2 ~]# vim /etc/rsyncd.conf
# Global Settings
uid = nobody
gid = nobody
use chroot = no
max connections = 10
strict modes = yes
timeout = 300
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
# Directory to be synced
[tools]
path = /data
ignore errors = yes
read only = no
write only = no
hosts allow = 192.168.30.0/24
hosts deny = *
list = false
auth users = tom, jerry
secrets file = /etc/rsyncd.passwd
[root@node2 ~]# vim /etc/rsyncd.passwd #创建密码文件
tom:hello
jerry:linux
rose:titanic
[root@node2 ~]# chmod 600 /etc/rsyncd.passwd
[root@node2 ~]# service xinetd restart
Stopping xinetd: [ OK ]
Starting xinetd: [ OK ]
[root@node2 ~]# ss -tnl #873端口已监听
...
LISTEN 0 64 :::873
2、rsync客户端
⑴生成连接服务端需要的密码文件
echo "hello" >> /etc/rsync.passwd
chmod 600 /etc/rsync.passwd
⑵同步文件
推送:
rsync -avz /tmp/ tom@192.168.30.20::tools --password-file=/etc/rsync.passwd
rsync -avz /tmp/ rsync://tom@192.168.30.20/tools --password-file=/etc/rsync.passwd
拉取:
rsync -avz tom@192.168.30.20::tools /tmp/ --password-file=/etc/rsync.passwd
rsync -avz rsync://tom@192.168.30.20/tools /tmp/ --password-file=/etc/rsync.passwd
[root@node1 ~]# echo "hello" >> /etc/rsync.passwd
[root@node1 ~]# chmod 600 /etc/rsync.passwd
[root@node1 ~]# rsync -avz tom@192.168.30.20::tools/test.txt /tmp/ceshi --password-file=/etc/rsync.passwd #从rsync服务器拉取数据
...
[root@node1 ~]# ls /tmp/ceshi
test.txt
测试中遇到一个问题,客户端向服务器端推送数据不成功,检查发现配置文件的模块配置段中未指定uid,因此直接继承了全局配置段中的uid设定,而全局配置段中的uid = nobody,它对模块目录/data没有写入权限,从而造成客户端无法推送数据。
解决办法:修改模块目录属主属组
[root@node1 ~]# rsync -avz iptables.nat tom@192.168.30.20::tools/ -password-file=/etc/rsync.passwd #提示向服务器推送数据不成功
rsync: mkstemp ".iptables.nat.6elLqN" (in tools) failed: Permission denied (13)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1039) [sender=3.0.6]
[root@node2 ~]# ls -ld /data
drwxrwxr-x+ 2 root root 4096 Nov 24 22:17 /data
[root@node2 ~]# chown -R nobody.nobody /data
[root@node1 ~]# rsync -avz iptables.nat tom@192.168.30.20::tools/
...
[root@node2 ~]# ls /data
fstab iptables.nat test.txt
六、rsync+inotify 实现数据实时同步
rsync不能实时地去监测、同步数据,虽然它可以通过crontab(周期性任务计划)方式触发同步,但是两次触发动作之间必然会有时间差,这样就可能导致客户端和服务端数据不一致,无法在应用故障时完全的恢复数据。而rsync+inotify就能够很好的解决这个问题。
inotify是一种强大的、细粒度的、异步的文件系统事件监控机制,Linux内核从2.6.13开始引入,允许监控工具(如inotifywait)监控文件系统下文件的各种变化事件,如添加、删除、修改、移动,当有变动发生时,就触发rsync同步,从而解决数据同步的实时性问题。
查看系统是否支持inotify机制:
ls /proc/sys/fs/inotify/,若出现以下三个文件,则支持,否则不支持:
max_queued_events max_user_instances max_user_watches
数据源是主动同步的一方,而备份源是被动的一方,我们要在数据源上触发rsync同步操作,由此,应该将数据源作为rsync客户端,将备份源作为rsync服务器端。
1、rsync服务器端配置(略,见上方)
2、客户端配置
⑴安装软件包:
yum -y install inotify-tools #inotifywait由inotify-tools包提供
⑵提供密码文件:
vim /etc/rsync_client.passwd #只需要输入一个密码,就是打算用于连接rsync服务器的用户对应的密码
chmod 600 /etc/rsync_client.passwd
⑶编写同步脚本
vim /root/scripts/rsync.sh
chmod +x /root/scripts/rsync.sh
/root/scripts/rsync.sh &
echo "nohup /root/scripts/rsync.sh &" >> /etc/rc.local #让数据同步脚本随开机执行
3、inotifywait
用法:inotifywait [-hcmrq] [-e <event> ] [-t <seconds> ] [--format <fmt> ] [--timefmt <fmt> ] <file> [ ... ]
选项:
-m:监视
-r:递归监视
-q:减少冗余信息
-e/--event:要监视的事件列表;
可监视的事件:create,delete,modify,move,access,attrib(元数据被修改),open,close
-t seconds:过期时长,即超出该时长退出监视,缺省为0,表示无限期监视
--format:指定事件信息的输出格式
%w:发生事件的目录或文件
%f:发生事件的文件
%e:发生的事件
%T:使用由-timefmt定义的时间格式
--timefmt:指定时间格式,具体用法可man inotifywait
--exclude <pattern>:指定排除不需要监视的文件模式
--fromfile <file>:从file中读取要监视或排除监视的文件(或目录),一行一个,不能使用正则表达式,以@开头的表示排除监视
例:inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f %e' -e modify,delete,create,move,attrib /tmp/test
以下node1为客户端,node2为服务端:
[root@node1 ~]# yum -y install inotify-tools #来自于epel源
...
Installed:
inotify-tools.x86_64 0:3.14-1.el6
Complete!
[root@node1 ~]# rpm -ql inotify-tools
/usr/bin/inotifywait #文件系统监视工具
/usr/bin/inotifywatch #统计文件系统访问的次数
/usr/lib64/libinotifytools.so.0
/usr/lib64/libinotifytools.so.0.4.1
/usr/share/doc/inotify-tools-3.14
/usr/share/doc/inotify-tools-3.14/AUTHORS
/usr/share/doc/inotify-tools-3.14/COPYING
/usr/share/doc/inotify-tools-3.14/ChangeLog
/usr/share/doc/inotify-tools-3.14/NEWS
/usr/share/doc/inotify-tools-3.14/README
/usr/share/man/man1/inotifywait.1.gz
/usr/share/man/man1/inotifywatch.1.gz
[root@node1 ~]# vim /etc/rsync_client.passwd
hello
[root@node1 ~]# chmod 600 /etc/rsync_client.passwd
[root@node1 ~]# vim scripts/rsync.sh #创建数据同步脚本
#!/bin/bash
src=/tmp/test/
log_file=/var/log/rsync_client.log
server=192.168.30.20
user=tom
pwd_file=/etc/rsync_client.passwd
module=tools
inotify_fun(){
/usr/bin/inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f %e' \
-e modify,delete,create,move,attrib $src | while read file
do
/usr/bin/rsync -avz --delete --bwlimit=200 --password-file=${pwd_file} $src $user@$server::$module
done
}
inotify_fun >> ${log_file} 2>&1 &
[root@node1 ~]# chmod +x !$ #给脚本设置执行权限
chmod +x scripts/rsync.sh
echo "nohup /root/scripts/rsync.sh &" >> /etc/rc.local
[root@node1 ~]# bash -n scripts/rsync.sh #语法检查
[root@node1 ~]# scripts/rsync.sh &
[1] 6155
[root@node1 ~]# echo "nohup /root/scripts/rsync.sh &" >> /etc/rc.local
[root@node1 ~]# cp a.txt anaconda-ks.cfg /tmp/test
[root@node1 ~]# ls /tmp/test
anaconda-ks.cfg a.txt tesla.txt
[root@node2 ~]# ls /data
anaconda-ks.cfg a.txt tesla.txt
[root@node1 ~]# rm -f /tmp/test/a.txt
[root@node2 ~]# ls /data
anaconda-ks.cfg tesla.txt