188f950d10e388ac8c2e0c35b1e09be7.gif

作者 | 刘光录

来源 | 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

以上就是本次分享全部内容,欢迎讨论。

d85b1253d83ade9c05292248db0dc484.gif

往期推荐

40 张图 详解 Docker 容器监控

剖析 kubernetes 集群内部 DNS 解析原理

Docker 镜像和容器的导入导出及常用命令

实战 Kubectl 创建 Deployment 部署应用

dc2192c94d7c1385d79c57965b6ec4a3.gif

点分享

37c2610906dbabc2ac48dca2cac1b948.gif

点收藏

db44160ff84a06f2b94ebaf1b369c10d.gif

点点赞

a4d5d5eb9cdd2b710d237d2c438fc0a9.gif

点在看

Logo

更多推荐