前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HBase调优及优化的20种方式(上)

HBase调优及优化的20种方式(上)

作者头像
用户5252199
发布2022-04-18 18:45:54
1.9K0
发布2022-04-18 18:45:54
举报

01

选择关闭AutoFlush

默认情况下,AutoFlush是开启的,当每次put操作的时候,都会提交到HBase server,大数据量put的时候会造成大量的网络IO,耗费性能

在大数据量并发下,AutoFlush设置为false,并且将WriteBufferSize设置大一些(默认是2MB)(WriteBufferSize只有在AutoFlush为False情况下起作用)

则需要通过调用HTable.setAutoFlushTo(false)方法可以将HBaseClient写客户端自动flush功能关闭,这样可以批量的将数据写入到HBase中,而不是一条put就执行一次更新!

但是这样也有一个弊端,就是当出现故障的时候,比如宕机事故,缓冲区的数据还没有来得及flush落盘,则会丢失!

02

采用批量读写方式

建议使用List<put>来写入hbase数据而不是put。

HBase 通过Put操作来将RowKey信息写入数据,如果在并发度比较高的情况下,频繁的Put会造成网络IO,HBase提供了另一种put操作,可以调用HTable.put(List<Put>)可以批量的写入多条记录,这样就只有一次网络IO操作

同样,HBase也提供一种可以批量读的方式,通过HTable.get(list)方式,可以根据给定的rowkey列表返回多个rowkey结果的集合,这样在通过list方式请求时,只会有一次网络IO,可以减少网络阻塞情况提供网络传输性能!

03

启用压缩

HBase创建表时要启用压缩,HBase支持的几种压缩算法分别为:GZIP、LZO、SNAPPY、Zippy.对于几种算法的比较

1)GZIP的压缩率最高,但它是CPU密集型的,对CPU的消耗较多,压缩和解压速度也慢; 2)LZO的压缩率居中,比GZIP要低一些,但是压缩和解压速度明显要比GZIP快很多,其中解压速度快的更多; 3)Zippy/Snappy的压缩率最低,而压缩和解压速度要稍微比LZO要快一些

所以在通常情况下使用Snappy和Zippy压缩算法.

启用压缩的两种方式:

一种是在创建表时指定压缩算法;另一种是创建表后指定压缩算法或者修改压缩算法。

创建表时指定:

代码语言:javascript
复制
create 'test', {NAME => 'info', VERSIONS => 1, COMPRESSION => 'snappy'}

创建表后修改:

代码语言:javascript
复制
disable 'test'
代码语言:javascript
复制
使用alter语句进行修改
代码语言:javascript
复制
alter 'test', NAME => 'info', COMPRESSION => 'snappy'enable 'test'

最后对表进行major_compact操作,使压缩生效

代码语言:javascript
复制
major_compact  'test'

04

提前评估好集群规模

如果事先不能够合理的评估一个HBase集群规模大小的话,除了对于性能有不好的影响之外,还会降低整个集群的稳定性,比如会出现的状况:客户端响应超时,regionserver宕机;整体集群恢复时间比较长等问题.

如果来评估HBase的集群规模?

首先需要了解应用场景是什么样子的,是一种读更加密集的还是写更加频繁的?因为它涉及到很多方面的考虑.

其次评估好负载情况,区分为读取/写入的负载使用以及预估到的使用模式

对于SLA的要求是什么,如何来量化读写延迟,以及能够对数据的不一致性的容忍程度达到多少?

然后是存储,评估好每天的数据增量是多少,是否要设置好TTL?在整个使用周期中HBase可能会达到的最大数据数据规模

最后是网络;在评估整个HBase集群部署时,网络是一个重要考虑因素,HBase集群通常使用千兆网或者10千兆网,最小配置也应该是千兆网,但是对于一些大的集群来讲使用10千兆网会更加的好一些.因为在底层硬件故障以及在做一些大合并的时候,网络将会是其中的一个瓶颈,region在进行大合并的时候,会进行远程的读写,如果集群故障或者region重新平衡,那么会将网络打满,对于一些SLA要求比较高的场景,显然是不足以支撑的.

那么一个好的环境部署应该是不低于10千兆网络.同时为了保障数据的容错性,使用多机架模式部署可以有效的防止数据单点问题.

05

regin太多不一定好

