HBase代码优化

Compression压缩

  • 数据量大,边压边写也会提升性能的,毕竟IO是大数据的最严重的的瓶颈,哪怕使用了SSD也是一样。众多的压缩方式中,推荐使用SNAPPY。从压缩率和压缩速度来看,性价比最高
    HColumnDescriptor hcd = new HColumnDescriptor(familyName);   
    hcd.setCompressionType(Algorithm.SNAPPY);
    

HBase数据表优化

1.预分区
  • 默认情况下,在创建HBase表的时候会自动创建一个region分区,写入数据时所有数据都向这一个region写数据,直到这个region足够大了才进行切分。而预分区可以通过先创建很多空region的方式加快批量写入的速度,这样当数据写入HBase时会按照region分区情况,在集群内做数据的负载均衡
2.RowKey优化
  • rowkey是按照字典存储,因为设置rowkey时,要充分利用排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放到一块。

  • rowkey若是递增生成的,建议不要使用正序直接写入,可以使用字符串反转方式写入,使得rowkey大致均衡分布,这样设计的好处是能将RegionServer的负载均衡,否则容易产生所有新数据都集中在一个RegionServer上堆积的现象。

  • rowkey设计原则
    1.长度

      1)rowkey最大长度64kb,越短越好,尽量不要超过16个字节
      2)rowkey过长,内存利用率会降低,系统不能缓存太多数据
      3)机器都是64位,内存以8个字节对齐,所以控制在8个字节的整数可以获得最佳性能
    

    2.分散:建议rowkey的设置散列字段,程序固定生成
    3.唯一性:rowkey要求独一无二

3.减少Column Family数量
  • 把所有列的数据放在一个文件里
    • 传统行存储的做法
    • 如果只希望访问个别的几列数据时,需要遍历每一行,效率低
  • 把所有列的数据分开放到不同文件里
    • 列存储
    • 文件数量很多,影响文件系统效率
  • 需要以上两个方面取折中:HBase将CF中的列放到一起,不同CF的数据分开存(一些经常访问的CQ可以放在一个CF里)
  • 不要在一张表中定义太多的CF。目前HBase并不能很好的处理超过2-3个CF的表,因为当某个CF的数据flush的时候,其他CF也会关联被触发flush。如果CF设计比较多,一旦出现连锁反应,会导致系统产生很大的IO,影响性能。
  • flush和region合并的时候,触发的基本单位都是region,如果memStore里面通常存储少量的数据的时候,没有必要flush
4.设置最大版本数
  • 创建表的时候,可以通过
    HColumnDescriptor.setMaxVersions(int maxVersions) 
    
    设置表中数据的最大版本,如果只需要保存最新版本的数据,那么可以设置setMaxVersions(1)
5.缓存策略(setCaching)
  • 创建表的时候,可以通过
    HColumnDEscriptor.setInMemory(true)
    
    将表放到RegionServer的缓存中,保证在读取的时候被cache命中
6.设置存储生命周期
  • 创建表的时候,可以通过
    HColumnDescriptor.setTimeToLive(int timeToLive)
    
    设置表中数据的存储生命周期,过期数据将自动被删除

写表操作

1.多个HTable并发写
  • 创建多个HTable客户端用于写操作,提高写数据的吞吐量
2.HTable参数设置
  • Auto Flash
    HTable.setAutoFlushTo(false)
    
    该方法可以将HTable写客户端自动flush关闭,这样可以批量写入数据到HBase,而不是有一条put就执行一次更新,只有当put填满客户端写缓存的时候,才会向HBase服务端发起写请求。
    每个HBase客户端默认的写缓冲区大小是2M,可以通过以下方法配置写缓冲区的大小。
  • Write Buffer
    通过调用
    HTable.setWriteBufferSize(long writeBufferSize)
    
    方法可以设置HTable客户端的写buffer大小,如果新设置的buffer小于当前写buffer中的数据时,buffer将会被flush到服务端。其中,writeBufferSize的单位是byte字节数,可以根据实际写入数据量的多少来设置该值
  • WAL Flag
    在HBase中,客户端向集群中的RegionServer提交数据时(Put/Delete操作),首先会写到WAL(Write Ahead Log)日志,即HLog,一个RegionServer上的所有Region共享一个HLog,只有当WAL日志写成功后,再接着写memStore,然后客户端被通知提交数据成功。如果写WAL日志失败,客户端被告知提交失败,这样做的好处是可以做到RegionServer宕机后的数据恢复
    对于不太重要的数据,可以在Put/Delete操作时,通过调用
    Put.setWriteToWAL(false)
    Delete.setWriteToWAL(false)
    
    放弃写WAL日志,以提高数据写入的性能
