hbase性能调优

标签: hbase 性能调优 | 发表时间:2014-05-17 23:10 | 作者:无尘道长
出处:http://www.iteye.com

一、服务端调优

 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,可配置上千

 

hdf调优:

  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,可以不调整。



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [hbase 性能调优] 推荐:

HBase性能调优

- - 学着站在巨人的肩膀上
我们经常看到一些文章吹嘘某产品如何如何快,如何如何强,而自己测试时却不如描述的一些数据. 其实原因可能在于你还不是真正理解其内部结构,对于其性能调优方法不够了解. 本文转自TaoBao的Ken Wu同学的博客,是目前看到比较完整的HBase调优文章. 原文链接:HBase性能调优. 因官方Book Performance Tuning部分章节没有按配置项进行索引,不能达到快速查阅的效果.

hbase性能调优

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

HBase+G1GC性能调优 - HBase 技术社区

- -
目前小米已经在线上开始大规模使用G1垃圾回收算法,在论坛中也看到一些朋友在讨论使用G1碰到的各种各样的问题,这里打算写一篇文章记录下调G1的一些经验.. 先传送门一下,之前在HBaseConAsia2017分享过一个g1gc调优的ppt:http://openinx.github.io/2012/01/01/my-share/ .

HBase在淘宝主搜索的Dump中的性能调优

- - 搜索技术博客-淘宝
目前HBase已经运用于淘宝主搜索的全量和增量的数据存储,有效的减低的数据库的压力,增强了业务扩展的能力. Dump系统的特点是要求在短时间内处理大量数据,对延时要求高. 在实施这个项目过程中,我们积累了一些优化的实践,抛砖引玉,供大家参考. 环境:Hadoop CDH3U4 + HBase 0.92.1.

Hadoop性能调优

- - 开源软件 - ITeye博客
是否对任务进行profiling,调用java内置的profile功能,打出相关性能信息. 对几个map或reduce进行profiling. 非常影响速度,建议在小数据量上尝试. 1表示不reuse,-1表示无限reuse,其他数值表示每个jvm reuse次数. reuse的时候,map结束时不会释放内存.

MapReduce - 性能调优

- - CSDN博客云计算推荐文章
        Hadoop为用户作业提供了多种可配置的参数,以允许用户根据作业特点调整这些参数值使作业运行效率达到最优.         对于一大批MapReduce程序,如果可以设置一个Combiner,那么对于提高作业性能是十分有帮助的. Combiner可减少Map Task中间输出的结果,从而减少各个Reduce Task的远程拷贝数据量,最终表现为Map Task和Reduce Task执行时间缩短.

Java 性能调优

- - 编程语言 - ITeye博客
1.用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用. 但如果一个对象实现了Cloneable接口,我们可以调用它的clone()方法. clone()方法不会调用任何类构造函数. 在使用设计模式(Design Pattern)的场合,如果用Factory模式创建对象,则改用clone()方法创建新的对象实例非常简单.

Spark性能调优

- - zzm
通常我们对一个系统进行性能优化无怪乎两个步骤——性能监控和参数调整,本文主要分享的也是这两方面内容. Spark提供了一些基本的Web监控页面,对于日常监控十分有用. http://master:4040(默认端口是4040,可以通过spark.ui.port修改)可获得这些信息:(1)stages和tasks调度情况;(2)RDD大小及内存使用;(3)系统环境信息;(4)正在执行的executor信息.

性能调优攻略

- - 酷壳 - CoolShell.cn
关于性能优化这是一个比较大的话题,在《 由12306.cn谈谈网站性能技术》中我从业务和设计上说过一些可用的技术以及那些技术的优缺点,今天,想从一些技术细节上谈谈性能优化,主要是一些代码级别的技术和方法. 本文的东西是我的一些经验和知识,并不一定全对,希望大家指正和补充. 在开始这篇文章之前,大家可以移步去看一下酷壳以前发表的《 代码优化概要》,这篇文章基本上告诉你—— 要进行优化,先得找到性能瓶颈.

[原]Java性能调优

- - 傲慢的上校的专栏
写Java也有n年了,现在还是有不少的坏的代码习惯,也通过学习别人的代码学到了不少好的习惯. 留给自己做个警戒,提示以后写代码的时候注意. 在文章的后面,会提供整理的原材料下载. 1、尽量少用new生成新对象.         用new创建类的实例时,构造雨数链中所有构造函数都会被自动调用,操作速度较慢.