青蛙学Linux—rsync
rsync是Linux下常用的一个数据镜像备份工具。通过sync,可以将本地的数据通过网络同步到远程主机上。rsync有以下特性:
- 可以镜像保存整个目录树和文件系统
- 可以增量同步数据,文件传输效率高,因而同步时间短
- 可以保持文件原有的权限、时间等属性
- 加密传输数据,保证了数据的安全性
1、三种工作方式
rsync支持以下三种工作方式:
- 本地文件系统上的同步(本机到本机)
- 本地主机使用远程shell和远程主机通信进行同步(client/client模式)
- 本地主机通过连接远程主机上的rsync daemon进行同步(client/server模式)
这三种工作方式的语法分别为:
本地同步模式
将指定的文件同步到本机的某个路径,类似cp
rsync [选项] 源文件路径 [目标文件路径]
client/client模式
将指定的文件同步到远程主机,类似scp
# 从远程主机拉取文件 rsync [选项] [用户@]主机:源文件路径 [目标文件路径] # 将文件推送到远程主机 rsync [选项] 源文件路径 [用户@]主机:目标文件路径
client/server模式
在远程主机上运行一个rsync daemon,监听特定的端口,本地主机通过socket连接远程主机并进行数据传输
# 从远程主机拉取文件 rsync [选项] [用户@]主机::模块 [目标文件路径] rsync [选项] rsync://[用户@]主机[:端口]/模块 [目标文件路径] # 将文件推送到远程主机 rsync [选项] 源文件路径 [用户@]主机::模块 rsync [选项] 源文件路径 rsync://[用户@]主机[:端口]/模块
注意:
- 当命令中仅有一个路径参数时,rsync始终认为该路径是源文件路径,此时会以类似ls -l的方式列出源文件路径下的文件列表
- 源路径如果是一个目录的话,带尾随斜杠和不带尾随斜杠是不同的,不带尾随斜杠表示的是整个目录包括目录本身进行同步,带上尾随斜杠表示的是目录中的文件,不包括目录本身
2、常用选项
rysnc有非常多的选项,这里仅介绍非常少的一部分常用选项,更多选项可以查看rsync的man手册。
- -v:显示rsync过程中的详细信息。另可以使用-vvvv获取更详细的信息
- -P:显示文件传输的进度
- -n:仅测试传输,而不实际传输,通常与-vvvv配合使用来查看rsync是如何工作的
- -a:归档模式,表示归档传输并保持文件属性。等同于-rtopgDl
- -r:归档到目录中去
- -t:保持mtime属性。如果没有该选项,则目标文件mtime时间会设置为系统时间,将导致增量备份出现问题
- -o:保持属主属性
- -g:保持属组属性
- -p:保持权限属性
- -D:拷贝设备文件和特殊文件
- -l:如果文件是符号链接,则拷贝符号链接本身而非其指向的对象
- -z:传输时进行压缩提高效率
- -R:使用相对路径,这样将把命令中指定的全路径发送给远程主机。例如将/etc/xxx发送到远程主机的/tmp下,则会生成/tmp/etc/xxx这样的路径
- --size-only:默认算法是检查文件大小和mtime不同的文件,使用该选择则只检查文件大小
- -u:仅在源mtime比目标已存在文件的mtime新时才拷贝。注意,该选项是接收端判断的,不会影响删除行为
- -d:不以递归方式拷贝目录本身。默认递归时,如果源为/etc/xxx,则不会拷贝/etc目录,使用该选项时只拷贝/etc而不拷贝xxx。如果源路径很长而且只想保持部分的目录结构可以在路径中使用.,rsync将保持从.开始的目录结构
- --max-size:限制rsync传输的最大文件大小,可以使用单位后缀
- --min-size:限制rsync传输的最小文件大小,可以用于禁止传输小文件或垃圾文件
- --include:选择指定的文件进行传输
- --exclude:排除不需要传输的文件
- --delete:已源为主,对目标进行同步。多则删之,少则补之。--delete是在接收端执行的,所以是在include/exclude规则生效之后执行
- -b:对目标上已存在的文件做备份,备份的文件名默认使用~做后缀
- --suffix:指定使用-b选项时备份文件的后缀
- --backup-dir:指定使用-b选项时备份文件的保存路径,在使用该选项指定路径之后,默认将不会设置备份文件名的后缀,除非使用--suffix进行指定后缀
- -e:指定所要使用的远程shell程序,默认为ssh。如当ssh的端口非22时,可以使用-e ‘ssh -p xxx’来指定ssh使用的端口
- --port:连接server时使用的端口号,默认为873
- --password-file:client/server模式时指定的密码文件,以实现非交互。这里的密码是rsync模块设置的认证密码,而非远程shell的认证密码。该文件仅保存指定用户的密码,权限必须为600
- -W:使用该选择则rsync不再使用增量传输模式,而是使用全量传输模式。在网络带宽高于磁盘带宽时该模式更加高效
- --existing:只更新目标端以存在的文件,不存在的文件不传输。注意,使用相对路径时如果上层目录不存在也不会传输
- --ignore-existing:只更新目标端不存在的文件
- --remove-source-files:要求删除源端已经成功传输的文件
常用选项组合有-avz --delete,表示压缩和显示部分信息,并以归档模式传输,同时以源为标准同步目标中的文件。
3、与--exclude排除规则和--delete删除规则有关的一些知识
在添加了--exclude规则之后,在使用--delete进行源与目标同步时,在目标端将不会删除源端使用--exclude排除掉的文件。这与rsync运行的原理有关。
当rsync开始运行时,将对源端的文件进行扫描,并将扫描到的文件记录到一个文件列表中。在使用--exclude进行排除文件时,这些排除掉的文件也将被记录到文件列表中,只是做了hide标记把它们隐藏起来而已。而rsync为了防止误删的情况发生,提供了保护规则和取消保护规则。在文件列表中标记为hide的文件将被保护规则保护,使得--delete无法删除这些文件。如果需要在目标端删除这些文件,可以使用--delete-excluded选项取消保护规则。
另外,还有一个--include传输规则,当--include选项和--exclude选项同时使用时,一个文件如果能被两个规则同时匹配,则先匹配到的规则优先生效,生效后就不能再被其他的规则匹配了。
注意: 一个--exclude和--include只能指定一条规则,如果要指定多条规则则需要使用多个--exclude和--include选项,也可以将排除规则写入文件,然后使用--exclude-from指定读取的文件
4、client/server模式(daemon模式)
使用该模式时在远程主机运行rsync daemon服务,该服务监听873端口。当客户端连接该端口时,通过socket进行数据传输。此时,运行rsync daemon的远程主机就成为了serve。
使用以下命令启动rsync daemon:
rsync --daemon
在CentOS 7.x中,rsync daemon可以使用systemctl进行管理,服务名为rsyncd.service。
rsync daemon默认读取的配置文件为:
/etc/rsyncd.conf
注意:如果该配置文件不存在则需要手动创建。
以下是CentOS 7.x下的一个配置文件的内容:
# /etc/rsyncd: configuration file for rsync daemon mode # See rsyncd.conf man page for more options. # configuration example: # 全局配置 # uid = nobody # gid = nobody # use chroot = yes # max connections = 4 # pid file = /var/run/rsyncd.pid # exclude = lost+found/ # transfer logging = yes # timeout = 900 # ignore nonreadable = yes # dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 # [ftp] # 模块 # path = /home/ftp # comment = ftp export area
注意:在rsync daemon模式下,访问服务端的路径是通过模块来进行的,模块下定义了文件保存的路径。
配置文件中的常用字段详解:
全局配置
- port:指定rysnc daemon的端口,默认为873
- uid:rsync服务运行的用户,默认为nobody,文件传输成功后属主将是这个uid
- gid:rsync服务运行的用户组,默认为nobody,文件传输成功后属组将是这个gid
- user chroot:rsync daemon在传输前是否切换到指定的path目录下,并保持在内,值为yes|no
- max connections:最大连接数,0表示没有限制
- timeout:超时时间,0表示永远不会超时
- pid file:指定rsync daemon的PID文件,默认为/var/run/rsyncd.pid
- lock file:指定rsync daemon的锁文件,默认为/var/run/rsync.lock
- log file:指定rsync的日志文件,使用该字段后将不通过rsyslog进行日志管理
- dnot compress:指定哪些后缀的文件不进行压缩传输
模块配置
- path:指定该模块的路径。该字段必须指定,而且指定的路径必须存在
- comment:对于该模块的说明
- ignore errors:忽略某些IO错误,注意,该字段没有值,不应该使用=号
- read only:指定该模块是否可读写,false表示可读写,ture表示只读。用于指定模块是否可以上传文件,默认所以模块不可上传
- write only:指定该模块是否支持下载,设置为ture表示客户端不能下载。所有模块默认可以下载
- list:客户端请求显示模块列表时,该模块是否显示,设置为false为隐藏,默认为ture
- hosts allow:指定允许连接到该模块的主机,多个IP用空格隔开或者设置IP区间
- hosts deny:指定不允许连接到该模块的主机
- auth users:指定连接到该模块的用户列表,注意,这里的用户不是系统用户,而是自定义的rsync用户。不设置时所有用户都可以连接,但是使用的是匿名连接
- secrets file:保存auth users中设置的用户名的密码,格式为用户名:密码。值为指定的一个文件,该文件的权限必须为600
注意:全局配置中指定的uid和gid用户必须对模块中path指定的目录有权限
5、几个例子
这里使用两台安装CentOS的主机进行rsync的实验。
- 主机A:IP地址为192.168.0.110,系统为CentOS 7.5.1804
- 主机B:IP地址为192.168.0.106,系统为CentOS 6.10
5.1、client/client模式
将主机A当前目录下的Python-3.7.1目录及目录下的文件通过rsync使用ssh同步到主机B的/data目录下(保持目录及文件的用户信息及权限信息),主机B使用的用户为root
[root@localhost ~]# rsync -avz --delete Python-3.7.1 root@192.168.0.106:/data root@192.168.0.106's password: ... sent 24,129,332 bytes received 77,216 bytes 489,021.17 bytes/sec total size is 78,775,345 speedup is 3.25
将主机B上/data目录下刚才上传的Python-3.7.1目录重新拉回主机A
[root@localhost ~]# rsync -avz --delete root@192.168.0.106:/data/Python-3.7.1 ./ root@192.168.0.106's password: ... sent 75,092 bytes received 24,127,762 bytes 499,027.92 bytes/sec total size is 78,775,345 speedup is 3.25
5.2、client/server模式
在主机B上开启rsync daemon,然后将主机A上当前目录下的Python-3.7.1目录及目录下的文件通过rsync daemon同步到主机B上的/data目录下
要启动rsync daemon,必须确认是否存在rsync的配置文件/etc/rsyncd.conf,该文件在CentOS 6.x下模式是不存在的
[root@localhost data]# ll /etc/rsyncd.conf ls: 无法访问/etc/rsyncd.conf: 没有那个文件或目录
所以我们必须先建立该文件并写入配置
[root@localhost data]# touch /etc/rsyncd.conf [root@localhost data]# vim /etc/rsyncd.conf
配置文件内容如下
uid = nobody gid = nobody use chroot = no max connections = 10 pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /data/rsync.log timeout = 500 dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 [test] path = /data comment = test rsync daemon ignore errors read only = false list = false auth users = rsync_test sercets file = /etc/rsyncpass.pwd
创建/etc/rsyncpass.pwd文件并写入用户名密码信息
[root@localhost data]# touch /etc/rsyncpass.pwd [root@localhost data]# vim /etc/rsyncpass.pwd
/etc/rsyncpass.pwd文件内容如下
rsync_test:12345
设置/etc/rsyncpass.pwd文件的权限为600
[root@localhost data]# chmod 600 /etc/rsyncpass.pwd [root@localhost data]# ll /etc/rsyncpass.pwd -rw-------. 1 root root 17 12月 20 10:57 /etc/rsyncpass.pwd
启动rsync daemon
[root@localhost data]# rsync --daemon
查看rsync daemon进程是否启动以及监听的是否是873端口
[root@localhost data]# ps -ef|grep rsync root 28148 1 0 13:43 ? 00:00:00 rsync --daemon root 28151 28105 0 13:44 pts/0 00:00:00 grep rsync [root@localhost data]# lsof -i :873 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rsync 28148 root 4u IPv4 305502 0t0 TCP *:rsync (LISTEN) rsync 28148 root 5u IPv6 305503 0t0 TCP *:rsync (LISTEN)
rsync daemon在主机B上已经成功启动,现在开始将主机A下的目录同步到主机B上
[root@localhost ~]# rsync -avz --delete Python-3.7.1 rsync_test@192.168.0.106::test Password: ... sent 24,129,316 bytes received 77,220 bytes 701,638.72 bytes/sec total size is 78,775,345 speedup is 3.25 # 这里没有指定密码文件,所以需要交互式输入密码,密码即为我们在主机B上设置的rsync_test用户的密码12345
在主机A上指定密码文件以使用非交互模式连接主机B
[root@localhost ~]# rsync -avz --delete --password-file=passwd.pwd Python-3.7.1 rsync_test@192.168.0.106::test