3.多线程并发写

在客户端开启多个HTable写线程,每个写线程复制一个HTable对象的flush操作,这样结合定时flush和写buffer(writeBufferSize),可以既保证在数据量小的时候,数据可以在较短时间内被flush(如1秒内),同时又保证在数据量大的时候,写buffer一满就及时进行flush。

4.批量写

通过调用HTable.put(Put)可以将一个指定的rowkey记录写入HBase,同样HBase提供了另一个方法,通过调用HTable.put(List)可以将指定的rowkey列表,批量写入多行记录,这样做的好处是批量执行,只需要一次网络I/O开销,这对于数据实时性要求高的场景下带来明显的性能提升

读表操作

多个HTable并发度

创建多个HTable客户端用于读操作,提高读数据的吞吐量

HTable参数设置
  • Scanner Caching
    通过使用
    HTable.setScannerCaching(int scannerCaching)
    
    可以设置HBase scanner一次从服务器抓取的数据条数;默认情况下一次一条,通过将此值设置成一个合理的值,可以减少scan过程中next()的时间开销,代价是scanner需要通过客户端的内存来维持这些被cache的行记录
  • Scan Attribute Selection
    scan时指定需要的Column family,可以减少网络传输数据量,否则默认scan操作会返回整行所有CF的数据
  • Close ResultScanner
    通过scan取完数据后,记得要关闭ResultScanner,否则RegionServer可能会出现问题(对应的server资源无法释放)
批量读

通过调用

HTable.get(Get) 

可以根据一个指定的row key获取一行记录,同样HBase提供了另一个方法:通过调用

HTable.get(List)

方法可以根据一个指定的rowkey列表,批量获取多行记录,这样做的好处是批量执行,只需要一次网络I/O开销,这对于对数据实时性要求高可能带来明显的性能提升

多线程并发度

在客户端开启多个HTable读线程,每个读线程负责通过HTable对象进行get操作

缓存查询结果

对于频繁查询HBase的应用场景,可以考虑在应用程序中缓存,当有新的查询请求时,首先在缓存中查找,如果存在则直接返回,不再查询HBase;否则对HBase发起读请求查询,然后在应用程序中将查询结果缓存起来。至于缓存的替换策略,可以考虑LRU等常用的策略

BlockCache

HBase的RegionServer的内存分为两部分,一部分作为memStore,主要用来写;另一部分作为BlockCache,主要用于读。
写请求会先写入memStore。RegionServer会给每个region提供一个memStore,当memStore满64M以后,会启动flush刷新到磁盘。当memStore的总大小超过限制时
(heapsize * hbase.regionserver.global.memstore.upperlimit * 0.9),会强行启动flush进程,从最大的memStore开始flush直到低于限制。
读请求先到BlockCache中查,查不到就去memStore中查,再查不到就会到磁盘上读,并把读的结果放入BlockCache。由于BlockCache采用的是LRU策略,由此BlockCache达到上限(heapsize * hfile.block.cache.size * 0.85)后,会启动淘汰机制,淘汰掉最老的一批数据。
一个RegionServer上有一个BlockCache和N个memStore,它们的大小之和不能大于等于heapsize * 0.8,否则HBase不能启动。默认BlockCache为0.2,而memStore为0.4。对于注重读响应时间的系统,可以将BlockCache设大些,以加大缓存的命中率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值