
# 提升HBase实时写数据效率
#### 操作场景
在业务系统运行过程中，需要将数据实时写入HBase，或存在大批量连续Put操作的场景。然而HBase的WAL同步策略、MemStore大小、Compaction策略等参数默认配置可能导致写入性能瓶颈，出现写入延迟增大、RegionServer频繁GC、写操作阻塞等问题。本章节从写数据服务端调优、客户端调优和表设计调优三个维度，指导用户优化HBase的实时写数据性能。
#### 前提条件
调用HBase的put或delete接口，把数据保存到HBase中。
#### 操作步骤
- **写数据服务端调优**
  登录FusionInsight Manager，选择"集群 \> 服务 \> 配置 \> 全部配置"，进入HBase服务参数"全部配置"界面，修改相关参数值。
  登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
  表1影响实时写数据配置项 
  | 参数                                                                                                                                                                                                                                                                                                                                    | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 默认值                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
  |:---|:---|:---|
  | hbase.wal.hsync                                                                                                                                                                                                                                                                                                                       | 控制HLog文件在写入到HDFS时的同步程度。 - true：HDFS在把数据写入到硬盘后才返回。  - false：HDFS在把数据写入OS的缓存后就返回。   把该值设置为"false"比"true"在写入性能上会更优。                                                                                                                                                                                                                                                                                                                                                                                                                                   | true                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
  | hbase.hfile.hsync                                                                                                                                                                                                                                                                                                                     | 控制HFile文件在写入到HDFS时的同步程度。 - true：HDFS在把数据写入到硬盘后才返回。  - false：HDFS在把数据写入OS的缓存后就返回。   把该值设置为"false"比"true"在写入性能上会更优。                                                                                                                                                                                                                                                                                                                                                                                                                                | true                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
  | GC_OPTS                                                                                                                                                                                                                                                                                                                               | HBase利用内存完成读写操作。提高HBase内存可以有效提高HBase性能。"GC_OPTS"主要需要调整HeapSize的大小和NewSize的大小。调整HeapSize大小的时候，建议将Xms和Xmx设置成相同的值，这样可以避免JVM动态调整HeapSize大小的时候影响性能。调整NewSize大小的时候，建议把其设置为HeapSize大小的1/8。 - HMaster：当HBase集群规模越大、Region数量越多时，可以适当调大HMaster的GC_OPTS参数。  - RegionServer：RegionServer需要的内存一般比HMaster要大。在内存充足的情况下，HeapSize可以相对设置大一些。   主HMaster的HeapSize为4GB时，HBase集群可以支持100000 Region数的规模。根据经验值，集群每增加35000个Region，HeapSize增加2GB，主HMaster的HeapSize不建议超过32GB。 | - HMaster -server -Xms4G -Xmx4G -XX:NewSize=512M -XX:MaxNewSize=512M -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512M -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=65 -XX:+PrintGCDetails -Dsun.rmi.dgc.client.gcInterval=0x7FFFFFFFFFFFFFE -Dsun.rmi.dgc.server.gcInterval=0x7FFFFFFFFFFFFFE -XX:-OmitStackTraceInFastThrow -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M   - Region Server -server -Xms6G -Xmx6G -XX:NewSize=1024M -XX:MaxNewSize=1024M -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512M -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=65 -XX:+PrintGCDetails -Dsun.rmi.dgc.client.gcInterval=0x7FFFFFFFFFFFFFE -Dsun.rmi.dgc.server.gcInterval=0x7FFFFFFFFFFFFFE -XX:-OmitStackTraceInFastThrow -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M    |
  | hbase.regionserver.handler.count                                                                                                                                                                                                                                                                                                      | 表示在RegionServer上启动的RPC侦听器实例数。如果设置过高会导致激烈线程竞争，如果设置过小，请求将会在RegionServer长时间等待，降低处理能力。根据资源情况，适当增加处理线程数。 建议根据CPU的使用情况，可以选择设置为100至300之间的值。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | 200                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
  | hbase.hregion.max.filesize                                                                                                                                                                                                                                                                                                            | HStoreFile的最大大小（单位：Byte）。如果任何一个列族HStoreFile超过此参数值，则托管Hregion将会一分为二。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | 10737418240                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
  | hbase.hregion.memstore.flush.size                                                                                                                                                                                                                                                                                                     | 在RegionServer中，当写操作内存中存在超过"memstore.flush.size"大小的MemStore，则MemStoreFlusher就启动flush操作将该MemStore以HFile的形式写入对应的store中。 如果RegionServer的内存充足，而且活跃Region数量也不是很多的时候，可以适当增大该值，以减少compaction的次数，有助于提升系统性能。 同时，这种flush产生的时候，并不是紧急的flush，flush操作可能会有一定延迟，在延迟期间，写操作还可以进行，Memstore还会继续增大，最大值为"memstore.flush.size" \* "hbase.hregion.memstore.block.multiplier"。当超过最大值时，将会阻塞操作。适当增大"hbase.hregion.memstore.block.multiplier"可以减少阻塞，减少性能波动，单位为字节。                                                                                                                                                                                                                 | 134217728                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
  | hbase.regionserver.global.memstore.size                                                                                                                                                                                                                                                                                               | 更新被锁定以及强制冲洗发生之前一个RegionServer上支持的所有MemStore的大小。RegionServer中负责flush操作的是MemStoreFlusher线程，该线程定期检查写操作内存，当写操作占用内存总量达到阈值，MemStoreFlusher将启动flush操作，按照从大到小的顺序，flush部分相对较大的MemStore，直到所占用内存小于阈值。 阈值 = "hbase.regionserver.global.memstore.size" \* "hbase.regionserver.global.memstore.size.lower.limit" \* "HBase_HEAPSIZE" **该配置与"hfile.block.cache.size"的和不能超过0.8，也就是写和读操作的内存不能超过HeapSize的80%，这样可以保证除读和写外其他操作的正常运行。**                                                                                                                                                                                                                                  | 0.4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
  | hbase.hstore.blockingStoreFiles                                                                                                                                                                                                                                                                                                       | 在Region flush前首先判断file文件个数是否大于"hbase.hstore.blockingStoreFiles"。 如果大于需要先compaction并且让flush延时90s（可以通过"hbase.hstore.blockingWaitTime"进行配置），在延时过程中，将会继续写从而使得Memstore还会继续增大超过最大值"memstore.flush.size" \* "hbase.hregion.memstore.block.multiplier"，导致写操作阻塞。当完成compaction后，可能就会产生大量写入。这样就导致性能激烈震荡。 增大"hbase.hstore.blockingStoreFiles"，可以减低BLOCK几率。                                                                                                                                                                                                                                                                                                      | 15                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
  | hbase.regionserver.thread.compaction.throttle                                                                                                                                                                                                                                                                                         | 大于此参数值的压缩将被大线程池执行，单位为Byte。控制一次Minor Compaction时，进行compaction的文件总大小的阈值。Compaction时的文件总大小会影响这一次compaction的执行时间，如果太大，可能会阻塞其他的compaction或flush操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | 1610612736                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
  | hbase.hstore.compaction.min                                                                                                                                                                                                                                                                                                           | 每次执行Minor Compaction的HStoreFile的最小数量。当一个Store文件超过该值时，会进行compact，适当增大该值，可以减少文件被重复执行compaction。但是如果过大，会导致Store文件数过多而影响读取的性能。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | 6                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
  | hbase.hstore.compaction.max                                                                                                                                                                                                                                                                                                           | 每次执行minor compaction的HStoreFile的最大数量。与"hbase.hstore.compaction.max.size"的作用基本相同，主要是控制一次compaction操作的时间不要太长。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 10                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
  | hbase.hstore.compaction.max.size                                                                                                                                                                                                                                                                                                      | 如果一个HFile文件的大小大于该值，那么在Minor Compaction操作中不会选择这个文件进行compaction操作，除非进行Major Compaction操作。 这个值可以防止较大的HFile参与compaction操作。在禁止Major Compaction后，一个Store中可能存在几个HFile，而不会合并成为一个HFile，这样不会对数据读取造成太大的性能影响。单位为字节。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 9223372036854775807                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
  | hbase.hregion.majorcompaction                                                                                                                                                                                                                                                                                                         | 单个区域内所有HStoreFile文件主压缩的时间间隔，单位为毫秒。由于执行Major Compaction会占用较多的系统资源，如果正在处于系统繁忙时期，会影响系统的性能。 如果业务没有较多的更新、删除、回收过期数据空间时，可以把该值设置为0，以禁止Major Compaction。 如果必须要执行Major Compaction，以回收更多的空间，可以适当增加该值，同时配置参数"hbase.offpeak.end.hour"和"hbase.offpeak.start.hour"以控制Major Compaction发生在业务空闲的时期。                                                                                                                                                                                                                                                                                                                                                                   | 604800000                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
  | - hbase.regionserver.maxlogs  - hbase.regionserver.hlog.blocksize   | - 表示一个RegionServer上未进行Flush的Hlog的文件数量的阈值，如果大于该值，RegionServer会强制进行flush操作。  - 表示每个HLog文件的最大大小。如果HLog文件大小大于该值，就会滚动出一个新的HLog文件，旧的将被禁用并归档。   这两个参数共同决定了RegionServer中可以存在的未进行Flush的HLog数量。当这个数据量小于MemStore的总大小的时候，会出现由于HLog文件过多而触发的强制flush操作。这个时候可以适当调整这两个参数的大小，以避免出现这种强制flush的情况。单位为字节。                                                                                                                                                                                                                    | - 32  - 134217728                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
     
  
