HBase读写优化

作者: Real_man | 来源:发表于2018-12-20 09:09 被阅读5次

    一个系统上线之后,开发和调优将一直贯穿系统的生命周期中,HBase也不列外。这里学习下HBase的调优

    Hbase查询优化

    作为NoSQL数据库,增删改查是其最基本的功能,其中查询是最常用的一项。

    设置Scan缓存

    HBase中Scan查询可以设置缓存,方法是setCaching(),这样可以有效的减少服务端与客户端的交互,更有效的提升扫描查询的性能。

    
       /**
       * Set the number of rows for caching that will be passed to scanners.
       * If not set, the default setting from {@link HTable#getScannerCaching()} will apply.
       * Higher caching values will enable faster scanners but will use more memory.
       * @param caching the number of rows for caching
       * 设置scanners缓存的行数
       */
      public void setCaching(int caching) {
        this.caching = caching;
      }
    
    显示的指定列

    当使用Scan或者GET获取大量的行时,最好指定所需要的列,因为服务端通过网络传输到客户端,数据量太大可能是瓶颈。如果能有效过滤部分数据,能很大程度的减少网络I/O的花费。

      /**
       * Get all columns from the specified family.
       * <p>
       * Overrides previous calls to addColumn for this family.
       * @param family family name
       * @return this
       * 获取指定列簇的所有列
       */
      public Scan addFamily(byte [] family) {
        familyMap.remove(family);
        familyMap.put(family, null);
        return this;
      }
    
      /**
       * Get the column from the specified family with the specified qualifier.
       * <p>
       * Overrides previous calls to addFamily for this family.
       * @param family family name
       * @param qualifier column qualifier
       * @return this
       * 获取指定列簇的特定列
       */
      public Scan addColumn(byte [] family, byte [] qualifier) {
        NavigableSet<byte []> set = familyMap.get(family);
        if(set == null) {
          set = new TreeSet<byte []>(Bytes.BYTES_COMPARATOR);
        }
        if (qualifier == null) {
          qualifier = HConstants.EMPTY_BYTE_ARRAY;
        }
        set.add(qualifier);
        familyMap.put(family, set);
        return this;
      }
    

    一般用:
    scan.addColumn(...)

    关闭ResultScanner

    如果在使用table.getScanner之后,忘记关闭该类,它会一直和服务端保持连接,资源无法释放,从而导致服务端的某些资源不可用。

    所以在用完之后,需要执行关闭操作,这点与JDBS操作MySQL类似

    scanner.close()

    禁用块缓存

    如果批量进行全表扫描,默认是有缓存的,如果此时有缓存,会降低扫描的效率。

    scan.setCacheBlocks(true|false);

    对于经常读到的数据,建议使用默认值,开启块缓存

    缓存查询结果

    对于频繁查询HBase的应用场景,可以考虑在应用程序和Hbase之间做一层缓存系统,新的查询先去缓存查,缓存没有再去查Hbase。

    写入优化

    写也是Hbase常有的操作之一,并且Hbase在写入操作上有着其他NoSQL无法比拟的优势,下面讲如何优化写入操作

    关闭写WAL日志

    一般为了保证系统的高可用性,WAL日志默认是开启状态,WAL主要用于灾难恢复的,如果应用可以容忍一定的数据丢失风险,可以在写数据的时候,关闭写WAL。

    风险: 当RegionServer宕机时,写入的数据出现丢失,且无法恢复

    image
    设置AutoFlush

    Htable有一个属性是AutoFlush,该属性用于支持客户端的批量更新,默认是true,当客户端每收到一条数据,立刻发送到服务端,如果设置为false,当客户端提交put请求时候,先将该请求在客户端缓存,到达阈值的时候或者执行hbase.flushcommits(),才向RegionServer提交请求。

    风险 在请求未发送到RegionServer之前客户端崩溃,数据也会丢失

            table.setAutoFlush(false);
            table.setWriteBufferSize( 12 * 1024 * 1024 );
    
    预创建Region

    一般表刚开始只有一个Region,插入该表的数据都会保存在此Region中,插入该表的所有塑化剂都会保存在该Region中,当到达一定的阈值时,才发生分裂。 这样开始时刻针对该表的写操作都集中在某台服务器上,造成这台服务器的压力很紧张,同时对整个集群资源的浪费

    建议刚开始的时候预创建Region,可以使用Hbase自带的RegionSplitter

    延迟日志flush

    默认写入操作,首先写入WAL,并且在1S内写入HDFS,这个时间默认是1S,可以通过参数配置

    hbase.regionserver.optionallogflushinterval

    可以配置大一点的值,比如5s,这段时间数据会保留在内存中,直到RegionServer周期性的执行flush操作。

    最后

    这里提供了一些读写优化的参考,希望能帮助大家

    相关文章

      网友评论

        本文标题:HBase读写优化

        本文链接:https://www.haomeiwen.com/subject/bhpekqtx.html