加速rsync的3-4个技巧。
1. 从/到本地网络复制:不要使用ssh
!
如果你在本地将一个服务器复制到另一个服务器,传输过程中没有必要加密数据!
默认情况下,rsync使用ssh
通过网络传输数据。为了避免这种情况,你需要在目标主机上创建一个rsync服务器
。你可以通过类似以下方式运行守护进程:
rsync --daemon --no-detach --config filename.conf
最简配置文件的样子可能是这样的:(参见
man rsyncd.conf
)
filename.conf
port = 12345
[data]
path = /some/path
use chroot = false
那么
rsync -ax rsync://remotehost:12345/data/. /path/to/target/.
rsync -ax /path/to/source/. rsync://remotehost:12345/data/.
1.1. 限制连接的最小化rsyncd.conf
配置文件。
关于jeremyjjbrown的评论关于安全性的问题,这里是一个使用专用网络接口的最小化配置示例:
主要公共服务器:
eth0: 1.2.3.4/0 Public address Main
eth1: 192.168.123.45/30 Backup network
一个30位的网络只能容纳两个主机。
┏━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━┓
┃ Network base│192.168.123.44 │ #0│11000000 10101000 01111011 001011│00┃
┃ Mask │255.255.255.252│/30 │11111111 11111111 11111111 111111│00┃
┃ Broadcast │192.168.123.47 │ #3│11000000 10101000 01111011 001011│11┃
┃ Host/net │2 │Class C │ │ ┃
┠─────────────┼───────────────┼───────────┼─────────────────────────────────┼──┨
┃▸First host │192.168.123.45 │ #1│11000000 10101000 01111011 001011│01┃
┃ Last host │192.168.123.46 │ #2│11000000 10101000 01111011 001011│10┃
┗━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━┛
备份服务器:
eth0: 1.2.3.5/0 Public address Backup
eth1: 192.168.123.46/30 Backup network
cat >/etc/rsyncd.conf <<eof
address 192.168.123.46
[main]
path = /srv/backup/backup0
comment = Backups
read only = false
uid = 0
gid = 0
eof
所以rsync只会监听连接到192.168.123.46(也就是第二个网络接口)的连接。
然后rsync从主服务器运行。
rsync -zaSD --zc zstd --delete --numeric-ids /mnt/. rsync://192.168.123.46/main/.
当然,在防火墙中添加一些规则可能并非完全无用。
iptables -I INPUT -i eth0 -p tcp --dport 873 -j DROP
2. 使用
zstandard zstd
进行高速压缩
Zstandard 可以比 常见的 gzip
快8倍。因此,使用这种更新的压缩算法将显著提高您的传输速度!
rsync -axz --zc=zstd rsync://remotehost:12345/data/. /path/to/target/.
rsync -axz --zc=zstd /path/to/source/. rsync://remotehost:12345/data/.
也许还可以使用一些--exclude
指令(请参见本答案底部!)。
3. 使用多路复用的rsync
来减少因浏览时间而导致的不活动
两个重要说明:
由于这种优化涉及磁盘访问和文件系统结构,与CPU数量无关!因此,即使您的主机使用单核CPU,这也可以提高传输效率。如果您计划使用任何并行化工具,请告诉它不要考虑物理CPU的数量。
由于目标是确保在其他任务浏览文件系统时尽可能利用带宽的最大数据量,同时进行的进程数取决于存在的小文件数量。
3.1 使用wait -n -p PID
的bash脚本:
最近的bash版本为wait
内置命令添加了一个-p PID
功能。对于这类作业来说,这是必备的:
#!/bin/bash
maxProc=3
source=''
destination='rsync://remotehost:12345/data/'
declare -ai start elap results order
wait4oneTask() {
local _i
wait -np epid
results[epid]=$?
elap[epid]=" ${EPOCHREALTIME/.} - ${start[epid]} "
unset "running[$epid]"
while [ -v elap[${order[0]}] ];do
_i=${order[0]}
printf " - %(%a %d %T)T.%06.0f %-36s %4d %12d\n" "${start[_i]:0:-6}" \
"${start[_i]: -6}" "${paths[_i]}" "${results[_i]}" "${elap[_i]}"
order=(${order[@]:1})
done
}
printf " %-22s %-36s %4s %12s\n" Started Path Rslt 'microseconds'
for path; do
rsync -axz --zc zstd "$source$path/." "$destination$path/." &
lpid=$!
paths[lpid]="$path"
start[lpid]=${EPOCHREALTIME/.}
running[lpid]=''
order+=($lpid)
((${#running[@]}>=maxProc)) && wait4oneTask
done
while ((${#running[@]})); do
wait4oneTask
done
输出可能如下所示:
myRsyncP.sh files/*/*
Started Path Rslt microseconds
- Fri 03 09:20:44.673637 files/1/343 0 1186903
- Fri 03 09:20:44.673914 files/1/43 0 2276767
- Fri 03 09:20:44.674147 files/1/55 0 2172830
- Fri 03 09:20:45.861041 files/1/772 0 1279463
- Fri 03 09:20:46.847241 files/2/346 0 2363101
- Fri 03 09:20:46.951192 files/2/4242 0 2180573
- Fri 03 09:20:47.140953 files/3/23 0 1789049
- Fri 03 09:20:48.930306 files/3/2545 0 3259273
- Fri 03 09:20:49.132076 files/3/4256 0 2263019
快速检查:
printf "%'d\n" $(( 49132076 + 2263019 - 44673637)) \
$((1186903+2276767+2172830+1279463+2363101+2180573+1789049+3259273+2263019))
6’721’458
18’770’978
处理18.77秒的时间经过了6.72秒,最多有三个子进程。
注意:您可以使用musec2str来改善输出,通过将第一个长printf
行替换为:
musec2str -v elapsed "${elap[i]}"
printf " - %(%a %d %T)T.%06.0f %-36s %4d %12s\n" "${start[i]:0:-6}" \
"${start[i]: -6}" "${paths[i]}" "${results[i]}" "$elapsed"
myRsyncP.sh files/*/*
Started Path Rslt Elapsed
- Fri 03 09:27:33.463009 files/1/343 0 18.249400"
- Fri 03 09:27:33.463264 files/1/43 0 18.153972"
- Fri 03 09:27:33.463502 files/1/55 93 10.104106"
- Fri 03 09:27:43.567882 files/1/772 122 14.748798"
- Fri 03 09:27:51.617515 files/2/346 0 19.286811"
- Fri 03 09:27:51.715848 files/2/4242 0 3.292849"
- Fri 03 09:27:55.008983 files/3/23 0 5.325229"
- Fri 03 09:27:58.317356 files/3/2545 0 10.141078"
- Fri 03 09:28:00.334848 files/3/4256 0 15.306145"
你可以通过对这个脚本进行一些编辑来添加总体统计数据。
#!/bin/bash
maxProc=3 source='' destination='rsync://remotehost:12345/data/'
. musec2str.bash
declare -ai start elap results order
declare -i sumElap totElap
wait4oneTask() {
wait -np epid
results[epid]=$?
local -i _i crtelap=" ${EPOCHREALTIME/.} - ${start[epid]} "
elap[epid]=crtelap sumElap+=crtelap
unset "running[$epid]"
while [ -v elap[${order[0]}] ];do
_i=${order[0]}
musec2str -v helap ${elap[_i]}
printf " - %(%a %d %T)T.%06.f %-36s %4d %12s\n" "${start[_i]:0:-6}" \
"${start[_i]: -6}" "${paths[_i]}" "${results[_i]}" "${helap}"
order=(${order[@]:1})
done
}
printf " %-22s %-36s %4s %12s\n" Started Path Rslt 'microseconds'
for path;do
rsync -axz --zc zstd "$source$path/." "$destination$path/." &
lpid=$! paths[lpid]="$path" start[lpid]=${EPOCHREALTIME/.}
running[lpid]='' order+=($lpid)
((${#running[@]}>=maxProc)) &&
wait4oneTask
done
while ((${#running[@]})) ;do
wait4oneTask
done
totElap=${EPOCHREALTIME/.}
for i in ${!start[@]};do sortstart[${start[i]}]=$i;done
sortstartstr=${!sortstart[*]}
fstarted=${sortstartstr%% *}
totElap+=-fstarted
musec2str -v hTotElap $totElap
musec2str -v hSumElap $sumElap
printf " = %(%a %d %T)T.%06.0f %-41s %12s\n" "${fstarted:0:-6}" \
"${fstarted: -6}" "Real: $hTotElap, Total:" "$hSumElap"
可以生产:
$ ./parallelRsync Data\ dirs-{1..4}/Sub\ dir{A..D}
Started Path Rslt microseconds
- Sat 10 16:57:46.188195 Data dirs-1/Sub dirA 0 1.69131"
- Sat 10 16:57:46.188337 Data dirs-1/Sub dirB 116 2.256086"
- Sat 10 16:57:46.188473 Data dirs-1/Sub dirC 0 1.1722"
- Sat 10 16:57:47.361047 Data dirs-1/Sub dirD 0 2.222638"
- Sat 10 16:57:47.880674 Data dirs-2/Sub dirA 0 2.193557"
- Sat 10 16:57:48.446484 Data dirs-2/Sub dirB 0 1.615003"
- Sat 10 16:57:49.584670 Data dirs-2/Sub dirC 0 2.201602"
- Sat 10 16:57:50.061832 Data dirs-2/Sub dirD 0 2.176913"
- Sat 10 16:57:50.075178 Data dirs-3/Sub dirA 0 1.952396"
- Sat 10 16:57:51.786967 Data dirs-3/Sub dirB 0 1.123764"
- Sat 10 16:57:52.028138 Data dirs-3/Sub dirC 0 2.531878"
- Sat 10 16:57:52.239866 Data dirs-3/Sub dirD 0 2.297417"
- Sat 10 16:57:52.911924 Data dirs-4/Sub dirA 14 1.290787"
- Sat 10 16:57:54.203172 Data dirs-4/Sub dirB 0 2.236149"
- Sat 10 16:57:54.537597 Data dirs-4/Sub dirC 14 2.125793"
- Sat 10 16:57:54.561454 Data dirs-4/Sub dirD 0 2.49632"
= Sat 10 16:57:46.188195 Real: 10.870221", Total: 31.583813"
用于测试此脚本的伪造的rsync
注意:为了测试这个,我使用了一个伪造的rsync:
## Fake rsync wait 1.0 - 2.99 seconds and return 0-255 ~ 1x/10
rsync() { sleep $((RANDOM%2+1)).$RANDOM;exit $(( RANDOM%10==3?RANDOM%128:0));}
export -f rsync
4. 加快rsync进程的重要步骤:避免减慢它的速度!!
你可能需要一些时间来适当配置避免同步无用数据的方式!!
在man页面中搜索
exclude
和/或
include
。
--cvs-exclude, -C auto-ignore files in the same way CVS does
--exclude=PATTERN exclude files matching PATTERN
--exclude-from=FILE read exclude patterns from FILE
--include=PATTERN don't exclude files matching PATTERN
--include-from=FILE read include patterns from FILE
为了保存用户目录,我经常使用以下方法:
rsync -axz --delete --zc zstd --exclude .cache --exclude cache source/. target/.
请仔细阅读 man 手册中的
FILTER RULES
部分。
man -P'less +/^FILTER\ RULES' rsync
结论:
安静地阅读 man 手册吧!man rsync
和 man rsyncd.conf
!!
ls
命令的输出,例如使用LISTFLAGS
变量或DIR_COLORS
文件,那么您可能需要使用ls --indicator-style=none
选项来防止ls
在路径名后面添加符号(例如可执行文件的*
) 。 - chadrikrsync
之前加上--sshdelay 0.2
,以确保不会过载远程服务器上的sshd。 - pzelasko