zoukankan      html  css  js  c++  java
  • 使用tar+lz4/pigz+ssh更快的数据传输

    使用tar+lz4/pigz+ssh更快的数据传输
    2013-11-8  |  10:41分类:Linux,MySQL  |  
    前面一篇介绍了如何最大限度的榨取SCP的传输速度,有了这个基础,就可以进一步的使用压缩来加速传输速度了。只使用scp,传输速率最快约90MB,本文通过压缩将把最快传输速率提升到约250MB/s(包括解压的过程)。
    
    目录 [hide]
    1. 结论
    2. 关于lz4
    3. 性能环境说明
    3.1 磁盘读取和落盘
    3.2 打包、拆包
    3.3 压缩、解压缩
    3.4 传输
    3.5 整体流程
    4. 实验测试
    4.1 分析
    5. lz4参数测试
    5. 为什么不用nc
    6. 还能不能更快
    附录
    参考阅读
    1. 结论
    使用tar+lz4+ssh的方式能够获得最大的传输性能:
    
    time tar -c sendlog/|pv|lz4 -B4|ssh -c arcfour128  
    -o"MACs umac-64@openssh.com" 10.xxx.xxx.36 "lz4 -d |tar -xC /u01/backup_supu"
    3.91GiB 0:00:16 [ 249MiB/s] 
    
    real    0m16.067s
    user    0m15.553s
    sys    0m16.821s
    249MB/s,妥妥的。是最原始scp(40MB/s)的6倍,原来400GB传输需要约3小时,现在只需要27分钟了。
    
    注1:lz4在解压方面的优异表现,使得他在本案例中非常重要。如果无需解压的传输,则可以考虑使用pigz/pbiz2
    
    注2:使用pv观察,网络流量约80MB,所以使用nc替换ssh并不会有明显的性能提升
    
    注3:lz4压缩使用-B4(64KB块大小),解压使用-B7(4MB块大小),是本案例的测试最优值
    
    2. 关于lz4
    lz4是一个让"人见人爱、花见花开"的压缩算法,能够在多核上很好的扩展,压缩速度和压缩比并没有太大优势(pigz),但是他的解压速度非常惊人,本案例测试lz4的解压是gunzip的3倍(更多的对比测试)。因为压缩时高效的多核利用,再加上惊艳的解压,lz4已经在非常多重要场合使用了:Linux3.11内核实现了LZ4,并可以使用其压缩和解压kernel image HBase:Add an LZ4 compression option to HFile等等(参考)。
    
    对于需要频繁压缩、实时快速解压的场景来说,lz4非常适合。
    
    3. 性能环境说明
    这里使用同上一篇文章相同的两台主机环境:ping获得RTT是17ms;使用iperf测试带宽是115MB(参考附录);
    
    整个过程有几个阶段:磁盘读取-->打包(tar)-->压缩-->传输-->解压缩-->拆包-->落盘 对应了的速度测试:
    
    3.1 磁盘读取和落盘
    磁盘读取(有page cache),能到3GB/s;磁盘写入约428MB:
    
    # dd if=./sendlog.tar of=/dev/null bs=4096 count=1048576
    1024002+1 records in
    1024002+1 records out
    4194314240 bytes (4.2 GB) copied, 1.33946 s, 3.1 GB/s
    
    # dd if=/dev/zero of=./x.zero.file bs=4096 count=1048576
    1048576+0 records in
    1048576+0 records out
    4294967296 bytes (4.3 GB) copied, 10.0306 s, 428 MB/s
    3.2 打包、拆包
    打包和拆包速度都大于350MB/s:
    
    # time tar -cf sendlog.tar ./sendlog/
    real    0m10.996s
    # time tar -xf sendlog.tar
    real    0m11.564s
    3.3 压缩、解压缩
    关于各个压缩工具的性能(压缩、解压、压缩率)已经有很多人做了比较,本文不做详细讨论,这里选择gzip/pigz lz4 bzip做本测试的比较:
    
               | input speed | output speed | rate   | speed of decoder
    pigz -p 16 | 327.0MB/s   | 57.2MB/s     | 17.5%  | 95  MB/s
    lz4        | 288.0MB/s   | 79.2MB/s     | 27.5%  | 264 MB/s
    bzip2      |   4.9MB/s   | 0.65MB/s     | 13.1%  | 25.6MB /s
    压缩工具的比较测试参考:Gzip vs Bzip2 vs LZMA vs XZ vs LZ4 vs LZO
    
    可以看到,lz4在压缩率上略微逊色(对比pigz),但是在解压速度上有这惊人的优势。
    
    3.4 传输
    前文介绍了scp,约90MB最快的传输速度。
    
    3.5 整体流程
    磁盘读取---->打包---->压缩------>传输---->解压缩-->拆包---->落盘
                 |->tar   |->gzip    |->ssh   |->gzip  |->tar
                          |->bzip2   |->http  |->bzip
                          |-> ...    |->nc    |->...
                          |->lz4              |->lz4
    >400MB/s    >350MB/s  79MB/s     90MB/s   72MB/s    >350MB/s >400MB/s
    这里可以看到,解压是最大的瓶颈,使用在解压方面最有优势的压缩工具,能让传输获得最大速度。而lz4正是在解压效率方面有着巨大的优势。
    
    按照上面lz4的测试,传输速度理论值为264MB/s(此时传输速度为264*27.3%=72MB),这也是本次测试的理论上限速度。
    
    4. 实验测试
    使用lz4压缩传输:
    
    # time tar -c sendlog/|lz4|ssh -c arcfour128 
     -o"MACs umac-64@openssh.com" 10.xxx.xx.36 "lz4 -d |tar -xC /u01/backup_supu"
    real    0m25.646s
    real    0m25.911s
    real    0m29.019s
    测试三次,分别耗时26s、29s、25.6s,传输的平均速度为:152MB/s,网络带宽占用约41.9MB/s。
    
    使用pigz的压缩传输:
    
    # time tar -c sendlog/|pigz -p 16|ssh -c arcfour128 
     -o"MACs umac-64@openssh.com" 10.xxx.xx.36 "gzip -d|tar -xC /u01/backup_supu"
    rreal    0m37.030s
    real    0m25.911s
    real    0m29.019s
    测试三次,分别耗时37s、37.2s、35.6s,传输的平均速度为:110.7MB/s,网络带宽占用约19.4MB/s。
    
    对比发现,在压缩方面pigz与lz4并没有太大区别,但是lz4解压速度非常快,所以在这种需要立刻解压的场景下,lz4轻松胜出(bzip2这种就不需要测试了)。
    
    4.1 分析
    按照第二节中的理论分析,传输速度应该能到260MB,但是上面只有152MB/s,这说明,还有调优的空间。继续分析,看看瓶颈在哪儿:
    
    使用pv工具观察到,tar+lz4有约70MB/s的输出:
    
     time tar -c sendlog/|lz4|pv > /dev/null
    1.02GiB 0:00:14 [70.8MiB/s] [                                 <=>]
    比直接lz4输出,要慢了10%左右(lz约79MB/s)。
    
    再加上一次网络ssh:
    
    time tar -c sendlog/|lz4|pv|ssh -c arcfour128 -o "MACs umac-64@openssh.com" 10.xxx.xxx.36 "cat - >/dev/null"
    1.02GiB 0:00:23 [43.9MiB/s] [                                 <=>]
    比直接lz4输出,要慢了45%左右(lz约79MB/s);远端再加上解压和拆包,压缩后的传输速度就是41.9MB/s。为什么会下降,还不明了,作者也还没有想到有什么方法能够直接加速这样的管道传输,如果看客有什么建议,不妨分享,看看还能不能优化,继续提升速度。
    
    至此,传输速度就能够到150MB/s。比最原始scp(40MB/s)要快了约4倍,原来400GB需要约3小时,现在只需要45分钟了。
    
    5. lz4参数测试
    前面试验发现,整个流程中lz4压缩比预期的要慢45%左右,而这里区别仅仅是一个使用管道(pipe)、一个直接读取。这里尝试通过修改lz4块大小对比,是否有性能提升:
    
    lz4-with-different-block-size
    
    测试命令:
    
    for i in `seq 4 7`; do time tar -c ./sendlog/|lz4 -B$i |pv > /dev/null ;done
    1.07GiB 0:00:11 [94.4MiB/s] [                          <=>]
    real    0m11.640s
    user    0m10.375s
    sys    0m4.308s
    可以看到块大小为64KB的时候,lz的压缩速度有显著提升(31%)。于是,我们在lz4新增参数-B4,看看是否能够提升性能:
    
    Bang!确实,传输性能提升到了约249MB/s:
    
    time tar -c sendlog/|pv|lz4 -B4|ssh -c arcfour128  
    -o"MACs umac-64@openssh.com" 10.xxx.xxx.36 "lz4 -d |tar -xC /u01/backup_supu"
    3.91GiB 0:00:16 [ 249MiB/s] 
    
    real    0m16.067s
    user    0m15.553s
    sys    0m16.821s
    5. 为什么不用nc
    就不用它!!!
    
    * nc不比ssh快;如果压缩后传输,nc比ssh没有优势
    
    * nc在脚本中不好调用,需要在两端执行命令
    
    * nc需要一个额外的网络端口
    
    * nc不加密
    
    6. 还能不能更快
    本案例中,lz4解压缩的速度是264MB/s,这里能够达到249MB/s,应该还有一点点可以榨取,不过我已经没有招了。
    
    附录
    iperf的带宽测试:
    
    iperf -c 10.xxx.xx.18 -p 3999 -t 30
    ------------------------------------------------------------
    Client connecting to 10.xxx.xx.18, TCP port 3999
    TCP window size: 16.0 KByte (default)
    ------------------------------------------------------------
    [  3] local 10.xx.xx.36 port 43838 connected with 10.xx.xx.18 port 3999
    [ ID] Interval       Transfer     Bandwidth
    [  3]  0.0-30.0 sec  3.15 GBytes   903 Mbits/sec
    
    iperf -s -p 3999 -m
    ------------------------------------------------------------
    Server listening on TCP port 3999
    TCP window size: 85.3 KByte (default)
    ------------------------------------------------------------
    [  4] local 10.xx.xx.18 port 3999 connected with 10.xx.xx.36 port 43838
    [ ID] Interval       Transfer     Bandwidth
    [  4]  0.0-30.0 sec  3.15 GBytes   902 Mbits/sec
    [  4] MSS size 1448 bytes (MTU 1500 bytes, ethernet)
    参考阅读
    * lz4@Google code
    
    * lz4's details
    
    * LZ4 Streaming Format
    
    * Quick Benchmark: Gzip vs Bzip2 vs LZMA vs XZ vs LZ4 vs LZO
    
    * lz4: Extremely Fast Compression algorithm
    
    喜欢本文,那就收藏到:
  • 相关阅读:
    C# 集合类 :(Array、 Arraylist、List、Hashtable、Dictionary、Stack、Queue)
    "Isa"与"Hasa"
    Access、SQLite、HSQLDB、Sybase、MySQL、DB4O比较
    C#反射(二)
    跳出语句
    C#反射(一)
    返回集合使用IEnumerable<>还是IList<>
    理解C#值类型与引用类型
    WF4 Beta2 工作原理
    Interesting thing with WF4 Activity Scheduling
  • 原文地址:https://www.cnblogs.com/archoncap/p/4916563.html
Copyright © 2011-2022 走看看