看了大佬提高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等傳輸工具,也可考慮使用該方式,腳本稍微改一下就行。