一、服务端调优

  1、参数配置
    1)、hbase.regionserver.handler.count:该设置决定了处理RPC的线程数量,默认值是10,通常可以调大,比如:150,当请求内容很大(上MB,比如大的put、使用缓存的scans)的时候,如果该值设置过大则会占用过多的内存,导致频繁的GC,或者出现OutOfMemory,因此该值不是越大越好。

    2)、hbase.hregion.max.filesize :配置region大小,0.94.12版本默认是10G,region的大小与集群支持的总数据量有关系,如果总数据量小,则单个region太大,不利于并行的数据处理,如果集群需支持的总数据量比较大,region太小,则会导致region的个数过多,导致region的管理等成本过高,如果一个RS配置的磁盘总量为3T*12=36T数据量,数据复制3份,则一台RS服务器可以存储10T的数据,如果每个region最大为10G,则最多1000个region,如此看,94.12的这个默认配置还是比较合适的,不过如果要自己管理split,则应该调大该值,并且在建表时规划好region数量和rowkey设计,进行region预建,做到一定时间内,每个region的数据大小在一定的数据量之下,当发现有大的region,或者需要对整个表进行region扩充时再进行split操作,一般提供在线服务的hbase集群均会弃用hbase的自动split,转而自己管理split。

    3)、hbase.hregion.majorcompaction:配置major合并的间隔时间,默认为1天,可设置为0,禁止自动的major合并,可手动或者通过脚本定期进行major合并,有两种compact:minor和major,minor通常会把数个小的相邻的storeFile合并成一个大的storeFile,minor不会删除标示为删除的数据和过期的数据,major会删除需删除的数据,major合并之后,一个store只有一个storeFile文件,会对store的所有数据进行重写,有较大的性能消耗。

    4)、hbase.hstore.compactionThreshold:HStore的storeFile数量>= compactionThreshold配置的值,则可能会进行compact,默认值为3,可以调大,比如设置为6,在定期的major compact中进行剩下文件的合并。

    5)、 hbase.hstore.blockingStoreFiles:HStore的storeFile的文件数大于配置值,则在flush memstore前先进行split或者compact,除非超过hbase.hstore.blockingWaitTime配置的时间,默认为7,可调大,比如:100,避免memstore不及时flush,当写入量大时,触发memstore的block,从而阻塞写操作。

    6)、hbase.regionserver.global.memstore.upperLimit:默认值0.4,RS所有memstore占用内存在总内存中的upper比例,当达到该值,则会从整个RS中找出最需要flush的region进行flush,直到总内存比例降至该数限制以下,并且在降至限制比例以下前将阻塞所有的写memstore的操作,在以写为主的集群中,可以调大该配置项,不建议太大,因为block cache和memstore cache的总大小不会超过0.8,而且不建议这两个cache的大小总和达到或者接近0.8,避免OOM,在偏向写的业务时,可配置为0.45,memstore.lowerLimit保持0.35不变,在偏向读的业务中,可调低为0.35,同时memstore.lowerLimit调低为0.3,或者再向下0.05个点,不能太低,除非只有很小的写入操作,如果是兼顾读写,则采用默认值即可。

    7)、hbase.regionserver.global.memstore.lowerLimit:默认值0.35,RS的所有memstore占用内存在总内存中的lower比例,当达到该值,则会从整个RS中找出最需要flush的region进行flush,配置时需结合memstore.upperLimit和block cache的配置。

    8)、file.block.cache.size:RS的block cache的内存大小限制,默认值0.25,在偏向读的业务中,可以适当调大该值,具体配置时需试hbase集群服务的业务特征,结合memstore的内存占比进行综合考虑。

    9)、hbase.hregion.memstore.flush.size:默认值128M,单位字节,超过将被flush到hdfs,该值比较适中,一般不需要调整。

    10)、hbase.hregion.memstore.block.multiplier:默认值2,如果memstore的内存大小已经超过了hbase.hregion.memstore.flush.size的2倍,则会阻塞memstore的写操作,直到降至该值以下,为避免发生阻塞,最好调大该值,比如:4,不可太大,如果太大,则会增大导致整个RS的memstore内存超过memstore.upperLimit限制的可能性,进而增大阻塞整个RS的写的几率。如果region发生了阻塞会导致大量的线程被阻塞在到该region上,从而其它region的线程数会下降,影响整体的RS服务能力,例如:

    开始阻塞:  

    

  解开阻塞:

    

  从10分11秒开始阻塞到10分20秒解开,总耗时9秒,在这9秒中无法写入,并且这期间可能会占用大量的RS handler线程,用于其它region或者操作的线程数会逐渐减少,从而影响到整体的性能,也可以通过异步写,并限制写的速度,避免出现阻塞。

    11)、hfile.block.index.cacheonwrite:在index写入的时候允许put无根(non-root)的多级索引块到block cache里,默认是false,设置为true,或许读性能更好,但是是否有副作用还需调查。

    12)、io.storefile.bloom.cacheonwrite:默认为false,需调查其作用。

    13)、hbase.regionserver.regionSplitLimit:控制最大的region数量,超过则不可以进行split操作,默认是Integer.MAX,可设置为1,禁止自动的split,通过人工,或者写脚本在集群空闲时执行。如果不禁止自动的split,则当region大小超过hbase.hregion.max.filesize时会触发split操作(具体的split有一定的策略,不仅仅通过该参数控制,前期的split会考虑region数据量和memstore大小),每次flush或者compact之后,regionserver都会检查是否需要Split,split会先下线老region再上线split后的region,该过程会很快,但是会存在两个问题:1、老region下线后,新region上线前client访问会失败,在重试过程中会成功但是如果是提供实时服务的系统则响应时长会增加;2、split后的compact是一个比较耗资源的动作。

    14)、Jvm调整
      a、内存大小:master默认为1G,可增加到2G,regionserver默认1G,可调大到10G,或者更大,zk并不耗资源,可以不用调整;
      b、垃圾回收:待研究。

  2、其它调优

    1)、列族、rowkey要尽量短,每个cell值均会存储一次列族名称和rowkey,甚至列名称也要尽量短,以下截图是表test2的数据和存入hdfs后的文件内容:

      

    由上图可见:短的列族名称、rowkey、列名称对最终的文件内容大小影响很大。

       

    2)、RS的region数量:一般每个RegionServer不要过1000,过多的region会导致产生较多的小文件,从而导致更多的compact,当有大量的超过5G的region并且RS总region数达到1000时,应该考虑扩容。

    3)、建表时:
      a、如果不需要多版本,则应设置version=1;
      b、开启lzo或者snappy压缩,压缩会消耗一定的CPU,但是,磁盘IO和网络IO将获得极大的改善,大致可以压缩4~5倍;
      c、合理的设计rowkey,在设计rowkey时需充分的理解现有业务并合理预见未来业务,不合理的rowkey设计将导致极差的hbase操作性能;
      d、合理的规划数据量,进行预分区,避免在表使用过程中的不断split,并把数据的读写分散到不同的RS,充分的发挥集群的作用;
      e、列族名称尽量短,比如:“f”,并且尽量只有一个列族;
      f、视场景开启bloomfilter,优化读性能。

