HBase存储文件格式概述

系统 3471 0

概述

HBase是基于Bigtable论文的面向列的分布式存储系统,其存储设计是基于Memtable/SSTable的。 其它如 Cassandra 都是采用的该设计。

整个存储分为两部分,一部分为内存中的 MemStore(Memtable) ,另外一部分为磁盘 ( 这里是 HDFS) 上的 HFile(SSTable) 。下面分别讲述两种类型的存储分别的实现:

MemStore 中最重要的变量是:

    volatile KeyValueSkipListSet kvset;
  

这里的 KeyValueSkipListSet 里面实际是这样的:

    private final ConcurrentNavigableMap<KeyValue, KeyValue> delegatee;
  

换句话说,其实就是一个放内存的 Map 存放着 kv

 

HFile HBase 实际的文件存储格式,它是基于 TFile 的文件格式,替换了早期的 MapFile ,改进了性能。

然后 HBase 会进行控制,当 MemStore 写满了以后进行刷磁盘操作。

而HLog是HBase的日志格式实现,主要是在写入的时候进行write-ahead-log,主要为recovery而做。

HFile

HFile HBase 中实际存数据的文件,为 HBase 提供高效快速的数据访问。它是基于 Hadoop TFile ,模仿 Google Bigtable 架构中的 SSTable 格式。之前的 Hadoop MapFiles 已经被证明性能不能到达我们的期望。文件格式如下:


HBase存储文件格式概述

 

 

文件是变长的,唯一固定的块是 File info Trailer ,如图所示, Trailer 有指向其它块的指针,这些指针也写在了文件里, Index 块记录了 data meta 块的偏移量, data meta 块都是可选的。

块的大小是由表创建时的 HColumnDescriptor 指定的,如下是 master web interface 上看到的一个例子:

{NAME => 'docs', FAMILIES => [{NAME => 'cache', COMPRESSION => 'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'false'}, {NAME => 'contents', COMPRESSION => 'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'false'}, ...

默认的大小是 64KB ,下面是一段关于 HFile 的解释:

“最小的块大小。我们建议通常将其设置为 8KB 1MB 之间,如果经常进行基于 primary key 的顺序访问,可以设置更大的块大小,但是这样会带来低效的随机访问效率(更多的数据需要被解压缩)。更小的块大小将带来更好的随机访问效率,但是会耗费更多的内存去维持索引,并且在创建的时候会比较慢,因为需要 flush 压缩流,这将导致一个 FS I/O flush 。由于内部的压缩 codec 的缓存,最小的块大小可以为 20-30KB


 

 

 

上图是 HFile 中每个 KeyValue 的格式,和普通的 key-value 没有太大的区别。

 

HLog

源码中的实现类是 HLog 。每个 HRegionServer 会对应一个 HLog HRegion 在初始化的时候 HRegionServer 会将该 HLog 的实例作为构造函数传入其中。 HLog 的核心函数是其 append() 函数。

HLog 中,会维持一个 Sequence Number ,是一个 AtomicLong 型,当一个 Region 启动的时候会从 HFile Meta field 里面读出当前的 Sequence Number


HBase存储文件格式概述


如图所示,由于 HLog Region 之间共享的,因此, log 的顺序是不定的,这一点后面会提到。当一个 HRegionServer 崩溃掉后, HMaster 会让 HRegionServer 重启的时候根据日志进行恢复。

当前的 WAL 使用的是 Hadoop 下的 SequenceFile 格式,其 key HLogKey 实例,它包括以下内容:

    private byte [] encodedRegionName;

private byte [] tablename;

private long logSeqNum;

// Time at which this edit was written.

private long writeTime;

private byte clusterId;

  

 

由于操作系统处理批量的数据要块过单个单个的处理,因此,需要进行 flush 日志。 LogFlusher 实现了该功能,它调用了 HLog.optionalSync() ,它将检查是否到了 hbase.regionserver.optionallogflushinterval ,默认是 10 秒。

         日志的大小会有一个限制,这是用 hbase.regionserver.logroll.period 参数控制的,默认是 1 个小时。到点以后 LogRoller 会触发操作,检查当前的 Sequence Number ,看小于它的所有日志是否完整。

 

参考文献

http://www.larsgeorge.com/

主要参考自larsgeorge的hbase系列文章

HBase存储文件格式概述


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论