@cdmonkey
2016-05-05T13:52:43.000000Z
字数 10850
阅读 1156
网络服务
它是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。它当前由rsync.samba.org维护,是可以用来取代rcp
的工具。它使用所谓的“Rsync演算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。运行“Rsync server(服务器端)”的机器也叫备份服务器,一个服务器端可同时备份多个客户端的数据;也可以多个服务器端备份一个客户端的数据(如图所示)。
Rsync可以实现全量及增量的本地或远程数据镜像同步备份。rsync通常用于文件的异地备份,可以达到类似“镜像备份”的功能。它是把一个文档划分成多个块进行扫描对比,所以可以进行差异同步,效率高速度也快。并且备份文件能够保留源文件的权限、属主、属组、时间等属性。
Rsync最早是想要取代rcp这个指令的,因为rsync不但传输的速度快,而且在传输时,通过其独特的“quick check”算法,可以对比本地端与远程主机欲复制的文件内容(还可以根据权限、时间戳等属性)的变化,而仅复制两端之间有差异的文件而已,所以传输的时间就相对降低很多。
Rsync在进行数据传输时默认是不加密的。rsync还可以删除文件,相当于rm指令。在同步时依据其特有的算法的,可以依据大小、属性的变化来决定是否同步数据,甚至于可以实现只同步一个文件内有变化的内容部分。
Rsync可以搭配SSH甚至使用daemon模式。Rsync服务器端会打开一个873端口的服务通道,等待对方进行连接。连接时,服务器端会检查口令是否相符,若通过口令查核,则可以开始进行文件传输。第一次连通完成时,会把整份文件传输一次,下一次就只传送二个文件之间不同的部份。
因此,rsync指令可以通过三种方式来工作:
第三种工作方式是最重要的工作方式。其实上述三种工作模式的差异在于有没有冒号(:)而已:
本地传输不需要冒号。
通过SSH传输时,需要使用一个冒号。
而如果是通过rsync daemon的话,就需要两个冒号(::)了。
对应于三种工作模式,其指令的书写也分为三种方式,但都遵循基本的模式,如图所示:
Local: rsync [选项] SRC [DEST]
Access via remote shell:
Pull: rsync [选项] [-e ssh] [user@]host:SRC [DEST]
Push: rsync [选项] SRC [-e ssh] [user@]host:DEST
书写格式二:使用一个远程Shell 程序(如rsh、ssh)来实现远程主机之间的数据同步:
拉取:当“源”地址路径包含单个冒号(
:
)分隔符时启动该模式。
推送:当“目标”路径地址包含单个冒号(:
)分隔符时启动该模式。
Access via rsync daemon:
Pull: rsync [选项] [user@]host::SRC [DEST]
rsync [选项] rsync://[user@]host[:PORT]/SRC [DEST]
Push: rsync [选项] SRC [user@]host::DEST
rsync [选项] SRC rsync://[user@]host[:PORT]/DEST
书写格式三:实现本地客户端与远程服务器端的数据同步:
拉取:当“源”路径信息包含双引号(
::
)分隔符时启动该模式。
推送:当“目标”路径信息包含双引号(::
)分隔符时启动该模式。
选项 | 长选项 | 说明 |
---|---|---|
-a ... |
--archive |
相当于-rtopgDl ,是最为常用的选项。 |
-b |
--backup |
创建备份,也就是对于目的端已经存在有同样的文件名时,将老的文件重新命名。可以使用--suffix 选项来指定不同的备份文件前缀。 |
--backup-dir |
[--backup-dir=DIR] 将备份的文件存放在在目录下。 |
|
--suffix=SUFFIX |
定义备份文件的前缀。 | |
-c |
--checksum |
打开校验开关,强制对文件传输进行校验。 |
-d |
--dirs |
|
-D |
保留源文件的设备属性(device)。 | |
--delete |
表示客户端上的数据要与服务器端完全一致。 | |
-e |
指定使用的信道协议,例如使用SSH协议。 | |
--exclude |
[--exclude=PATTERN] 排除文件,多个文件用逗号分隔,并用大括号括起来。 |
|
--exclude-from |
[--exclude-from=FILE] 将要排除的文件写入到一个文本文件中。 |
|
-g |
--group |
保持文件的用户组。 |
-H |
--hard-links |
保留硬链接。 |
-I |
--ignore-times |
不跳过那些有相同mtime和大小的文件。 |
-l |
--links |
保留软链结。 |
-L |
--copy-links |
想对待常规文件一样处理软链接。 |
-r |
--recursive |
以递归方式同步文件夹及其子目录。 |
-p |
保持文件权限。 | |
-P |
--partial |
|
-t |
--times |
保持mtime属性。 |
-u |
--update |
仅仅进行更新,也就是跳过所有已经存在于目的端,并且文件时间晚于要备份的文件(不覆盖更新的文件)。 |
-v |
--verbose |
显示指令执行过程的详细信息。 |
-z |
--compress |
传输数据时进行压缩,以提高传输效率。 |
使用“-t”选项后,rsync总会想着一件事,那就是将源文件的“mtime”同步到目标机器。带有“-t”选项的rsync会变得更聪明一些,它会在同步前先对比两边文件的时间戳以及文件的大小,如果一致,则就认为两边文件一样,对此文件就不再采取更新动作了。当然,它也会反被聪明误。如果目的端文件的时间戳、大小和源端完全一致,但是内容恰巧不一致时,rsync是发现不了的。这就是传说中的“坑”~。对于它自作聪明的情况,解决办法就是使用-I选项。
如上所述,如果时间戳和文件大小完全一致,只有文件内容不同,且你没有使用“-I”选项的话,那么rsync是不会进行数据同步的。
那么,提个问题:“因为在Linux的世界里,文件夹也是文件,如果这类文件(文件夹)也只有内容不同,而时间戳和文件大小都相同,rsync会发现么?”对于文件夹,rsync是会明察秋毫的,只要你使用了“-r”选项,它就会恪尽职守的进入到文件夹里去检查,而不会只对文件夹本身做“quick check”的。
如果我们要同步一个软链接文件,rsync会提示什么?嗯,你猜对了,rsync会无情地拒绝我们。它一旦发现某个文件是软链接,就会无视它,除非我们增加“-l”选项。使用了该选项后,rsync会完全保持软链接文件类型,原原本本的将软链接文件复制到目的端,而不会链接到指向的实体文件。但如果我们偏偏就想让rsync采取follow link的方式,那么只要使用“-L”选项就可以了。
这个选项的全名是“perserve permissions”,顾名思义,就是保持权限。如果你不使用此选项,rsync是这样来处理权限问题的:
如果你使用了“-p”选项,则无论如何,rsync都会让目的端保持与源端的权限一致的。
这两个选项是一对,用来保持文件的属组(group)和属主(owner),作用应该很清晰明了。不过要注意的一点是,改变属主和属组,往往只有管理员权限才可以。
这个“-a”选项是rsync里比较霸道的一个选项,因为如果你使用了该选项,那么就相当于使用了“-rlptgoD”这一坨选项,相当于以一敌七。它的学名应该叫做“archive option”,中文叫做归档选项。使用“-a”选项,就表明你希望采取递归方式来同步,且尽可能的保持各个方面的一致性。但它也有其短板,那就是这个选项无法同步“硬链接”情况。如果有这方面的需求,要加上“-H”选项。
本地数据的备份十分简单,其用法几乎和cp指令一样。
[root@ServerB ~]# rsync -avz /etc/hosts /data
#将本机的hosts文件备份到指定目录中。看到了吧,十分的简单。
-----------------------
[root@ServerB ~]# mkdir /null #创建一个空目录。
[root@ServerB ~]# rsync -r --delete /null/ /data/
[root@ServerB ~]# ll /data
total 0
#通过--delete选项,实际上进行了删除工作(注意,该选项要配合-r来使用)。
#由于--delete选项的作用是『从目标目录删除多余的文件』,而源目录是空的,所以与之对应的目标目录中的所有文件都被视为多余的,从而被删除了。
在rsync指令中,备份源如果是目录的话,那么目录名结尾有无斜线是有区别的:
如果没有斜线,则会将整个目录文件及其内容都拷贝到目标目录中。
如果机上斜线,则仅仅将源目录下的所有内容都拷贝到目标目录中。
此工作模式下的rsync和scp两者之间除了备份策略上的不同外(全量和增量),没有其他的差别了。具体的操作过程可以参考scp指令,当然,rsync要配合使用“-e”选项才行。
[root@oaimage 07]# rsync -avz /image/nfs/ -e ssh root@10.10.200.21:/data/AppNFS/oaimages/nfs/
在涉及到Rsync服务的生产环境中,最重要的是指定服务器端,一般是由备份服务器作为Rsync的服务器端(见下图)。而配置Rsync服务器往往是我们要进行的第一个步骤!
在远程同步任务中,负责发起rsync同步操作的客户机称为“发起端”。
而负责响应来自客机的同步操作的服务器称为“备份端”。
注意:上图的rsync发起端与备份源是同一台主机,其实备份源与发起端可以是不同主机,但如果需要配合inotify进行实时同步时,会有问题。
其实所谓的客户端与服务器端只不过是指在rsync服务的“C-S”模型中的不同角色而已,作为同步工作的发起方,发起端实际上就是服务模型中的客户端,这一点要了解。
服务器的架设比较简单,可能我们安装好rsync后,并没有配置文件,因为每个管理员可能使用的用途不一样,所以一般的发行版只是安装好软件就完事了,让管理员来根据自己的用途和方向来自己架设rsync服务器。因为rsync的应用比较广泛,能在同一台主机进行备份工作,还能在不同主机之间进行工作。如果在不同主机之间的进行备份,是必须架设rsync服务器的。
在以daemon方式运行时rsync服务器会打开一个873端口,等待客户端去连接。连接时,rsync服务器会检查口令是否相符,若通过口令查核,则可以开始进行文件传输。第一次连通完成时,会把整份文件传输一次,以后则就只需进行增量备份。
Rsync服务器端主要有三个配置文件:
最为关键的主配置文件
/etc/rsyncd.conf
。
密码文件。
服务器信息文件。
配置rsync服务之前,我们先来检查一下系统中是否有安装rsync软件:
[root@ServerA ~]# rpm -qa|grep rsync
rsync-3.0.6-9.el6_4.1.x86_64
#如果没有安装,可以yum安装,也可以到官方站点下载源码包进行编译安装。
#官方站点地址:http://rsync.samba.org/
第一步:创建主配置文件:/etc/rsyncd.conf
(包括用户,目录,模块,虚拟用户及密码文件等)。这个文件默认是不存在的,需要我们手工创建:
[root@ServerA ~]# vim /etc/rsyncd.conf
配置文件详解:
##########第一部分:全局定义##########
#created by oldboy 15:01 2007-6-5
port = 873 #指定运行服务的端口,默认是873当然也可以自己指定。
uid = rsync
gid = rsync
#上述两个选项指定当该模块传输文件时守护进程应该具有的UID以及GID,这样可以确定守护进程的访问权限,其默认值为nobody。其实,任何一个系统服务都要对应一个系统中的用户账号,这里指定的用户及用户组就是专供rsync服务进程来使用。
use chroot = no
#注:用chroot,在传输文件之前,服务器守护程序在将chroot到文件系统中的目录中,这样做的好处是可能保护系统被安装漏洞侵袭的可能。缺点是需要超级用户权限。另外对符号链接文件,将会排除在外。也就是说,你在rsync服务器上,如果有符号链接,你在备份服务器上运行客户端的同步数据时,只会把符号链接名同步下来,并不会同步符号链接的内容。
max connections = 200
#指定该模块的最大并发连接数量以保护服务器,超过限制的连接请求将被告知随后再试。
timeout = 300
#通过该选项可以覆盖客户指定的IP超时时间。通过该选项可以确保rsync服务器不会永远等待一个崩溃的客户端。超时单位为秒,0表示没有超时定义,这也是默认值。对于匿名rsync服务器来说,理想的数字是600。
pid file = /var/run/rsyncd.pid #指定守护进程的PID文件。
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log #定义日志文件。
##########第二部分:模块定义##########
#模块定义了什么呢?主要是定义了服务器中的哪个目录要被同步。每个模块都要以『中括号+模块名称』形式开头,这个名字就是在客户端看到的名字,其实有点象Samba服务器提供的共享名。而服务器真正同步的数据是通过『path』指定的。我们可以根据自己的需要,来指定多个模块。每个模块要指定认证用户、密码文件等,但排除并不是必须的。
[oldboy]
path = /oldboy #指定备份源目录所在位置,该参数是必须指定的。
ignore errors #忽略某些I/O错误。
read only = false
#该选项设定是否允许客户端推送文件。如果为true那么任何推送请求都会失败,如果为false并且服务器目录读写权限允许那么上载是允许的。默认值为true。
list = false
#该选项设定当客户端请求可以使用的模块列表时,该模块是否被列出。如果设置该选项为false,可以创建隐藏的模块。
hosts allow = 10.0.0.0/24
hosts deny = 0.0.0.0/32
#这两个选项指定哪些IP的客户端允许或不允许连接该模块。对IP的定义可以是单个IP地址,也可以是网段。默认是允许所有主机连接,且默认是没有『hosts deny』定义的。
auth users = rsync_backup
#该选项指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块。这里的用户可以看成虚拟用户,和系统中的实体用户没有任何关系。
secrets file = /etc/rsync.password
#该选项指定了存放密码的文件。只有在『auth users』被定义时,该文件才有作用。
exclude = file1 file2 ...
#用来指定多个由空格隔开的文件或目录(相对路径),并将其添加到排除列表中。这等同于在客户端命令中使用排除选项。
需要注意的问题:
第一:如果auth users
参数被设置,那么客户端发出对该模块的连接请求后会被服务器端请求进行身份验证。用户名和口令都是以明文方式存放在指定的文件中(由secrets file
选项设定)。默认情况下无需使用密码就可以连接模块(即匿名方式)。注意,rsync在进行远程同步备份时,支持匿名或认证(无需系统用户)的传输模式,可以实现方便安全的数据备份及镜像。如果需要进行认证,就可以启用auth users
选项来指定虚拟的认证用户。
第二:密码文件的每行包含一个username:passwd
对,一般来说密码最好不要超过8个字符。
注意:该文件的权限一定要是600,否则客户端将不能连接服务器。
第三:一个模块只能指定一个排除选项。但是需要注意的一点是该选项有一定的安全性问题,客户端很有可能绕过排除列表,如果希望确保特定的文件不能被访问,那就最好结合“uid/gid”选项一起使用。其实,这与在服务端的rsync指令中使用选项进行排除,两者是等效的。客户端进行排除操作要更加的灵活一些。
注意:模块定义中有许多配置项(所有模块的配置项中那些相同的部分)也可以作为全局定义。
第二步:创建共享目录。
[root@ServerA ~]# mkdir /oldboy #这就是我们模块中指定的目录。
第三步:创建rsync用户,并且授权访问共享目录。
这个用户就是配置文件中的“uid/pid”选项所指定的用户,它是系统中的实体用户,供rsync守护进程来使用。
[root@ServerA ~]# useradd rsync -s /sbin/nologin
[root@ServerA ~]# chown -R rsync:rsync /oldboy
第四步:创建密码文件,其格式为:
auth users:password
[root@ServerA ~]# echo "rsync_buckup:oldboy">/etc/rsync.password
#这里的密码属于虚拟用户。
#这里的密码值得注意,为了安全你不能把系统用户的密码写在这里。
[root@ServerA ~]# cat /etc/rsync.password
rsync_backup:oldboy
第五步:修改密码文件权限:600。
[root@ServerA ~]# chmod 600 /etc/rsync.password
#由于密码是明文的,出于安全目的,将密码文件的属主及属组设为root,且权限要设为600,否则无法备份成功。
[root@ServerA ~]# ll /etc/rsync.password
-rw-------. 1 root root 20 Sep 28 11:38 /etc/rsync.password
第六步:启动rsync服务。
启动rsync服务器相当简单:
[root@ServerA ~]# /usr/bin/rsync --daemon --config=/etc/rsyncd/rsyncd.conf
#选项“--config”用于指定rsyncd.conf的位置,如果是在/etc目录下可以不写。
[root@ServerA ~]# rsync --daemon #注意启动方式。
[root@ServerA ~]# netstat -tulnp|grep rsync
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 1589/rsync
tcp 0 0 :::873 :::* LISTEN 1589/rsync
#可以看到,873端口目前处于监听状态。
[root@ServerA ~]# ps -ef|grep rsync|grep -v grep
root 1589 1 0 01:39 ? 00:00:00 rsync --daemon
#进程也同样存在。
[root@ServerA ~]# lsof -i :873
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsync 1589 root 3u IPv4 14727 0t0 TCP *:rsync (LISTEN)
rsync 1589 root 5u IPv6 14728 0t0 TCP *:rsync (LISTEN)
[root@ServerA oldboy]# cat /var/run/rsyncd.pid #查看PID文件。
1589
可以将rsync服务的启动命令加入到/etc/rc.local
中。通过上述的操作,我们打开了rsync这个守护进程,一旦有客户端请求连接进行同步操作时,xinetd会把它转介给rsyncd这个进程。
除此之外,如果出现错误信息,还需要查看日志。
第一步:创建密码文件,其格式为:
password
[root@ServerB ~]# echo oldboy > /etc/rsync.password
#这个密码就是服务器端的虚拟用户rsync_backup的密码。
[root@ServerB ~]# cat /etc/rsync.password
oldboy
第二步:修改密码文件权限:600
[root@ServerB ~]# chmod 600 /etc/rsync.password
[root@ServerB ~]# ll /etc/rsync.password
-rw------- 1 root root 7 Oct 8 00:15 /etc/rsync.password
这样的话就可以同步服务器端的数据了。当然,客户端需要建立一个本地的同步目录。
[root@ServerB ~]# rsync -avz rsync_backup@192.168.0.100::oldboy /data --password-file=/etc/rsync.password
receiving incremental file list
./
001.txt
002.txt
003.txt #这些是服务器端/oldboy目录中的数据。都被拉过来了。
sent 124 bytes received 264 bytes 776.00 bytes/sec
total size is 0 speedup is 0.00
#数据备份成功。
注意,对于上面的rsync指令,要和使用SSH通道进行数据传输时的指令区分开来:
[root@ServerA oldboy]# echo "This is a test">001.txt
#我们在服务器端对001.txt文件进行了修改。
[root@ServerB ~]# rsync -avz rsync_backup@192.168.0.100::oldboy /data --password-file=/etc/rsync.password
receiving incremental file list
001.txt #显然,这次只将001.txt进行了同步,因为只有它被改动过。
sent 83 bytes received 211 bytes 588.00 bytes/sec
total size is 15 speedup is 0.05
-------------------
[root@ServerB ~]# echo "This is a test too.">>/data/001.txt
#我们将客户端的001.txt再次进行修改。
[root@ServerB ~]# rsync -avz /data/ rsync_backup@192.168.0.100::oldboy --password-file=/etc/rsync.password
sending incremental file list
001.txt #也只是推送了001.txt文件。
#省略后面的提示信息。
另外,rsync指令的执行永远是在客户端,也就是同步服务的发起端,而不会在服务器端去执行同步指令,服务器端只有rsync服务进程在默默的运行~(有待商榷)
过程是杀进程,然后再次启动服务:
[root@ServerA ~]# pkill rsync
[root@ServerA ~]# /usr/bin/rsync --daemon
拉取操作与推送操作并不能保证服务器端与客户端中同步目录中的文件完全一致。就是说双方会出现差异。这是因为rsync指令的默认操作是不会将目标端的多余文件删除掉。
但是好多时候,我们需要无差异的同步。就是使用“--delete”,保证数据实时同步。这个选项是把双刃剑,控制好了非常有用,控制不好会损失数据,具体的风险如下:
企业实例:
rsync -nrv --exclude-from=/root/shell/DirnoSync.txt --password-file=/etc/.rsyncclient.passwd /data/AppNFS/oaimages/nfs/ syncuser@10.13.8.3::Images