二、Client端调优

  1、hbase.client.write.buffer:写缓存大小,默认为2M,推荐设置为6M,单位是字节,当然不是越大越好,如果太大,则占用的内存太多;

  2、hbase.client.scanner.caching:scan缓存,默认为1,太小,可根据具体的业务特征进行配置,原则上不可太大,避免占用过多的client和rs的内存,一般最大几百,如果一条数据太大,则应该设置一个较小的值,通常是设置业务需求的一次查询的数据条数,比如:业务特点决定了一次最多100条,则可以设置为100

  3、设置合理的超时时间和重试次数,具体的内容会在后续的blog中详细讲解。

  4、client应用读写分离
    读和写分离,位于不同的tomcat实例,数据先写入redis队列,再异步写入hbase,如果写失败再回存redis队列,先读redis缓存的数据(如果有缓存,需要注意这里的redis缓存不是redis队列),如果没有读到再读hbase。
    当hbase集群不可用,或者某个RS不可用时,因为HBase的重试次数和超时时间均比较大(为保证正常的业务访问,不可能调整到比较小的值,如果一个RS挂了,一次读或者写,经过若干重试和超时可能会持续几十秒,或者几分钟),所以一次操作可能会持续很长时间,导致tomcat线程被一个请求长时间占用,tomcat的线程数有限,会被快速占完,导致没有空余线程做其它操作,读写分离后,写由于采用先写redis队列,再异步写hbase,因此不会出现tomcat线程被占满的问题, 应用还可以提供写服务,如果是充值等业务,则不会损失收入,并且读服务出现tomcat线程被占满的时间也会变长一些,如果运维介入及时,则读服务影响也比较有限。

  5、如果把org.apache.hadoop.hbase.client.HBaseAdmin配置为spring的bean,则需配置为懒加载,避免在启动时链接hbase的Master失败导致启动失败,从而无法进行一些降级操作。

  6、Scan查询编程优化:
    1)、调整caching;
    2)、如果是类似全表扫描这种查询,或者定期的任务,则可以设置scan的setCacheBlocks为false,避免无用缓存;
    3)、关闭scanner,避免浪费客户端和服务器的内存;
    4)、限定扫描范围:指定列簇或者指定要查询的列;
    5)、如果只查询rowkey时,则使用KeyOnlyFilter可大量减少网络消耗;

作为hbase依赖的状态协调者ZK和数据的存储则HDFS,也需要调优:

ZK调优:
  1、zookeeper.session.timeout:默认值3分钟,不可配置太短,避免session超时,hbase停止服务,线上生产环境由于配置为1分钟,出现过2次该原因导致的hbase停止服务,也不可配置太长,如果太长,当rs挂掉,zk不能快速知道,从而导致master不能及时对region进行迁移。

  2、zookeeper数量:至少5个节点。给每个zookeeper 1G左右的内存,最好有独立的磁盘。 (独立磁盘可以确保zookeeper不受影响).如果集群负载很重,不要把Zookeeper和RegionServer运行在同一台机器上面。就像DataNodes 和 TaskTrackers一样,只有超过半数的zk存在才会提供服务,比如:共5台,则最多只运行挂2台,配置4台与3台一样,最多只运行挂1台。

  3、hbase.zookeeper.property.maxClientCnxns:zk的最大连接数,默认为300,可配置上千

