今天有15G的资料需要先传递到服务器上,琢磨着怎么能更快的上传完成,最后总结了一下方法,确实比直接scp传递效率高很多,从直接scp速度是40M/s,到参照参考文章利用lz4变成93M,最后换成zstd变成了152M,效果很棒,语句如下

1
2
tar -c gh/ |pv| zstd -9 -T0 |ssh -c chacha20-poly1305@openssh.com  
-o "MACs umac-64@openssh.com" clickhouse "zstd -d | tar -xC /tmp/xx"

反向

1
2
ssh -c chacha20-poly1305@openssh.com  -o "MACs umac-64@openssh.com" remote 
"cat /data/filename | zstd -T0" | pv | zstd -d > filename

一般传文件会有两种选择,scp和rsync,scp最基础,rsync主要是增加了块计算,实现了增量传输。增量传输是rsync的优点,在某些场景却也是它的致命伤,为了计算区别,rsync不得不读取要传输的文件信息,对比之后再决定传哪一块,这种方式就对流传输不友好,无法做到边生成文件边传输的作用

加速传输的主要思路是,将文件压缩后再上传,但是一般的压缩上传又要分为几个步骤

  1. 本地压缩
  2. scp上传
  3. 远程解压

每次上传一个文件需要执行三条命令很烦躁,而且绝大多数情况下上传的速度是很慢的,我们完全可以做到边压缩边上传,这样就节约了时间。在无损压缩算法里面最近几年新出的zstd算法可谓是完爆各类压缩算法,看官方benchmark图就知道性能差异了

Compressor name Ratio Compression Decompress.
zstd 1.3.4 -1 2.877 470 MB/s 1380 MB/s
zlib 1.2.11 -1 2.743 110 MB/s 400 MB/s
brotli 1.0.2 -0 2.701 410 MB/s 430 MB/s
quicklz 1.5.0 -1 2.238 550 MB/s 710 MB/s
lzo1x 2.09 -1 2.108 650 MB/s 830 MB/s
lz4 1.8.1 2.101 750 MB/s 3700 MB/s
snappy 1.1.4 2.091 530 MB/s 1800 MB/s
lzf 3.6 -1 2.077 400 MB/s 860 MB/s

压缩快的没它压缩率高,而且解压速度还贼快,很适合流式处理的场景

再看它的压缩级别和压缩率曲线
zstd_compression_rate

我个人觉得上图中第9个点很有意思,压缩率3.5, 压缩速率为64M/s, 压缩率很高,压缩文件速率也很快,
比如我用5G Wifi无线网络连接内网服务器,传输速度是40M/s,这个时候假如选择了压缩率为9,压缩速率为64,压缩后就只有18M了,浪费了40M/s的性能,所以这种情况应该选择低压缩率占满带宽,假如是上传到云服务器,可能上传速度只有2M/s,这个时候就可以选择更高的压缩率10或者11,但不能选择太大,应该极限情况下压缩文件速率只有5M/s, 因此选择怎样的压缩速率由原始上传速率决定

注意: 以上讨论的时候文件能够被压缩节省空间的情况下,如果你本来就是传输已经被压缩过的文件,比如mp4, 那么启用压缩很可能得不偿失

在内网某些情况下,也有人赞成不启用压缩进行传输,看这个链接 , 但是我个人觉得,在有zstd这么优秀的压缩算法加持下,对于可以压缩的文件,加上zstd肯定不会亏

另外,使用zstd需要本机和远程机器同时安装zstd osx: brew install zstd ubuntu: sudo apt install zstd

其他就是ssh传输参数的调节了,因为ssh会话是安全加密的,加密性越强的算法性能一般会越低,所以一般而言,换成更低级别的加密强度会获得更好的性能,当然用更优秀的算法在不损失安全性的情况下也能获得更好的性能,本来性能最好的是arcfour(有安全问题),但是这玩意儿已经被弃用了,综合之下选择chacha20-poly1305@openssh.com这个速度也挺好

MACs umac-64@openssh.com 这个参数就是参照一篇13年的文章了,具体我没有测试过

总结

使用流式压缩,边压缩边传输边解压,修改ssh传输配置, 让传输更快

扩展

如果你经常使用ssh协议传大量文件,把它加到ssh配置里面其实不错,这样就能减少命令行参数了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
参照相关资料照抄的配置
Host *
Port 22
User root
StrictHostKeyChecking no
IdentityFile ~/.ssh/id_rsa
ConnectTimeout 15
ConnectionAttempts 3
ServerAliveInterval 20
ServerAliveCountMax 5
# 多条连接共享
ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
# 长连接(退出服务器后连接依然可重用)
ControlPersist 4h
# 减少延迟
GSSAPIAuthentication no
# 选择合适的Ciphers和MACs http://www.wreck.net/ssh_speed
Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com
MACs umac-128-etm@openssh.com,umac-128@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1,hmac-sha2-512-etm@openssh.com,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-256
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
HostKeyAlgorithms ssh-ed25519,ssh-rsa
ChallengeResponseAuthentication no
UseRoaming no

相关资料

使用tar+lz4/pigz+ssh更快的数据传输
ssh-cipher-benchmark.sh
另一个测试