`
085567
  • 浏览: 220178 次
  • 性别: 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.tbdata.org/archives/1551

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

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

分享到:
评论

相关推荐

    hadoop mr file2hfile2hbase

    HFile是HBase内部存储数据的二进制格式,它提供高效的随机读取性能。在将数据加载到HBase之前,通常会先将数据转换成HFile,以便于后续的高效写入和存储。 **MapReduce过程**: 1. **数据预处理**:首先,你需要...

    Hbase几种入库方式

    HFile 是 Hbase 的存储文件格式,预先生成 HFile 后,可以将其直接加载到 Hbase 中。这是一种高效的入库方式,尤其是在大规模数据集的情况下。预先生成 HFile 入库的优点是快捷、可靠,缺点是需要提前生成 HFile,...

    MR-read-Hfile2

    在这个特定的项目中,它被优化来直接从HBase的数据存储格式——HFile中读取数据,而不是通过传统的HBase接口,如TableMapReduceUtil。 HBase是建立在Hadoop之上的一个分布式、可扩展的NoSQL数据库,它以键值对的...

    LevelDB SSTable格式详解

    HBase是一个开源的Bigtable实现,它使用HFile作为数据存储格式。通过对比SSTable和HFile的文件格式,可以从文件结构、索引机制、压缩方式等方面分析它们之间的异同,从而更深入地了解两种存储格式的优缺点。 8. ...

    hfile-to-hbase:处女发表

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

    备注标签博文篇

    HFile是HBase存储数据的主要格式,它是Hadoop生态系统的一部分,主要用于大规模分布式存储。HBase是一个基于Google Bigtable设计的开源NoSQL数据库,适用于高吞吐量的随机读写操作。 HFile是HBase数据持久化的一种...

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

    HFile是HBase中的存储格式文件,它可以被HBase识别和读取,类似于传统数据库中的数据文件。在转换过程中,Hadoop MapReduce程序用于处理文本文件中的数据,并生成HBase能识别的HFile格式。这一步骤需要将原始文本...

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

    MOB 对象的存储格式主要包括 Row Key、Qualifier、Timestamp、MOB Value Length、File Path 和 Tag 等字段。其中,Row Key 是 MOB 对象的唯一标识,Qualifier 是 MOB 对象的名称,Timestamp 是 MOB 对象的时间戳,...

    hbase+批量上传jar包

    1. **准备数据**:数据通常需要预先按照HBase的格式组织好,例如,如果使用HFile批量加载,数据会被转换成HFile格式,这是一种HBase内部存储格式。数据可以来源于各种源,如CSV、JSON或其他数据库。 2. **创建jar包...

    How-to: Use HBase Bulk Loading, and Why

    1. **生成SequenceFile**:首先,我们需要将数据转化为SequenceFile格式,这是一种Hadoop支持的高效存储格式,它包含键值对,并且可以进行压缩,适合大规模数据处理。 2. **创建表和列族**:在导入数据前,需要确保...

    MR程序Bulkload数据到hbase

    1. **数据预处理**:首先,使用MapReduce作业将源数据转换为HBase的内部存储格式HFile。在这个阶段,Mapper处理输入数据,可能涉及解析、清洗、转换等操作。Reducer则负责将处理后的数据写入HDFS上的一个临时目录,...

    大数据性能调优之HBase的RowKey设计.docx

    1. 影响HFile存储效率:如果RowKey过长,会极大影响HFile的存储效率。例如,如果RowKey超过100字节,1000w行数据,光RowKey就要占用100*1000w=10亿个字节,将近1G数据。 2. 影响MemStore缓存:如果RowKey字段过长,...

    HBase存储架构详解

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

    hbase海量数据的全量导入方法

    数据以HFile格式存储于HDFS上,HFile是一种优化过的数据文件格式,支持高效的数据检索和压缩。 #### 全量导入挑战与解决方案 在全量导入过程中,HBase的compaction机制可能会显著减慢写入速度。这是因为compaction...

    jobs_hbase_mirrorm5y_BulkLoadjava_

    在HBase中,Bulk Load是一种高效的数据加载方法,它允许我们预先将数据转换为HFile格式,然后直接加载到表中,避免了多次写入RegionServer的开销,从而提高了性能。本文将深入探讨如何使用Java API实现HBase的Bulk ...

    hbase-2.4.11-src.tar.gz

    HBase使用HFile作为数据存储格式,这是一种二进制格式,支持高效的随机读取和压缩,降低了存储成本。 8. **过滤器和扫描器**: HBase提供了丰富的过滤器和扫描器机制,用户可以通过定义特定的过滤规则来筛选需要...

    李中欢_大数据作业四1

    StoreFile以HFile格式保存在HDFS中。 7. MemStore和StoreFile: MemStore是RegionServer上的一段内存空间;StoreFile是HDFS中的一个HFile文件。数据库操作会先存入MemStore,当MemStore满了后会转存到StoreFile中。...

    hadoop考试复习试题200道.docx

    Hive作为数据仓库工具,支持多种存储格式,如TextFile、SequenceFile和RCFile,但不包括HFile,HFile是HBase的存储格式。 Spark的任务被划分为Stage,每个Stage由多个Task组成,Stage的划分基于shuffle操作。在...

    java从本地读文件并上传Hbase

    // 假设每一行格式为"key\tvalue" String[] parts = line.split("\t"); byte[] rowKey = parts[0].getBytes(), value = parts[1].getBytes(); Put put = new Put(rowKey); put.addColumn(family, Bytes.toBytes(...

Global site tag (gtag.js) - Google Analytics