hdfs调优:

  1、dfs.name.dir: namenode的数据存放地址,可以配置多个,位于不同的磁盘并配置一个NFS远程文件系统,这样nn的数据可以有多个备份

  2、dfs.data.dir:dn数据存放地址,每个磁盘配置一个路径,这样可以大大提高并行读写的能力

  3、dfs.namenode.handler.count:nn节点RPC的处理线程数,默认为10,需提高,比如:60

  4、dfs.datanode.handler.count:dn节点RPC的处理线程数,默认为3,需提高,比如:20

  5、dfs.datanode.max.xcievers:dn同时处理文件的上限,默认为256,需提高,比如:8192

  6、dfs.block.size:dn数据块的大小,默认为64M,如果存储的文件均是比较大的文件则可以考虑调大,比如,在使用hbase时,可以设置为128M,注意单位是字节

  7、dfs.balance.bandwidthPerSec:在通过start-balancer.sh做负载均衡时控制传输文件的速度,默认为1M/s,可配置为几十M/s,比如:20M/s

  8、dfs.datanode.du.reserved:每块磁盘保留的空余空间,应预留一些给非hdfs文件使用,默认值为0

  9、dfs.datanode.failed.volumes.tolerated:在启动时会导致dn挂掉的坏磁盘数量,默认为0,即有一个磁盘坏了,就挂掉dn,可以不调整。

本文档转载自 HBase性能调优

hbase优化操作与建议的更多相关文章

  1. 全面认识HBase架构(建议收藏)

    在网上看过很多HBaes架构相关的文章,内容深浅不一,直到发现了一篇MapR官网的文章https://mapr.com/blog/in-depth-look-hbase-architecture/#. ...

  2. 【hbase】——Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  3. hadoop之 mr输出到hbase

    1.注意问题: 1.在开发过程中一定要导入hbase源码中的lib库否则出现如下错误 TableMapReducUtil 找不到什么-- 2.编码: import java.io.IOExceptio ...

  4. (转)Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  5. Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  6. HBase 笔记

    参考资料:HBase权威指南 一行由若干列组成,若干列又构成一个列族一个列族的所有列存储在同一个底层的存储文件里,这个文件叫HFile列族的数量有限制:一个列族里列的数量没限制谓词删除:例如允许用户只 ...

  7. HBase学习总结(1)

    HBase是一种数据库:HadoopDatabase顾名思义就是Hadoop数据库,它是一种基于hadoop文件系统HDFS的一种分布式数据库,专门设计用来快速随机读写大规模数据.本文介绍HBase的 ...

  8. [转] HBase 深入浅出

    [From] https://www.ibm.com/developerworks/cn/analytics/library/ba-cn-bigdata-hbase/index.html HBase ...

  9. HBase之四--(1):Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

随机推荐

  1. SpirteKit深度复制SKSpriteNode节点及convert转换其它Scene上的节点到当前场景坐标

    Playground输出的代码 ,注意右侧打印出的SpriteNode输出值,HAPPY_NODE的输出信息一致. SpriteNode //MARK:- 扩展SkSpriteNode属性 exten ...

  2. STM32(5)——通用定时器基本定时器

    1.STM32的Timer简介 STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器. 其中系统嘀嗒定时器是前文中所描述的S ...

  3. Wtrofms

    一.安装 安装:pip3 install wtforms 二.使用1(登录) from flask import Flask, render_template, request, redirect f ...

  4. C语言用一级指针处理字符串的反思

    1.一级指针处理字符串的常见方式 如果使用单个指针,不方便对字符串本身进行操作,只适合遍历. 使用两个指针, 两个指针和字符串大致有两个常见处理方式: (1)两个指针从字符串首部开始向后移动,同时处理 ...

  5. 【blockly教程】第一章 Google Blockly教学应用手册

    1.1 Google Blockly概述 美国计算科学教育一直认为计算机作为当今各个领域的基础技术工具,有必要让学生尽早的了解和学习计算机工作原理,理解基础的编程思维.在2006年周以真教授提出计算思 ...

  6. typedef和define一些问题

    1. 四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如: char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针 ...

  7. 10 Quality Free Flat Icon Sets for Your Designs

    Subscribe It’s clear that flat design has gained great popularity in recent years. This is hardly su ...

  8. 20155209实验二《Java面向对象程序设计》

    20155209实验二<Java面向对象程序设计> 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计 ...

  9. [2016北京集训测试赛3]masodik-[凸包]

    Description Soluton 666这道题竟然用凸包... 维护r和c的下凸壳.哪个斜率大走哪个. 证明:我们先不考虑其他的,只考虑两条路,如下图: 设图的长度为x,宽度为y.如果我们要走上 ...

  10. Drupal7重置密码方法

    Drupal版本 7.40 方法1: 根目录index.php添加 require_once 'includes/password.inc'; require_once 'includes/boots ...