青蛙学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
原文地址:https://www.cnblogs.com/yu2006070-01/p/10137294.html