`
king_c
  • 浏览: 222721 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hfile存储结构

 
阅读更多

转自淘宝数据平台

 

HBase中的所有数据文件都存储在Hadoop HDFS文件系统上,主要包括两种文件类型:

1. HFile, HBase中KeyValue数据的存储格式,HFile是Hadoop的二进制格式文件,实际上StoreFile就是对HFile做了轻量级包装,即StoreFile底层就是HFile

2. HLog File,HBase中WAL(Write Ahead Log) 的存储格式,物理上是Hadoop的Sequence File

下面主要通过代码理解一下HFile的存储格式。

HFile

下图是HFile的存储格式:

HFile由6部分组成的,其中数据KeyValue保存在Block 0 … N中,其他部分的功能有:确定Block Index的起始位置;确定某个key所在的Block位置(如block index);判断一个key是否在这个HFile中(如Meta Block保存了Bloom Filter信息)。具体代码是在HFile.java中实现的,HFile内容是按照从上到下的顺序写入的(Data Block、Meta Block、File Info、Data Block Index、Meta Block Index、Fixed File Trailer)。

KeyValue:HFile里面的每个KeyValue对就是一个简单的byte数组。但是这个byte数组里面包含了很多项,并且有固定的结构。我们来看看里面的具体结构:

开始是两个固定长度的数值,分别表示Key的长度和Value的长度。紧接着是Key,开始是固定长度的数值,表示RowKey的长度,紧接着是 RowKey,然后是固定长度的数值,表示Family的长度,然后是Family,接着是Qualifier,然后是两个固定长度的数值,表示Time Stamp和Key Type(Put/Delete)。Value部分没有这么复杂的结构,就是纯粹的二进制数据了。

Data Block:由DATABLOCKMAGIC和若干个record组成,其中record就是一个KeyValue(key length, value length, key, value),默认大小是64k,小的数据块有利于随机读操作,而大的数据块则有利于scan操作,这是因为读KeyValue的时候,HBase会将查询到的data block全部读到Lru Block Cache中去,而不是仅仅将这个record读到cache中去。

private void append(final byte [] key, final int koffset, final int klength, final byte [] value, final int voffset, final int vlength) throws IOException {

this.out.writeInt(klength);

this.keylength += klength;

this.out.writeInt(vlength);

this.valuelength += vlength;

this.out.write(key, koffset, klength);

this.out.write(value, voffset, vlength);

}

Meta Block:由METABLOCKMAGIC和Bloom Filter信息组成。

public void close() throws IOException {

if (metaNames.size() > 0) {

for (int i = 0 ; i < metaNames.size() ; ++ i ) {

dos.write(METABLOCKMAGIC);

metaData.get(i).write(dos);

}

}

}

File Info: 由MapSize和若干个key/value,这里保存的是HFile的一些基本信息,如hfile.LASTKEY, hfile.AVG_KEY_LEN, hfile.AVG_VALUE_LEN, hfile.COMPARATOR。

private long writeFileInfo(FSDataOutputStream o) throws IOException {

if (this.lastKeyBuffer != null) {

// Make a copy.  The copy is stuffed into HMapWritable.  Needs a clean

// byte buffer.  Won’t take a tuple.

byte [] b = new byte[this.lastKeyLength];

System.arraycopy(this.lastKeyBuffer, this.lastKeyOffset, b, 0, this.lastKeyLength);

appendFileInfo(this.fileinfo, FileInfo.LASTKEY, b, false);

}

int avgKeyLen = this.entryCount == 0? 0: (int)(this.keylength/this.entryCount);

appendFileInfo(this.fileinfo, FileInfo.AVG_KEY_LEN, Bytes.toBytes(avgKeyLen), false);

int avgValueLen = this.entryCount == 0? 0: (int)(this.valuelength/this.entryCount);

appendFileInfo(this.fileinfo, FileInfo.AVG_VALUE_LEN,

Bytes.toBytes(avgValueLen), false);

appendFileInfo(this.fileinfo, FileInfo.COMPARATOR, Bytes.toBytes(this.comparator.getClass().getName()), false);

long pos = o.getPos();

this.fileinfo.write(o);

return pos;

}

Data/Meta Block Index: 由INDEXBLOCKMAGIC和若干个record组成,而每一个record由3个部分组成 — block的起始位置,block的大小,block中的第一个key。

static long writeIndex(final FSDataOutputStream o, final List<byte []> keys, final List<Long> offsets, final List<Integer> sizes) throws IOException {

long pos = o.getPos();

// Don’t write an index if nothing in the index.

if (keys.size() > 0) {

o.write(INDEXBLOCKMAGIC);

// Write the index.

for (int i = 0; i < keys.size(); ++i) {

o.writeLong(offsets.get(i).longValue());

o.writeInt(sizes.get(i).intValue());

byte [] key = keys.get(i);

Bytes.writeByteArray(o, key);

}

}

return pos;

}

Fixed file trailer: 大小固定,主要是可以根据它查找到File Info, Block Index的起始位置。

public void close() throws IOException {

trailer.fileinfoOffset = writeFileInfo(this.outputStream);

trailer.dataIndexOffset = BlockIndex.writeIndex(this.outputStream,

this.blockKeys, this.blockOffsets, this.blockDataSizes);

if (metaNames.size() > 0) {

trailer.metaIndexOffset = BlockIndex.writeIndex(this.outputStream,

this.metaNames, metaOffsets, metaDataSizes);

}

trailer.dataIndexCount = blockKeys.size();

trailer.metaIndexCount = metaNames.size();

trailer.totalUncompressedBytes = totalBytes;

trailer.entryCount = entryCount;

trailer.compressionCodec = this.compressAlgo.ordinal();

trailer.serialize(outputStream);

}

注:上面的代码剪切自HFile.java中的代码,更多信息可以查看Hbase源代码。

参考:http://www.searchtb.com/2011/01/understanding-hbase.html

http://th30z.blogspot.com/2011/02/hbase-io-hfile.html

分享到:
评论

相关推荐

    HBASE hfile v2 format

    hbase hfile v2 format draft 描述存储结构

    HBase存储架构详解

    7. HFile:HFile是HBase中的文件格式,负责存储Region中的数据块。 8. MemStore:MemStore是HRegion中的内存存储单元,负责管理Region中的数据、数据的读写操作等。 9. HLog:HLog是HBase中的日志系统,负责记录...

    hadoop mr file2hfile2hbase

    在大数据处理领域,Hadoop MapReduce是一种广泛使用的分布式计算框架,而HBase是基于Hadoop的数据存储系统,用于处理大规模的非结构化数据。本文将深入探讨如何使用Hadoop MapReduce任务将文件数据转换为HBase所需的...

    栅格GIS系统的分布式存储方案

    HBase架构为三级存储结构,包括HMaster、RegionServer和HFile。HBase限制中提到列最大长度为20MB,列簇数量受限于区服务器的硬件,但对项目影响不大。 栅格GIS系统对HBase的要求包括能够存储PB级别的大规模数据集、...

    藏经阁-云上HBase冷热分离实践.pdf

    热表的HFile存储在基于云盘的HDFS中,冷表的HFile存储在OSS中。 云HBase冷存架构 云HBase冷存架构主要包括HDFS、OSS、ApsaraDistributedFileSystem和HBase。其中,HDFS用于存储热表的HFile,OSS用于存储冷表的...

    Cassandra与HBase系统架构比对.pdf

    HBase的读写性能也很高,因为它使用了 REGIONSERVER 和 HFile来存储数据。HBase可以提供高达10,000次/秒的写性能和5,000次/秒的读性能。 Cassandra和HBase都是高性能的NoSQL数据库管理系统,它们之间有着许多相似之...

    hfile-to-hbase:处女发表

    HFile是HBase的一种数据存储格式,主要用于存储HBase表的数据块,而HBase则是一个分布式、版本化的NoSQL数据库,广泛应用于大数据处理领域。 在Java开发中,处理HFile与HBase的交互是常见的任务,特别是在数据迁移...

    MR-read-Hfile2

    然而,这也要求开发者具备深入理解HBase数据存储结构和MapReduce编程模型的能力。 在实际应用中,需要注意的是,虽然直接读取HFile可以提高效率,但这种方法可能不适合实时查询或更新操作,因为它们缺乏HBase服务层...

    备注标签博文篇

    HFile是HBase数据持久化的一种方式,它将数据以键值对的形式存储在HDFS上,采用了分层的存储结构,以优化磁盘I/O性能。每个HFile包含一个或多个Block,每个Block内数据按Key排序,便于快速查找。HFile还支持数据压缩...

    HBase架构简介.pdf

    HFile存储在/hbase目录下,WAL文件位于.logs子目录,定期进行日志轮换。旧的日志文件会被移动到.oldlogs目录,由HMaster定时清理。 在HBase中,表的region可能会因为数据增长而分裂。当一个region的大小超过预设...

    时序数据库技术和架构演进.pdf

    1. **HFile**: HFile是HBase中的文件格式之一,用于存储时序数据。它是一种高效的列式存储格式,支持数据压缩和索引功能,能够有效地提高数据的读写性能。 2. **KeyValue结构**: 在时序数据库中,数据通常以KeyValue...

    HBase应用架构PDF版本

    《HBase应用架构》这本书由吉恩-马克·斯帕加里撰写,中文版由陈敏敏、夏锐和陈其生翻译,深入探讨了分布式大数据存储系统HBase的架构和应用。HBase是建立在Apache Hadoop之上的一款非关系型数据库,特别适合处理...

    李中欢_大数据作业四1

    大数据作业四HBase知识点总结 HBase是Hadoop数据库,能够随机访问、实时存储和检索大数据平台。...它的表结构、面向列的存储和权限控制、行键和列族、HFile和Store等特点使其能够高效地存储和检索大规模数据集。

    Hadoop数据迁移--从Hadoop向HBase载入数据

    HBase是一个基于Hadoop的分布式数据库,它主要用于随机实时读/写访问超大表,适用于存储半结构化或非结构化稀疏数据。在Hadoop数据迁移过程中,从Hadoop向HBase载入数据是常见的操作。 数据迁移主要分为两个步骤: ...

    HugeTable面向应用结构数据存储系统

    - **HFile**:用于存储数据的文件格式,支持列族(Column Families)。 - **索引存储**:提供高效的索引机制,以加速数据检索过程。 - **Web管理界面**:提供了一个基于Web的管理平台,用于监控系统状态、配置参数等...

    HBase概述——HBase的存储模型.pdf

    MemStore的Flush过程包括了开启新的MemStore来接收新写入,同时将旧的MemStore内容生成HFile存储到HDFS。随着时间推移,HDFS上会累积大量小文件,影响查询效率,这时就需要进行Compact操作。Compact分为minor ...

    藏经阁-HBase2.0重新定义小对象实时存取.pdf

    MOB 技术的架构主要包括 rowtsf2 存储 MOB 对象、Memstore Scanner 扫描 HFile 读取路径、Compaction Index 合并索引文件等。MOB 技术的实现是基于 HBase 2.0 的架构,使用 MOB 阈值来控制小对象的存储。 MOB 技术...

    HBase应用架构

    HBase是Apache Hadoop生态系统中的一个关键组件,它提供了高可靠、高性能、分布式的列式存储功能,尤其适合处理海量结构化和半结构化数据。 1. **HBase基础概念** - HBase是基于Google Bigtable的开源实现,主要为...

    气象大数据存储和查询优化[收集].pdf

    Hbase的存储框架基于HDFS,将数据存储在HFile中,每个列族对应一个HFile,这样可以优化I/O操作。此外,Hbase还引入了协处理器机制,允许在数据存储和查询过程中进行自定义操作,进一步提升系统的灵活性和性能。 ...

Global site tag (gtag.js) - Google Analytics