首先从hbase的原理来讲,首先一个regionserver会有多个region组成,那么一个region又包含多个HStore,HStreo由memstore和storefile组成,当client进行写入操作时,会先将数据写入memstore,memstore满了之后将数据flush到storefile,一直到增长到某个阀值,触发compact操作,然后多个storefile会合并为一个Storefile,在这之后还会有storefile split的操作,也就是经常会遇到的region split,使得原先一个region的压力,被分配多个region,统一由master去分配到不同的regionserver中.

那么如果region数量很多,就会生成很多的storefile文件小文件,小文件问题就不再多说了,其次就是会触发hbase的文件合并操作,从而保证HFile的数量在一个合理的范围内,合并操作会造成集群的不稳定,影响集群的性能,region数量越多那么触发合并的操作频次也就越多,也就会直接的影响集群的性能,包括网络IO的,fullgc,regionserver加载异常会报出RegionTooBusyException.

会有哪些因素导致region太多呢?

1). Region的最大值设置的太小

2).split的次数太多

3)预分区设置的不合理

解决方案:

这里有一个关于region数量的计算公式:

代码语言:javascript
复制
((RS Xmx) * hbase.regionserver.global.memstore.size) / (hbase.hregion.memstore.flush.size * (# column families))

06

不建议设置多个列族

我们知道,hbase表中可以设置一个或者多个列族,但是为什么说要把列族数据量不要太多呢?

regionserver管理着多个region,每个region中有多个hstore组成,每个hstore对应表中的column family中的存储,hstore是hbase存储的核心,由memstore和stroefile组成,当memstore满了之后会flush到storefile中.

  • region下面的某个storefile过大之后,就会进行split操作.
  • 多个列族会形成更多的hfile小文件
  • 不同列族会共享region,split操作会导致io增加.
  • 一个列族触发flush时,其它列族也会进行flush,导致io压力增加
  • 会形成更多小文件,增加hdfs压力
  • 查询CF时,会出现跨多个region,查询效率变低
  • 多个CF会有多个Memstore,内存占用增大.

07

Bloomfilter的合理设置

Bloomfilter过滤器的思想为:当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在
Bloomfilter根据key随机读时,在StoreFile级别进行过滤
Bloomfilter主要用来过滤不存在待检索RowKey或者Row-Col的HFile文件,避免无用的IO操作。它会告诉你在这个HFile文件中是否可能存在待检索的KV,如果不存在,就可以不用消耗IO打开文件进行seek。通过设置Bloomfilter可以提升随机读写的性能,在使用Bloom Filter判断一个元素是否属于某个集合时,会有一定的错误率,不过这种错误率很低. 也就是说除了空间换时间、时间换空间之外,Bloomfilter使用了一种用很低的错误率来减少空间并且快速查询.

Bloomfilter取值有两个,row以及rowcol,需要根据业务来确定具体使用哪种。任何get类型的读取都会Bloomfilter,有如果业务大多数随机查询仅仅使用row作为查询条件,Bloomfilter就需要设置为row,否则如果大多数随机查询使用row+cf作为查询条件,Bloomfilter需要设置为rowcol。如果不确定业务查询类型,则可以设置为row

所以在一般的业务场景中

在创建表时开启即可

代码语言:javascript
复制
create 'test',{NAME=>'INFO,BLOOMFILTER=>'ROWCOL'}
create 'test1',{NAME=>'INFO,BLOOMFILTER=>'ROW'}

08

HBase表设计时刻考虑热点问题

热点问题主要原因在于rowkey的设计不合理.

在某个时间段,对HBase的读写请求集中到少数几个region上面,导致这些region所属的regionserver请求量比较大,负载压力增加,而其他regionserver属于空闲状态,一般这种问题就是hbase的rowkey热点问题了.

对于热点问题常用的有效解决办法就是rowkey加盐或者预分区

这里罗列几点rowkey的设计原则:

  • rowkey的长度尽量短.
  • 散列原则,将数据分散到不同region中.
  • 表设计要考虑好热点问题
  • rowkey唯一原则,要保证rowkey是唯一的

09

避免长时间的GC操作(GC调优)

在HBase服务中影响最大的垃圾回收事件是Java虚拟机要执行一次full gc(一次彻底的垃圾回收)操作,那么此时会导致jvm暂停服务,在这个时候,hbase上面所有的读写操作将会被客户端归入队列中排队,一直等到jvm完成它的gc操作, 在继续的恢复服务.

会导致的问题:

hbase服务长时间暂停会导致HBase服务超时

客户端操作超时,操作请求处理异常.

服务端超时会导致region信息上报异常,导致丢失心跳.

会导致region的重新分配到其它regionserver上

导致RegionServer终止,原有的regionserver 恢复之后,请求zk会告知死亡,并抛出YouAreDeadException异常

如何避免和预防GC超时?

减少堆大小,堆越大,JVM完成GC的时间越长

使用堆外内存,减少GC的时间

使用G1的的GC算法

一些常用的必备参数

代码语言:javascript
复制
-XX:+UseG1GC
-XX:+PrintFlagsFinal
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+PrintAdaptiveSizePolicy
-XX:+PrintReferenceGC

10

HBase负载均衡调优

正常来讲,一个hbase集群是有多个regionserver组成,这样可以提高hbase集群的并发读写,但是在某些情况下(具体场景具体分析), 应用程序的读可能会落到一个regionserver上面去.那么这样的话 原本的并发优势就不存在了,反而会增加单个regionserver的压力.这是一个很严重的情况,极大概率的会使得这个regionserver挂掉,影响正常的读写请求,造成业务瘫痪,所以说负载不均衡是hbase中的大忌

这里汇总了常见的几种负载均衡的调优方式:

1、观察,出现问题首先要先观察服务的监控和日志信息,观察每个regionserver的qps,看看是否有读写不均衡的现象.

2、rowkey散列化处理,将region分配到不同的regionserver中,可以极大的减少负载不均衡的情况.

3、限流限资源,一旦发现有不均衡情况,可以选择针对用于进行限流或者

罗列几个限制语句

限制用户u1每秒请求10次

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10req/sec'

限制用户u1每秒的读请求为10次

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', LIMIT => '10req/sec'

限制用户u1每天的请求量为10M

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10M/day'

限制用户u1的写请求量每秒为10M

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => WRITE, USER => 'u1', LIMIT => '10M/sec'

限制用户u1在操作表t2时,每分钟的请求量为5K

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, USER => 'u1', TABLE => 't2', LIMIT => '5K/min'

限制用户u1在操作表t2时,每秒的读请求为10次

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', TABLE => 't2', LIMIT => '10req/sec'

删除用户u1在命令空间ns2的请求限制

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, USER => 'u1', NAMESPACE => 'ns2', LIMIT => NONE

限制在命名空间ns1中每小时的请求为10次

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, NAMESPACE => 'ns1', LIMIT => '10req/hour'

限制表t1每小时的请求为10T

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, TABLE => 't1', LIMIT => '10T/hour'

删除用户u1的所有请求限制

代码语言:javascript
复制
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => NONE

显示用户u1在命名空间ns2中的所有限制详情

代码语言:javascript
复制
hbase> list_quotas USER => 'u1, NAMESPACE => 'ns2'

显示命令空间ns2的所有限制详情

代码语言:javascript
复制
hbase> list_quotas NAMESPACE => 'ns2' 

显示表t1的所有限制详情

代码语言:javascript
复制
hbase> list_quotas TABLE => 't1'

显示所有限制详情

代码语言:javascript
复制
hbase> list_quotas

4、选择开启或手动均衡

查看均衡器状态

代码语言:javascript
复制
balance_switch status

开启均衡器

代码语言:javascript
复制
balance_switch true

关闭均衡器

代码语言:javascript
复制
balance_switch false

也可以手动将region移动到其它regionserver中

代码语言:javascript
复制
move [regionid] [servername]
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据技术博文 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Bloomfilter过滤器的思想为:当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在
  • Bloomfilter根据key随机读时,在StoreFile级别进行过滤
  • Bloomfilter主要用来过滤不存在待检索RowKey或者Row-Col的HFile文件,避免无用的IO操作。它会告诉你在这个HFile文件中是否可能存在待检索的KV,如果不存在,就可以不用消耗IO打开文件进行seek。通过设置Bloomfilter可以提升随机读写的性能,在使用Bloom Filter判断一个元素是否属于某个集合时,会有一定的错误率,不过这种错误率很低. 也就是说除了空间换时间、时间换空间之外,Bloomfilter使用了一种用很低的错误率来减少空间并且快速查询.
相关产品与服务
TDSQL MySQL 版
TDSQL MySQL 版(TDSQL for MySQL)是腾讯打造的一款分布式数据库产品,具备强一致高可用、全球部署架构、分布式水平扩展、高性能、企业级安全等特性,同时提供智能 DBA、自动化运营、监控告警等配套设施,为客户提供完整的分布式数据库解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档