作者 | 刘光录
来源 | TIAP
rsync(远程同步,Remote Sync)是一种在系统中或两个系统之间复制文件和目录的同步工具。rsync 的一个最大的优点,就是它只复制更改的文件,因而可以减少 CPU 消耗,在复制文件时节省带宽和时间。
rsync 相比于 scp 的优点
我们大家可能知道 scp(secure copy 的简写),也是一个通过 ssh 在两个远程系统之间复制文件的工具。但是 rsync 更好用,表现在以下三个方面:
1)rsync 只复制更改的文件,而 scp 会复制所有的每个文件,并且会覆盖旧的文件,因此,rsync的速度更快;
2)rsync 也可以在没有加密的情况下工作,这可以减少系统开销(仅用作对加密传输没要求的情况下,有安全风险时慎用);
3)rsync 支持断点续传(但是scp不可以)。
在大多数Linux发行版中,rsync 默认是没有安装的,因此需要手动安装。在 Ubuntu 和 Debian 系统中,可以使用如下命令安装:
sudo apt install rsync
rsync 命令示例
rsync命令的结构如下:
rsync [OPTIONS] Source Destination
上述命令中 Source 为文件的源地址,Destination 为目的地址。源地址和目的地址可以是本地路径也可以是远程路径,格式为:username@hostname:path/to/file
我们接下来看几个实际的例子。
注意:假如我们有一个目录 A,那么 A 和 A/ 是不一样的。A/ 指的是在目录A下的所有文件,但是不包括 A 本身;所以 复制 A 会在目的地址新建一个目录,然后复制 A 中的文件。但是复制 A/ 只会将 A 中的文件复制到目的地址中。
1. 同步本地文件(单向同步)
我们假设要将文件从目录 A 复制到 Backup-A-dir 中:
rsync A/ Backup-A-dir/
上述命令会将 A 中的文件复制到 Backup-A-dir 中。但Backup-A-dir中的文件不会同步到A中,这就是为什么会被称为单向同步的原因。
2. 同步远程文件(单向同步)
远程系统和本地系统之间同步文件,命令是类似的。注意,源地址和目的地址都可以是本地文件系统路径或者远程系统(ssh)路径。
rsync dev/build username@hostname:~/Backup
3. 双向同步
上述命令是将文件从源地址复制到目的地址。我们假设有这样一种情况,就是在目的地址中存在一些额外文件,但是这些额外文件在源地址中并不存在,那么在单向同步的时候,不会将目的地址中的这些额外文件删掉。如果我们想要在同步的时候删掉目的地址中的这些额外文件(也就是需要与源地址中的文件保持绝对一致),那么就需要使用双向同步。
要保持源地址和目的地址中的文件一致,将 --delete 选项添加到命令中即可:
rsync A/ Backup-A-dir/ --delete
4. 复制完成后删掉源文件
如果要在复制完成后,删掉源文件,需要在命令中添加 --remove-source-files 选项:
rsync A/ Backup-A-dir/ --remove-source-files
删掉源文件需要慎重,要确保已经保存好了备份,并且待删数据已经没有用了。
5. “包括”和“排除”文件
如果你需要(或者不需要)传输某些指定的文件,可以使用 --include 或者 --exclude 选项,后面跟上 = 和 指定文件的模式表达式:
rsync A/ Backup-A-dir/ --include=*.py --exclude=*.tmp.py
以上命令会传输所有以 .py 作为后缀名的文件,排除掉所有以 .tmp.py 为后缀名的文件。
上面提到的模式表达式,可以是正则表达式。
注:如果 include 或 exclude 的文件列表比较长,可以将其存储在文件中,使用的时候将文件名称传递给 --include-from 或者 --exclude-from 选项。
6. 通过 ssh 传输
如果想要通过 ssh 传输文件,那么需要使用 -e 选项来指定 ssh:
rsync -e ssh A/ username@hostname:~/Backup-A-dir/
这是传输文件到远程系统的首选方式,因为它传输的时候是加密的。需要注意的是,由于是加密传输,会产生系统开销,所以这比正常传输更耗时。
要使用 ssh 传输,还需要确保服务器端已经配置了ssh。
7. 详情模式
Linux 中的大多数命令都会有详情选项,用于在终端中记录命令的操作。rsync 也不例外。
使用 -v 或者 -verbose 选项来显示详情,它会列出正在执行的操作和进度。这在调试的时候很方便。
rsync A/ Backup-A-dir/ -v -r
其输出类似于如下的输出:
$ rsync A/ Backup-A-dir/ -v -rsending incremental file listcreated directory Backup-A-dir./file1.txtfile2.txtfile3.txtfile4.txtfile5.txtfile6.txtsent 388 bytes received 168 bytes 1,112.00 bytes/sectotal size is 0 speedup is 0.00
8. 只运行(运行但是不执行复制操作)
如果你只是想知道在不进行实际传输的情况下,需要复制的文件,那么可以使用 --dry-run(或者 -n)选项:
除复制部分外,它与正常rsync命令一样执行所有操作。它将列出要复制或删除的文件(如果需要),然后在复制之前停止。
$ rsync -v A/ Backup-A-dir/ –dry-run
sending incremental file list
created directory Backup-A-dir
./
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
file6.txt
sent 172 bytes received 72 bytes 488.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)
注意,上述命令需要带有参数 -v 来显示详情,否则不会显示任何结果。
9. 显示传输进度
要显示传输进度,可使用 --progress 选项:
rsync A/ Backup-A-dir/ --progress
上面的命令将显示一个类似于下面的进度条:
$ rsync -r A/ Backup-A-dir/ –progresssending incremental file listcreated directory Backup-A-dir./file1.txt 0 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=5/7)file2.txt 0 100% 0.00kB/s 0:00:00 (xfr#2, to-chk=4/7)file3.txt 0 100% 0.00kB/s 0:00:00 (xfr#3, to-chk=3/7)file4.txt 0 100% 0.00kB/s 0:00:00 (xfr#4, to-chk=2/7)file5.txt 0 100% 0.00kB/s 0:00:00 (xfr#5, to-chk=1/7)file6.txt 0 100% 0.00kB/s 0:00:00 (xfr#6, to-chk=0/7)
10. 压缩和传输数据
使用 -z 选项可以压缩要传输的数据,压缩后在传输数据会更加节省网络带宽和时间。它将在目的地自动解压缩。
当传输的数据量很大时,使用 -z 选项进行压缩会节省时间,但是对于小文件,应该避免使用 -z,因为处理压缩的开销会超过正常情况下的时间。
rsync -z A/ Backup-A-dir/
11. 递归复制文件和目录
以上所有命令只复制文件,不复制子目录(每个Linux命令都是这样)。因此,不会复制这些子目录中的文件。要复制子目录中的文件,可以使用 -r 选项。
rsync -r A/ Backup-A-dir/
12. 归档并保留元数据
如果要保留符号链接、时间戳、文件权限、文件的用户和组所有权,可以使用 -a 选项。
rsync -a A/ Backup-A-dir/
结合使用 -r 可以递归复制文件并保留复制文件的元数据。
13. 设置文件大小限制
为了避免传输大文件,可以使用 --max-size 选项设置文件大小限制。
rsync --max-size='100K' A/ Backup-A-dir/
14. 设置带宽限制
--bwlimit 选项可以设置最大传输速率,单位是 kbps。
rsync --bwlimit=100 A/ Backup-A-dir/
15. 断点续传
如果文件传输不完整,可以使用 rsync 命令保留不完整的下载,以便在下一次发出相同命令时继续传输。
要恢复传输,使用 --append 选项:
rsync --append A /Backup-A-dir/
多线程传输
以上都是一些基本的命令,是在单个进程中复制文件。如果文件特别大,比如有5TB,那么整个传输过程的持续时间会非常长。这里介绍一种方法可以加快传输速度,那就是使用 parallel。
parallel 是用于执行并发作业的GNU程序,可以和 rsync 结合使用。
与 rsync 一样,parallel 也需要手动安装:
sudo apt install parallel
在我们正式介绍 parallel 之前,先来了解一些它是如何工作的。我们来考虑一个类比:
假设有1000个鸡蛋和100个篮子,然后每个篮子配备一个无人机,任务就是将这1000个鸡蛋交付给客户。经理给每个篮子分配10个鸡蛋,并将篮子交给无人机进行交付。这样每个无人机都会执行一个操作(就是送篮子中的鸡蛋,我们的例子中,就好比是 rsync 处理10个文件)。经理监督无人机的工作。请注意,每个无人机都不知道是否还有其他无人机,只有经理才知道。
类似地,rsync像无人机一样执行文件传输,而 parallel 就担任经理的角色。
parallel 将要传输的文件分割成若干份(每份都是一个文件列表),每份都由rsync启动一个进程进行传输。rsync不知道其他并行的进程,也不具备并行传输的能力。而parallel就启动rsync,来启动并管理多个并行进程。
因此,parallel 命令由两部分组成,一个是参数(鸡蛋/文件),另一个是并行进程命令(管理器)。
ls A/* | parallel -j 20 rsync A/{} /Backup-A-dir/
在上述命令中,管道符号 | 左侧的部分,输出是一个文件列表,每个文件都作为一个参数;在 parallel 命令中,{} 则表示这些参数(相当于占位符)。
-j n,它给- n 一个数字来表示任务数(或者进程数),本例中,n 是20;之后是 rsync 的常用命令,来处理每个参数(管道符号左侧的文件列表)。最后,它会被捆绑到20个进程中,并行执行。
注意,上面的 rsync 命令就是普通的rsync命令,跟我们上面介绍的用法完全一样,就像不用 parallel 时一样,可以添加任何选项(比如 -z, -a, -e ssh等)。
关于 garallel 的详细介绍,可参考:
https://www.gnu.org/software/parallel/
使用 rsync 时的一些常见故障
使用 rsync 时可能会遇到一些问题,下面是一些常见的错误。
1. rsync 权限被拒绝(rsync permission denied)
当你使用没有权限的路径时,就会报出这个错,比如:
rsync B/ /home/
如果你没有 /home 的写入权限,那上述命令就会报权限被拒绝(普通用户通常不这样做)。
2. 在<路径>中设置时间错误(rsync failed to set times on <path>)
当文件系统无法处理文件和目录的修改时间时,就会发生这种情况。关于这个问题,可以参考:
https://superuser.com/questions/200012/rsync-failed-to-set-times-on-dir-path
以上就是本次分享全部内容,欢迎讨论。
往期推荐
40 张图 详解 Docker 容器监控
剖析 kubernetes 集群内部 DNS 解析原理
Docker 镜像和容器的导入导出及常用命令
实战 Kubectl 创建 Deployment 部署应用
点分享
点收藏
点点赞
点在看