欢迎投稿

今日深度:

HBASE性能优化之最佳内存实践,hbase性能优化实践

HBASE性能优化之最佳内存实践,hbase性能优化实践


最近生产上rs服务频繁挂,都是因为gc时间过久导致的session超时,其实服务是好的,只是被zk认为死了,所以rs自己也就把自己kill了

  首先会考虑到调高Session的容忍度,默认180000其实这个回话有效期已经够长的了,但是有的集群是可以

   降低了这个值,可能会造成Session 超时,这个参数是 zookeeper.session.timeout 默认18000。           针对上面这个参数,有的博文认为即使设为180000也不能真正的达到目的,因为zookeeper 会将minSessionTimeout 设为 2*ticktimes ,而将maxSessionTimeout 设为    20*ticktimes 当 zookeeper.session.timeout 设置超过20*ticktimes 的时候,系统会取 min(zookeeper.session.timeout,20*ticktimes) 来出来。           针对上述观点,我从源码中找到了结论,首先如果是分布式的Hbase那 会启动HQuorumPeer 进程 看下这个源码:
    •           HQuorumPeer.main 方法中会调用 writeMyID(zkProperties) ,而就在此方法中已经将 maxSessionTimeout设置为 zookeeper.session.timeout 的时长。
    •           调用HQuorunPeer.runZKServer
    •           调用QuorumPeerMain.runFromConfig
    •           设置quorumPeer.setMaxSessionTimeout(config.getMaxSessionTimeout());
    •           由此可看此件并没有直接和tickTime对比的机会。倒是minSessionTimeout没有设置,默认是2*ticktime
          由此可见 其实如果设置了Zookeeper.session.timeout的话 不会轻易去截取20*ticktime,再不信可以用echo conf|nc zserver 2181 看一下 zookeeper系统参数        

 其实,真正要解决的是gc导致的停止,hbase中不能有较长的gc等待,具体的gc经过实践,可以参考以下配置:

我们目前的系统是使用export HBASE_HEAPSIZE=16384,16G的内存,这个数字从哪来呢?相信这还得查看官网,官网不是万能的,但不看官网是万万不能的。一下是官网的一段话: 
   Thus, ~20-24Gb or less memory dedicated to one RS is recommended
        我的英文不是很好,前一句的大概意思是regionserver因为GC的原因不能分配太大的内存,这句就不用我翻译了吧。20~24GB或者更小比较适合。嘿嘿。当然这个参数跟很多因素有关,以后我会再深入总结影响这个内存参数的因素。姑且先这么多。

  2)GC配置
        不要以为配置了上面的参数就完了,因为你可能会遇到很多情况。比如OOM。为什么?这就要说到java的内存机制了,简要说说吧,以后会有JVM调优的专题。
        
        上图是JVM 分代垃圾收集系统的图表,简要说一下:

        这里有 3 个堆分代:Perm(或是 Permanent)代【永久代】,Old Generation 代【老年代】,和 Young 代【年轻代】。年轻代由三个独立的空间组成,Eden 空间和两个 survivor 空间,S0 和 S1
        通常,对象被分配在年轻代的 Eden 空间,如果一个分配失败(Eden 满了),所有 java 线程停止,并且一个年轻代 GC(Minor GC)被调用。所有在年轻代存活的对象(Eden 和 S0 空间)被拷贝到 S1 空间。如果 S1 空间满了,对象被拷贝(提升)到老年代。当这个提升失败,老年代被收集(Major/Full GC)。永久代和老年代通常一起被收集。永久代被用于在存放类和对象中定义的方法。

        回到本话题,我们设置GC的参数为
        export HBASE_OPTS="$HBASE_OPTS -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseParNewGC -XX:ParallelGCThreads=6"
        简要说明一下,
        -XX:+UseConcMarkSweepGC 表示年老代并发收集
        对于老年代来说, 它可以更早的开始回收。当分配在老年代的空间比率超过了一个阀值,CMS 开始运行。如果 CMS 开始的太晚,HBase 或许会直接进行 full garbage collection。这种情况会导致block所有的线程,如果这个时间过长,就会导致hbase连接超时,结果就是regionserver集体下线。这是不能容忍额。为了避免这种情况的发生,我们建议设置 -XX:CMSInitiatingOccupancyFraction JVM 参数来精确指定在多少百分比 CMS 应该被开始,正如上面的配置中做的那样。在 百分之 60 或 70 开始是一个好的实践。当老年代使用 CMS,默认的年轻代 GC 将被设置成 Parallel New Collector。
        再来看看hbase为什么可能进行full gc,如果我们不配置-XX:CMSInitiatingOccupancyFraction,jdk1.5以后会使用默认值90%,那么很可能,当老年代内存占用超过分配给他的内存大小的90%,会进行CMS(老年代的回收),但是不会阻止年轻代到老年代的迁移,如果迁移过快,CMS较慢,会出现老年代内存使用率100%,这时会导致full gc。如果我们把这个参数调整小一点,那么能给年轻带到老年代迁移的同时做CMS时一些时间,也就减少了full gc的发生。当然这可能会频繁的gc,但总比整个hbase挂掉的好不是么?

         对于一般应用,如下配置运行稳定:

    • export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE -Xmx2000m -Xms2000m -Xmn750m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70"
    • export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Xmx20000m -Xms20000m -Xmn1000m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70" 

      -XX:+UseCMSInitiatingOccupancyOnly





 



www.htsjk.Com true http://www.htsjk.com/hbase/35937.html NewsArticle HBASE性能优化之最佳内存实践,hbase性能优化实践 最近生产上rs服务频繁挂,都是因为gc时间过久导致的session超时,其实服务是好的,只是被zk认为死了,所以rs自己也就把自己kill了  ...
相关文章
    暂无相关文章
评论暂时关闭