將scp傳輸速度發揮到極致

看了大佬提高SCP傳輸速度的文章php

使用tar+lz4/pigz+ssh更快的數據傳輸:mysql

http://www.orczhou.com/index.php/2013/11/tranfer-data-faster-on-the-fly/sql

加速scp傳輸速度:bash

http://www.orczhou.com/index.php/2013/11/make-scp-faster-with-cipher-and-compression/併發

[root@mysql141 binlog]# time scp -r mysql-bin.000214 172.25.2.142:/opt/soft/test_scp/
mysql-bin.000214                                                                 100% 1024MB 126.0MB/s   00:08    
real    0m8.331s
user    0m6.597s
sys     0m2.721s
[root@mysql141 binlog]# time scp -r -c aes192-cbc mysql-bin.000214 172.25.2.142:/opt/soft/test_scp/
mysql-bin.000214                                                                 100% 1024MB 177.4MB/s   00:05    
real    0m5.959s
user    0m4.444s
sys     0m2.825s
[root@mysql141 binlog]# time tar -c mysql-bin.000214|lz4 -B4|ssh -c aes192-cbc 172.25.2.142 "lz4 -d |tar -xC /opt/soft/test_scp"
using blocks of size 64 KB 
real    0m4.024s
user    0m5.049s
sys     0m2.634s


閒來無事,想着scp爲串行方式,能否使用並行方式再進一步提高速度,作了以下實驗:ssh

192.168.11.81讀:ide

dd if=20210331.txt of=/dev/null bs=1M count=1000工具

1.8 GB/s性能

scp傳輸:測試

scp -c aes192-cbc 20210331.txt 192.168.11.82:~/

20210331.txt                     100% 1000MB 114.2MB/s   00:08

192.168.11.82寫:

dd if=/dev/zero of=20210331.txt bs=1M count=1000

892 MB/s

總體流程

磁盤讀取--------->scp傳輸--------->落盤

>1.8 GB/s       >114.2MB/s       >892 MB/s

瓶頸仍是在scp傳輸上,看看iperf測試帶寬狀況,114.2MB/s 明顯沒達到帶寬極限

ethtool eth0|grep Speed

 Speed: 1000Mb/s 

iperf -c 192.168.11.82 -t 60 -f M

[ ID] Interval       Transfer     Bandwidth

[  3]  0.0-60.0 sec  28010 MBytes   467 MBytes/sec

iperf -c 192.168.11.82 -P 10 -t 60 -f M 

[ ID] Interval       Transfer     Bandwidth

[SUM]  0.0-60.0 sec  29660 MBytes   494 MBytes/sec

如今想辦法把scp傳輸這一過程速度發揮到極致,對比串行和並行的速度狀況

造測試數據,10個1000M的文件:

for i in {1..10}
do
 dd if=/dev/zero of=${i}_20210331.txt bs=1M count=1000
done

常規串行執行:

time scp -r -c aes192-cbc *_20210331.txt 192.168.11.82:~/
10_20210331.txt                   100% 1000MB  70.1MB/s   00:14    
1_20210331.txt                    100% 1000MB  75.7MB/s   00:13    
2_20210331.txt                    100% 1000MB  83.3MB/s   00:12    
3_20210331.txt                    100% 1000MB  76.6MB/s   00:13    
4_20210331.txt                    100% 1000MB  78.1MB/s   00:12    
5_20210331.txt                    100% 1000MB  76.6MB/s   00:13    
6_20210331.txt                    100% 1000MB  76.8MB/s   00:13    
7_20210331.txt                    100% 1000MB  83.2MB/s   00:12    
8_20210331.txt                    100% 1000MB  77.3MB/s   00:12    
9_20210331.txt                    100% 1000MB  83.3MB/s   00:12

real    2m11.144s

user    1m2.778s

sys     1m20.256s

編寫並行執行腳本parallel_scp.sh,內容和執行方式以下:

#腳本傳值依次是:文件名(支持通配符) 目標IP 目標路徑 scp併發數

sh parallel_scp.sh '*_20210331.txt' 192.168.11.82 '/root/' 10

cat parallel_scp.sh
#!/bin/bash
fileName=$1
remoteHost=$2
remoteDir=$3
maxScp=$4
ls ${fileName} > filelist.lst
cat filelist.lst | while read line
do
scpNum=`ps -ef| awk '{print $8}' |grep ^scp|egrep -v 'grep|tail'|wc -l`
while [ ${scpNum} -ge ${maxScp} ]
do
  sleep 5
  scpNum=`ps -ef| awk '{print $8}' |grep ^scp|egrep -v 'grep|tail'|wc -l`
done
scpFileName=`echo ${line}| awk '{print "scp_"$0".sh"}'`
echo "scp -r -c aes192-cbc ${line} ${remoteHost}:${remoteDir}" >  ${scpFileName}
time nohup sh ${scpFileName} > ${scpFileName}.out 2>&1 &
#echo "當前進度:nohup sh ${scpFileName} > ${scpFileName}.out &"
done
#echo "傳輸完成。"


sh parallel_scp.sh '*_20210331.txt' 192.168.11.82 '/root/' 10

real    1m12.449s

user    0m5.911s

sys     0m5.150s

經過理論和測試實驗的執行時間來看,並行的scp會比串行時間快。


以上都是基於文件大小相同,若須要傳輸的文件大小不一,要是並行執行時,同一批並行的都是大文件,或者都是小文件,傳輸速度確定是不均衡的,下面考慮把同一批並行的文件組合成大小差很少

ls -lS /root/*_20210331.txt|awk '{print $9}' > 123456.txt--按文件大小排序,由大到小倒序排

123456.txt 存在100行,內容爲

/root/1_20210331.txt --10G

/root/2_20210331.txt --9G

....

/root/100_20210331.txt --1MB


awk '{lines[NR]=$0} END{i=50; while(i>0){print lines[i];--i}}' 123456.txt >p1.txt  --倒序排列文件,100個文件中前50大小的文件倒序排

awk '{lines[NR]=$0} END{j=51; while(j<101){print lines[j];++j}}' 123456.txt >p2.txt --順序排列文件,100個文件中前50大小的文件順序排

方法一:

paste -d "\n" p1.txt p2.txt >c.txt --逐行交叉合併兩文件,c.txt的內容爲均分大小後的文件排序

方法二(unix環境不必定存在paste命令):

將兩個文件的內容按行交叉合併

for ((i=1;i<=$line;i++));do

cat a.txt | tail -n +$i |head -n 1 >>c.txt  #提取p1.txt的第i行,追加到c.txt

cat b.txt | tail -n +$i |head -n 1 >>c.txt  #提取p2.txt的第i行,追加到c.txt

done

這裏最後的c.txt,替換到腳本里面的filelist.lst,就能夠調用parallel_scp.sh執行了。


總結:

一、這裏採用並行把scp速度發揮到極致,並未考慮性能影響,生產環境須要謹慎使用。

二、對於很大的二進制文件(data類型),考慮使用tar+lz4/pigz+ssh數據傳輸。

三、類比,對於相同串行執行的ftp、sftp等傳輸工具,也可考慮使用該方式,腳本稍微改一下就行。

相關文章
相關標籤/搜索