• HBASE 优化之REGIONSERVER


    HBASE 优化之REGIONSERVER

     一,概述

    本人在使用优化regionserver的过程有些心得,借此随笔的机会,向大家介绍我的心得,有些是网上拿来的有些是自己在使用过程自己的经验,希望对大家有帮助,如有不同观点希望大家立即指正。本人使用的hbase版本是 HBase 1.2.0-cdh5.10.0。本文主要从regionserver的角度进行优化hbase,简单来书就是:使regionServer查询延迟更低,磁盘IO降低,系统更加稳定,提高吞吐能力,提升资源利用率,节约成本。

    二、参数优化

    磁盘读流量主要是本地regionserver业务读和compact读,写流量主要是本地regionserver写、wal、flush、compact,以及其他datanode的写副本。

    1,优化hlogs触发强制刷memstore

    设置参数hbase.regionserver.maxlogs hbase.regionserver.hlog.blocksize

    参数解释:当数据被写入的时会默认先写入wal。wal包含所有已经写入memstore但是还未flush到hfile的更改(edits)。在memstore中数据还未有持久化,当regionserver宕掉的时候,可以使用wal恢复数据。当wal变得很大的时候,在恢复的时候就需要很长的时间。因此,对wal的大小也有一些限制,当达到这些限制的时候,就会触发memstore的flush。memstore flush会使wal减少,因为数据持久化之后,就没有必要在wal中再保存这些修改,有这些属性可以配置,其中wal的最大值是由:hbase.regionserver.maxlogs * hbase.regionserver.hlog.blocksize (2GB by default) 决定,一旦达到这个值就是说,memstore flush就会触发,所以当你增加memstore的大小以及调整其他的memstore设置项的时候,你也需要去调整hlog的配置。否则,wal的大小限制可能会首先被触发,因而,你将利用不到其他专门为memstore而设计的优化。抛开这些不说,通过wal的限制来触发memstore的flush并非最佳方式,这样做可能会一次flush很多region,尽管写数据是很好的分布整个集群,进而很有可能会引发flush大风暴。最好将hbase.regionserver.hlog.blocksize * hbase.regionserver.maxlogs 设置为稍微大于hbase.regionserver.global.memstore.lowerLimit * HBASE_HEAPSIZE。

    2,jvm xx:MaxDirectMemory 调大

    众所周知jvm堆内存大小可以通过-Xmx来设置,同样direct byteBuffer可以通过-Xx:MaxDirectMemorySize来设置,此参数的含义是当Direct ByteBuffer分配的堆外内存达到指定大小的时候,即触发Full GC ,

    3,hbase.bucketcache.size 

    这个配置是指读缓存占用内存的大小,该值可以为内存真实值,单位为M,也可以是比例值,表示缓存大小占JVM内存大小比例,

    4,hfile.block.cache.size

    表示LRUBlockCache占用内存在jvm内存中的比例,目前这是唯一的LRUBlockCache,无法关闭。

    5,hbase.regionserver.global.memstore.upperLimit和hbase.regionserver.global.memstore.lowerLimit

    当一个region server中所有的memstore的大小总和上限(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默认 40%的JVM内存使用量),会触发部分memstore刷新。flush顺序是按照memstore由大到小执行,先flush最大的region,再次执行次大的,直至总体memstore内存使用量低于阈值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默认 38%的JVM内存使用量)。

    6,hbase.regionserver.handle.count

    server端处理request线程的个数,

    7,hbase.regionserver.optionalcacheflushinterval

    内存中的文件在自动刷新之前能够存活的最长时间。

    8,hbase.hregion.memstore.flush.size

    单个region里memstore的缓存大小,超过那么整个hregion就会flush。

    9,hbase.hlog.split.skip.errors =true

    如果遇到文件损坏等无法跳过去的错误,设置true,忽略之。

    10,hbase.master.distributed.log.replay

    是否启用分布式日志重播
    // 可以看出来这里面有两种模式,分布式文件恢复模式,通过zk来恢复,还有一种是recovered.edit模式,通过创建recovered.edits文件来恢复。文件恢复是通过hbase.master.distributed.log.replay参数来设置,默认是false,走的recovered.edit模式。看得出来,这个函数是为恢复做准备工作的,如果是分布式模式,就执行prepareLogReplay准备日志恢复,否则就开始创建recovered.edits恢复文件

    11,hbase.ipc.server.callqueue.handler.factor

    //如果 hbase.ipc.server.callqueue.handler.factor 为 0,那么 callExecutor 池 BalancedQueueRpcExecutor,如果 hbase.ipc.server.callqueue.handler.factor 大于 0,那么池的 executor 为 RWQueueRpcExecutor,该 executor 中分为 3 个队列:write,read 和 scan,分别通过参数 hbase.ipc.server.callqueue.read.ratio 和参数 hbase.ipc.server.callqueue.scan.ratio 进行控制,其中 hbase.ipc.server.callqueue.handler.factor 用来控制队列个数。

    12,hbase.ipc.server.callqueue.read.ratio 和hbase.ipc.server.callqueue.scan.ratio

    hbase.ipc.server.callqueue.read.ratio 设置为0.5,代表有50%的线程数处理读请求

    如果再设置hbase.ipc.server.callqueue.scan.ratio 设置为0.5,则代表在50%的读线程之中,再有50%的线程处理scan,也就是全部线程的25%

    二,垃圾回收方式优化-G1

    优化之前要说明一下:垃圾回收G1特点就是内存分片,支持动态调整young区大小,old区使用mixed gc方式分成多次小gc,尽量减少单次gc STW(stop the world)暂停时间,让gc对应用延迟的影响在预期范围内。总的来说,G1比较适合 对平均响应时间,最大响应时间有严格要求的应用系统。

    优化原则:系统调优就是从业务到实现,从整体到局部,从架构到具体组件的。在进行gc调优之前,我们应该确保业务层和应用层已经评估优化过了。业务层和应用层的优化一般来说更容易有收益,我们不能指望一个架构设计有缺陷,应用层代码有很多已知问题的系统,通过gc调优一劳永逸。GC调优3选2原则:先来看一下衡量gc的指标有哪些。对应用吞吐量的影响(一般是gc对cpu的消耗),对延迟的影响,总内存占用(gc触发时留有内存业务可以继续,留有内存做对象拷贝碎片整理等操作,不能oom)。GC调优3选2原则: 在吞吐量、延迟、内存占用上,我们只能选择其中两个进行调优,无法三者兼得。

    以下是我经过测试得出的结论:

    -Xms107374182400 -Xmx107374182400
    
    -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:MaxDirectMemorySize=100g -XX:G1NewSizePercent=5 -XX:G1MaxNewSizePercent=60 -XX:G1MixedGCCountTarget=64 
    -XX:G1OldCSetRegionThresholdPercent=4 -XX:ParallelGCThreads=63 -XX:MaxGCPauseMillis=400 -XX:+ParallelRefProcEnabled -XX:+UseStringDeduplication -XX:-ResizePLAB -XX:MaxTenuringThreshold=1
    -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2048M
    -XX:+PrintPromotionFailure -XX:+PrintGCApplicationStoppedTime -XX:+PrintSafepointStatistics
    -XX:PrintSafepointStatisticsCount=1 -XX:+PrintHeapAtGC -Xloggc:/datafs/cdh/gclog/hbase-gc.{{PID}}.log

      

    以下对上述参数的解释:

    -XX:+UnlockExperimentalVMOptions 和-XX:+UnlockDiagnosticVMOptions 

    这2个参数主要是解锁一些隐藏的参数设置。例如:查看汇编需要加入虚拟机参数  :-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssmbly

    -XX:MaxDirectMemorySize

    众所周知jvm堆内存大小可以通过-Xmx老设置,同样direct byteBuffer可以通过-Xx:MaxDirectMemorySize来设置,此参数的含义是当Direct ByteBuffer分配的堆外内存达到指定大小的时候,就触发full gc。注意该值是有上限的,默认是64M,最大为sun.misc.VM.maxDirectMemory(),在程序中可以获得 -XX:MaxDirectMemorySize的设置的值。

     

    -XX:G1NewSizePercen

    新生代内存初始空间默认整个堆内存的5%。

    -XX:G1MaxNewSizePercent

    新生代内存最大空间大小默认是60%。

    -XX:G1MixedGCCountTarget

    混合收集周期中的包含多少次混合收集的次数。设置标记周期完成后,对存活数据上限为G1MixedGCLIveThresholdPercent的老年代region执行混合垃圾回收的目标次数,默认是8次。

    -XX:G1OldCSetRegionThresholdPercent

    这个参数是设置混合垃圾回收期间要回收的最大旧区域数。默认值是10%。改小的话可以减少单次混合收集时间。

    -XX:ParallelGCThreads

    这个是STW期间,并行GC线程数,其值计算方式为:

    1),如果用户指定了其大小,则使用用户指定的值。

    2),否则需要根据实际的CPU所能够支持的线程数来计算这个值,如果CPU支持的线程数小于8,则其值为cpu所支持的线程数,如果CPU所支持的线程数大于8,其值的计算方式为:8加上物理cpu所支持的线程数减去8所得值的5/8或者5/16,JVM会根据实际的情况来选择是5/8或者5/16。比如:在64线程的x86 CPU上,如果用户未指定ParallelGCThreads的值,则默认的计算方式为:ParallelGCThreads = 8 + (64 - 8) * (5/8) = 8 + 35 = 43。

    -XX:MaxGCPauseMillis

    设置G1收集过程目标时间,默认是200ms,不是硬性条件,不是说设置越小越好,有时候设置过小反而会放大收集时间。

    -XX:+ParallelRefProcEnabled

    如果应用有很多的Reference or finalizable objects,那么可以使用-XX:+ParallelRefProcEnabled来减少duration。默认为false,并行的处理Reference对象,如WeakReference,除非在GC log里出现Reference处理时间较长的日志,否则效果不会很明显。

    -XX:+UseStringDeduplication 

    字符串去重,提高性能。我们可以通过删除重复的字符串,只保留一个char[]来优化堆内存。这个选择在Java 8 u 20被引入。

    -XX:-ResizePLAB

    减少gc线程间通信的东西,关闭动态提升本地buffer。Thread Local Allocation Buffer,简称就是:TLAB,即内存本地的持有的buffer。

    -XX:MaxTenuringThreshold

    在新生代中对象存活次数(经过Minor GC的次数)后仍然存活,就会晋升到旧生代。

    -XX:+PrintGCDetails

    打印gc过程详细信息。

    -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps

    PrintGCTimeStamps时间是从jvm启动开始计时的时间。而PrintGCDateStamps就是时间戳就是当时的时间。

    -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2048M

    开发者通过 JVM 参数 `-XX:+UseGCLogFileRotation` 实现 GC 日志轮转。指定上述参数,当日志文件大小增加到 2048MB,JVM 会进行 GC 日志轮转生成最多5个文件,扩展名分别为 `gc.log.0`、`gc.log.1`、`gc.log.2`、`gc.log.3` 和 `gc.log.4`。但是这个参数有个问题解决链接为:

    https://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651483102&idx=1&sn=4c272df4ba8527fd54f4df3364a61a3f&chksm
    =bd2507a18a528eb7ff45df8813e6bdb98c5e14dc68fa5e5c2958ad23fbd63d1b2f4982d6d6e4&mpshare=1&scene=1&srcid=#rd

      

    -XX:+PrintPromotionFailure

    看看Promotion Failed的时候是不是有很大的对象要晋升到旧生代,日志显示在晋升的时候失败。

    -XX:+PrintGCApplicationStoppedTime

    打印垃圾回收期间程序暂停的时间.可与上面混合使用。

    -XX:+PrintSafepointStatistics  -XX:PrintSafepointStatisticsCount=1

    根据-XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1 参数虚拟机打印的日志文件可以看出safepoint的执行过程,可以检测未知的错误。

    -XX:+PrintHeapAtGC

    每一次GCZ之后都会打印堆信息。

     

     

     

  • 相关阅读:
    ServletConfig类
    坑爹的去哪儿网订酒店经历
    python + opencv + pycharm +语音生成
    最近看到的工作要求
    pip in windows
    路由器外接硬盘做nas可行吗?
    阅读201706
    scrum学习
    学习concurrency programming进展
    Reactor/Proactor的比较 (ZZ)
  • 原文地址:https://www.cnblogs.com/boanxin/p/10580818.html
Copyright © 2020-2023  润新知