一、内存优化

HBase操作过程中需要大量的内存开销,毕竟Table是可以缓存在内存中的,一般会分配整个可用内存的70%给HBase的Java堆。但是不建议分配非常大的堆内存,因为GC过程持续太久会导致RegionServer处于长期不可用状态,一般16-48G内存就可以了,如果因为框架占用内存过高导致内存不足,框架一样会被系统服务拖死。

二、基础优化

  1. 1、允许在HDFS的文件中追加内容:hdfs-site.xmlhbase-site.xml
  2. 属性:dfs.support.append
  3. 解释:开启HDFS追加同步,可以优秀的配合HBase的数据同步和持久化,默认值为true
  4. 2、优化DataNode允许的最大文件打开数:hdfs-site.xml
  5. 属性:dfs.datanode.max.transfer.threads
  6. 解释:HBase一般都会同一时间操作大量的文件,根据集群的数量和规模以及数据动作,设置为4096或者更高。默认值为4096
  7. 3、优化延迟高的数据操作的等待时间:hdfs-site.xml
  8. 属性:dfs.image.transfer.timeout
  9. 解释:如果对于某一次数据操作来说,延迟非常高,socket需要等待更长的时间,建议把该值设置为更大的值(默认60000毫秒),以确保socket不会timeout掉。
  10. 4、优化数据的写入效率:mappred-site.xml
  11. 属性:
  12. mapreduce.map.output.compress
  13. mapreduce.map.output.compress.codec
  14. 解释:开启这两个数据可以大大提高文件的写入效率,减少写入时间,第一个属性值修改为true,第二个属性值修改为:org.apache.hadoop.io.compress.GzipCodec或者其他压缩方式。
  15. 5、设置RPC监听数量:hbase-site.xml
  16. 属性:Hbase.regionserver.handler.count
  17. 解释:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。
  18. 6、优化HStore文件大小:hbase-site.xml
  19. 属性:HBase.hregion.max.filesize
  20. 解释:默认值1073741824010GB),如果需要运行HbaseMR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分成两个HFile
  21. 7、优化HBase客户端缓存:hbase-site.xml
  22. 属性:Hbase.client.write.buffer
  23. 解释:用于指定HBase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多的内存,反之则反之;一般设置该值可以达到减少RPC次数的目的即可。
  24. 8、指定scan.next扫描HBase所获取的行数
  25. 属性:Hbase.client.scanner.caching
  26. 解释:用于指定scan.next方法获取的默认行数,值越大,消耗内存越大。
  27. 9flushcompactsplit机制
  28. MemStore达到阈值,将MemStore中的数据FlushStoreFilecompact机制则是把flush出来的小文件合并成大的StoreFile文件;split则是当Region到达阈值,会把过大的Region一分二。
  29. 涉及的属性:
  30. hbase.hregion.memstore.flush.size:134217728
  31. 解释:Memstore的默认阈值,当HRegion内所有的Memstore大小总和超过指定值时,flushHRegion的所有memstoreRegionServerflush是通过将请求添加一个队列,模拟生产消费模型来进行异步处理的,那这里就有一个问题,当队列来不及消费,产生大量积压请求时,可能会导致内存徒增,最坏的情况就是OOM
  32. hbase.regionserver.global.memstore.upperLimit:0.4
  33. hbase.regionserver.global.memstore.lowerLimit:0.38
  34. 解释:当MemStore使用内存总量到达hbase.regionserver.global.memstore.upperLimit指定值时,将会有多个MemStore flush到文件中,MemStore flush顺序是按照大小降序执行的,直到刷新到MemStore使用内存略小于lowerLimit

优化不是必要的,更重要的是进行预分区和进行合理的rowkey设计

三、其他

3.1、Column Family

不要在一张表里定义太多的column family。目前HBase并不能很好的处理超过2~3个column family。因为某个 column family 在flush的时候,它邻近的 column family 也会因关联效应被触发flush,最终导致系统产生更多的I/O。

3.2、In Memory

创建表的时候,可以通过HColumnDescriptor.setInMemory(true) 将表放到 RegionServer 的缓存中,保证在读取的时候被cache命中。用在读取比较频繁的列族上。

3.3、Max Version

创建表的时候,可以通过 HColumnDescriptor.setMaxVersions(int maxVersions) 设置表中数据的最大版本,如果只需要保存最新版本的数据,那么可以设置为1。

3.4、Time To Live

创建表的时候,可以通过 HColumnDescriptor.setTimeToLive(int timeToLive) 设置表中数据的存储生命周期,过期的数据将被自动删除,例如如果只需要存储最近两天的数据,那么设置为setTimeToLive(2243600) ,单位秒。
image.png
默认 TTL => ‘FOREVER’ 表示永久保存。

3.5、Compact & Split

image.pngimage.png
image.png
image.png
image.png

image.pngimage.png

四、写表操作

4.1、HTable参数设置

1、Write Buffer
通过调用HTable.setWriteBufferSize(writeBufferSize) 方法可以设置HTable客户端的写buffer大小,如果新设置的buffer小于当前写buffer中的数据时,buffer将会被flush到服务端。其中writeBufferSize的单位是byte字节数,可以根据实际写入数据量的多少来设置该值。
image.png
默认大小是2MB(即2097152字节),这个大小比较适中,一般用户插入HBase中的数据都相当小,即每次插入的数都远小于缓冲区的大小。如果需要存储交到的数据,通常需要考虑增大这个数值,从而允许客户端更高效地将一定数据量的数据组成一组,通过RPC请求来执行。
或者在配置修改参数,hbase.client.write.buffer , 单位字节。

2、Auto Flush
调用HTable.setAutoFlushTo(false)方法可以将HTable写客户端字段flush关闭,这样可以批量写入数据到HBase,而不是有一条put就执行一次更新,只有当put填满客户端写缓存时,才实际向HBase服务端发起写请求。默认auto flush是开启的。

3、WAL Flag
一般只有数据成功写入到WAL后,再往MemStore写数据,这样就会造成写效率低。对于不是很重要的数据,可以调用Put.setWriteToWAL(false) 或者 Delete.setWriteToWAL(false) ,在PUT/DELETE 时放弃写WAL日志,提高数据写入性能。但是这样会在出现RegionServer宕机时无法根据WAL日志进行数据恢复。

4、批量写,一次提交多个Put。

5、多线程写,可以创建多个HTable,每个线程负责各自的客户端。

五、读表操作