- **写数据客户端调优**
  写数据时，在场景允许的情况下，更适合使用Put List的方式，可以极大地提升写性能。每一次Put的List的长度，需要结合单条Put的大小，以及实际环境的一些参数进行设定。建议在选定之前先做一些基础的测试。
  
- **写数据表设计调优**
  在**hbase shell**中设置以下表相关参数，以提升HBase写数据性能。
  表2影响实时写数据相关参数 
  | **配置参数**    | **描述**                                                                                                                                                                                                                                          | **默认值** |
  |:---|:---|:---|
  | COMPRESSION | 配置数据的压缩算法，该压缩指的是HFile中block级别的压缩。对于可以压缩的数据，配置压缩算法可以有效减少磁盘的IO，从而达到提高性能的目的。 并非所有数据都可以进行有效压缩，例如一张图片的数据，因为图片一般已经是压缩后的数据，所以压缩效果有限。常用的压缩算法是SNAPPY，因为它有较好的Encoding/Decoding速度和可以接受的压缩率。               | NONE    |
  | BLOCKSIZE   | 配置HFile中block块的大小，不同的block块大小，可以影响HBase读写数据的效率。越大的block块，配合压缩算法，压缩的效率就越好；但是由于HBase的读取数据是以block块为单位的，所以越大的block块，对于随机读的情况，性能可能会比较差。 如果要提升写入的性能，一般扩大到128KB或者256KB，可以提升写数据的效率，也不会影响太大的随机读性能。单位为字节 | 65536   |
  | IN_MEMORY   | 配置对应表的数据优先缓存在内存中，可以有效提升读取的性能。对于一些小表，而且需要频繁进行读取操作的，可以设置此配置项。                                                                                                                                                                                     | false   |
     
  
 
