Hadoop学习四十一:HBase基础

一.概述

      再次学习HBase实战和HBase权威指南时,对HBase了解又深了许多。本文列出一些值得关注的点。

二.HBase物理和逻辑存储结构

      Hadoop学习四十一:HBase基础

     user表包含两个列族info activity,为此表预分区[1,3) [3,正无穷),此时user表在HBase里的物理和逻辑存储结构如上图。

  1. 一个user表的数据存储在两个region上,这两个region可能在一个RegionServer上,也可能在两个不同的RegionServer上。
  2. 一个RegionServer可以有多个region,这些region共享一个WAL(write-ahead log预写式日志,也称HLog)。
  3. 一个region可以包含多个列族的数据。
  4. 一个列族由一个MemStore,一个BlockCache和多个HFile组成。两个不同列族的MemStore  BlockCache 毫无关系。
  5. 也有书里谈到Store这个概念,实际就是对于一个列族的管辖区域。

三.HBase读写路径

  1.  执行写入时会写到两个地方:WAL和MemStore,只有当这两个地方的变化信息都被成功写入并确认后,才认为写动作完成。MemStore填满(hbase.hregion.memstore.flush.size默认64M,在hbase0.96 habse-default里为128M)后被flush到硬盘,所以客户端的写操作不会与底层的HFile直接交互。
  2. 从HBase中读出一行,首先会检查MemStore等待被flush的数据,其次检查BlockCache是否包含该行的Block信息,最后访问硬盘上的HFile。BlockCache使用LRU算法,缓存的是Block块而非Block所有。

四.客户端写缓冲区

  1. 每一个put操作实际上都是一个RPC操作。当然,HBase的API配备了一个写缓冲区,它负责收集put请求,然后调用RPC操作一次性将put发送给服务器。
  2. 注意这个缓冲区位于客户端,默认情况下是禁用的。HTable的setAutoFlush(false)方法可以将自动刷新autoflush设置为false来激活缓冲区。
    @Override
      public boolean isAutoFlush() {
        return autoFlush;
      }
    Deprecated
      @Override
      public void setAutoFlush(boolean autoFlush) {
        setAutoFlush(autoFlush, autoFlush);
      }
    
      /**
       * {@inheritDoc}
       */
      @Override
      public void setAutoFlushTo(boolean autoFlush) {
        setAutoFlush(autoFlush, clearBufferOnFail);
      }
    
      /**
       * {@inheritDoc}
       */
      @Override
      public void setAutoFlush(boolean autoFlush, boolean clearBufferOnFail) {
        this.autoFlush = autoFlush;
        this.clearBufferOnFail = autoFlush || clearBufferOnFail;
      }
     
  3. 也可以配置此缓冲区大小。默认大小为2MB。
    @Override
      public long getWriteBufferSize() {
      }
    public void setWriteBufferSize(long writeBufferSize) throws IOException {
      }
     
  4. 当需要强制把数据写到服务器时,使用
    @Override
      public void flushCommits() throws InterruptedIOException, RetriesExhaustedWithDetailsException {
        // As we can have an operation in progress even if the buffer is empty, we call
        //  backgroundFlushCommits at least one time.
      }
     
  5. 此缓冲区没有任何备份,这些数据可能丢失。

五.大小合并 自动分区

     首先要明白一个概念,大小合并是针对HFile,自动分区是针对region。

  1. 当一个region里的存储文件增长到大于配置的hbase.hregion.max.filesize默认256M时,region会被一分为二。关于分区的过程,我还没弄太明白。
  2. 大小合并
    1. 小合并:
      1. 将多个HFile合并成一个HFile。经过读-合并写-删除步骤。
      2. 小合并的文件数量由hbase.hstore.compaction.min默认3且要求大于等于2和hbase.hstore.compaction.max默认10决定。
      3. 小合并的文件大小由hbase.hstore.compaction.min.size默认64M和hbase.hstore.compaction.max.size默认Long.MAX_VALUE决定。hase.hstore.compaction.min.size比较奇葩,小于这个值才被include。既然这样,hbase.hstore.compaction.max.si还有何用?
    2. 大合并:
      1. 将给定region的一个列族的所有HFile合并成一个HFile。
      2. 大合并是HBase清理被删除的唯一机会。如果一个单元的版本超过了最大数量,也会在大合并时删掉。
      3. 触发大合并:shell命令或客户端API;距离上次大合并是否超过hbase.hregion.majorcompaction默认24小时;小合并的文件就是一个列族的所有文件且满足文件大合并大小要求,小合并被提升为大合并。

六.HFile

  1. 我们已经知道HFile的两种来源:由MemStore flush而来,由其它HFile合并而来。所以我们并不知道HFile到底有多大,实际上我们也不需要知道。需要了解的是,HFile只是一个逻辑上的概念,真正存储的是HDFS,而HFile与HDFS的块之间没有匹配关系,HBase把文件透明的存储在HDFS上,如一个HFile232M,将被存储在两个Block上,Block1 128M,Block2 104M。 
  2. HFile块大小64KB怎么理解?先看一个HFile的结构。Hadoop学习四十一:HBase基础这里的块指的就是Data块(一系列KeyValue的集合),也就是一个HFile由许多大小为64KB的Data块以及其它项组成。
  3. KeyValue的结构Hadoop学习四十一:HBase基础这个比较好理解。通过此图可以看到,如果一个rowkey存在多个版本,每个版本都将对应一个KeyValue,因为它们TimeStamp不同。

      当然HBase还有许多值得深究的地方,后面会不断学习不断更新本文。如有错误,欢迎指出。

相关推荐