rsync
rsync: remote sync,远程同步,用于在本地机器及远程机器之间同步数据。
对于本地机器之内,同步数据使用cp即可。
对于本地与远程,使用scp即可。
但上面两个命令同步数据时一般是无脑覆盖文件,而rsync则不会直接覆盖以前的数据(如果数据已经存在),而是先判断已经存在的数据和新数据的差异,只有数据不同时才会把不相同的部分覆盖。
怎么判定文件有改动呢?默认是检查文件大小和最后修改时间是否一致,如果一致则认为无变动,不会传输该文件,如果不一致则同步。
对于想让两台机器某个目录一致的需求来说,如果目录每天新增数据,则相对scp来说,可以节省大量带宽。
因为它用少量的文件信息换取了大量文件内容的传输。
常用参数
以本地同步文件为例,远程同步只需要在本地同步的基础上加上远程主机的前缀即可,见下文介绍。
初次使用rsync可能会有些疑惑,有时想同步文件夹,却被新创建的目录迷惑,如下:
rsync -r a b
-r参数表示递归目录,与cp中一致。如果不加-r,不会同步任何东西:skipping directory a。
想要把a目录下所有文件同步到b目录下,结果却把a连同目录同步到了b:
% tree
.
└── a
└── a.csv
1 directory, 1 file
% rsync -rv a b
sending incremental file list
created directory b
a/
a/a.csv
sent 125 bytes received 63 bytes 376.00 bytes/sec
total size is 4 speedup is 0.02
% tree
.
├── a
│ └── a.csv
└── b
└── a
└── a.csv
3 directories, 2 files
其中:
- -v表示显示详细信息
- 如果目标目录不存在,则创建
- 同步时连同目录a一块同步了
- 最后生成了b/a/a.csv的目录结构
想要达到目的也简单,只需要在目录上加后缀即可:
% rm -rf b
% rsync -rv a/ b
sending incremental file list
created directory b
./
a.csv
sent 115 bytes received 62 bytes 354.00 bytes/sec
total size is 4 speedup is 0.02
% tree
.
├── a
│ └── a.csv
└── b
└── a.csv
2 directories, 2 files
可见,在源目录后加目录后缀,就会只传输目录内文件,不会带目录传输了。
最常用的参数是-a,它包含了-r的含义,并保持文件所有属性,包括软链接、文件权限、属主信息、修改时间等等。
总之一句话,以后同步不要用-r了,-a即可搞定一切。
其他常用参数:
- –delete:删除只存在于目标目录、不存在于源目录的文件,默认只保证源目录的内容传输到了目标目录,而不管目标目录内其他文件
- –exclude:同步时排除某些文件或目录,如 rsync -av --exclude=‘*.txt’ a/ b,不同步所有以txt结尾的文件
- –include:指定需要同步的文件,经常与–exclude组合使用,如 rsync -av --include=".txt" --exclude='’ a/ b,只同步以txt结尾的文件
- -z:同步时压缩数据
增量传输
rsync是增量传输,来具体看看传输过程:
# 有一个22Bytes的文件
% ls -l a
total 4
-rw-r--r-- 1 ysj user 22 May 12 18:32 a.csv
# 传输
% rsync -av a/ b
sending incremental file list
created directory b
./
a.csv
sent 144 bytes received 62 bytes 412.00 bytes/sec
total size is 22 speedup is 0.11
# 目标文件已经存在,且文件无修改,再次传输
% rsync -av a/ b
sending incremental file list
sent 72 bytes received 12 bytes 168.00 bytes/sec
total size is 22 speedup is 0.26
# 修改文件内容,加一个Bytes
% ls -l a
total 4
-rw-r--r-- 1 ysj user 23 May 12 18:40 a.csv
# 再次传输
% rsync -av a/ b
sending incremental file list
./
a.csv
sent 148 bytes received 38 bytes 372.00 bytes/sec
total size is 23 speedup is 0.12
# 在源目录新增文件,再传输
% echo 'abc' > a/b.csv
% rsync -av a/ b
sending incremental file list
./
b.csv
sent 150 bytes received 38 bytes 376.00 bytes/sec
total size is 27 speedup is 0.14
# 无修改再次传输
% rsync -av a/ b
sending incremental file list
sent 96 bytes received 12 bytes 216.00 bytes/sec
total size is 27 speedup is 0.25
总结如下:
- 每次都会传输数据,即使目标目录与源目录相同,传输的应该是文件的属性,包括文件名、修改时间等
- 目标目录与源目录相同时,不会传输文件
- 如果文件被修改,则会被传输
- 如果有新增文件,则新增文件会被传输
远程传输
与scp一样,只需要加上远程主机标识,如把本地a目录内容传输到远程主机:
rsync -av a/ user@192.168.1.2:/home/user/b
# 反过来,远程传输到本地
rsync -av user@192.168.1.2:/home/user/a/ b
小节
使用rsync可以替代大部分scp的应用场景。
但rsync的因为需要对比文件是否一致,传输时带宽的利用率不如scp。
scp是不管三七直接猛传,可以把带宽打满。所以对于较大的文件,第一次传输时可以用scp省时间。
参数的话,用-a就行了,传目录还是传文件,写清楚就ok了。