HDFS写的high CPU之vtune的profile分析解决

公司组里最近有位同事在实现HDFS文件写的时候,发现了high CPU,达200%+。先经jprofile初步定为问题,high CPU共有两个地方。第一个是序列化/反序列化。这个问题看下来,其实是引入了一次本可避免的序列化/反序列化。这个倒是容易解决。第二个地方比较诡异,显示是在BufferedOutputStream.write的native调用上。那位同事后又尝试使用snappy压缩。令人惊奇的事发生了,采用snappy压缩后,CPU utilization竟然大幅下降。这个引起了我很大的兴趣。压缩竟然比不压缩更省CPU,岂有此理?为了一探究竟,我想起了前不久被人推荐过多次的强力profile工具——intel的vtune。话说intel的vtune真的很强大。无论对于.net/java/C/C++等诸多语言都有杀伤力,特别对于如java hotspot的性能profiling。于是在centos上装了Intel® VTune™ Amplifier XE 2013,分别对snappy压缩和非snappy压缩的writer进行性能分析。嘿嘿,其结果嘛,也真出乎我的意料。


原来问题出在了默认codec上。如果不配置默认codec,我们本来以为就不会有任何的压缩。其实不然,hadoop发现codec没有设,竟然会非常“好心”的帮你设成org.apache.hadoop.io.compress.DefaultCodec。然后问题也就自然地出现在这个DefaultCodec类实现上。该类会调用ZlibFactory的方法,进而会初始化该类。由于没有设置native zlib库,代码很不幸,转而使用java实现的BuiltInZlibDeflater,然后CPU就开始发飙。


vtune的profiling的功能当真很强大。非常明确地给出了native库中的高CPU的位置。看到了非snappy的性能结果,我们才恍然大悟。其实vtune对于java的hotspot的profile,也很直观,而且是非入侵式的。关于vtune进一步的调优,以后有时间整理再写了。


  static {

    if (NativeCodeLoader.isNativeCodeLoaded()) {
      nativeZlibLoaded = ZlibCompressor.isNativeZlibLoaded() &&
        ZlibDecompressor.isNativeZlibLoaded();
      
      if (nativeZlibLoaded) {
        LOG.info("Successfully loaded & initialized native-zlib library");
      } else {
        LOG.warn("Failed to load/initialize native-zlib library");
      }
    }
  }


采用snappy的结果:

HDFS写的high CPU之vtune的profile分析解决_第1张图片


采用默认压缩的结果:

HDFS写的high CPU之vtune的profile分析解决_第2张图片

你可能感兴趣的:(HDFS写的high CPU之vtune的profile分析解决)