Hadoop SequenceFile
詳見:http://hadoop.apache.org/docs/r1.0.4/api/org/apache/hadoop/io/SequenceFile.html
3個概念:記錄(Record)、塊(Block)、文件(File)。
記錄(Record): Hadoop SequenceFile的存儲格式是通用的KV數據存儲格式,key和value都是變長二進制數據。Record Len 表示的是key 和value 的占用的byte之和,Record壓縮方式中 key 是不壓縮。同步點Sync 作用數據恢復和掃描。當指定讀取的位置不是記錄首部的時候,通過讀取一個同步點的記錄,不至於讀取數據的reader “迷失”。 (hadoop實現:每2000byte 就插入一個同步點,這個同步點占16 byte ,包括同步點標示符:4byte ,一個同步點的開銷是20byte 。)對二進制數據,任何字符都可出現,故采用單字節的Sync標識難於區分數據和同步點,需要采用多字節的Sync(什么樣的多個字節常被用來所Sync標識?0xFFFFFFFFFFFFFFFF?)。
塊(Block):存儲Block header和多個record數據。Hadoop SequenceFile可認為沒有塊概念,只有Block-Compressed SequenceFile才會將多個record壓縮后一起存儲,詳見hadoop文檔。
文件(File): 文件頭+數據。存儲如下信息:文件標識SEQ,key和value的格式說明,壓縮相關信息,metadata(二級索引,The sequence file also can contain a “secondary” key-value list that can be used as file Metadata. This key-value list can be just a Text/Text pair, and is written to the file during the initialization that happens in the SequenceFile.Writer constructor, so you can’t edit your metadata.),Sync。常規的文件頭需要的數據:文件標識、Sync標識、數據格式說明(含壓縮)、文件元數據(時間、owner、權限等)、檢驗信息等。
HBase
Hbase MapFile
Hbase最初直接使用Hadoop的MapFile實現有序的Key存儲(將數據和索引分別存成Hadoop SequenceFile)。用MapFile實現有序Key存儲需要解決2個問題:1)如何刪除數據?2)如何保證數據有序?解決方案:1)使用刪除標志Type;2)內存中排序,達到閾值后寫成MapFile(MemStore實現)。
MemStore 的方案意味這存在多個MapFile,這樣對於讀數據意味着可能需要掃描多個文件。為了減少需要讀取的文件數,Hbase的設計者引入compaction:1) 將多個小文件合並成大文件;2)將所有的文件合並成一個大文件。
HFile V1
引入版本:HBase 0.20。核心特性:1)將index和數據合成一個文件(為減少index量,可只對每個塊的首個key做索引);2)增加metadata特性。
The Meta block is designed to keep a large amount of data with its key as a String, while FileInfo is a simple Map preferred for small information with keys and values that are both byte-array. Regionserver’s StoreFile uses Meta-Blocks to store a Bloom Filter, and FileInfo for Max SequenceId, Major compaction key and Timerange info. This information is useful to avoid reading the file if there’s no chance that the key is present (Bloom Filter), if the file is too old (Max SequenceId) or if the file is too new (Timerange) to contain what we’re looking for.
HFile V2
引入版本:HBase 0.92。核心特性:1)引入多級索引;2)引入基於塊的索引和Bloom Filter(解決問題:無需載入所有索引和Bloom Filter數據)。
從圖上可知,HFileV2有3種索引:Root Index記錄每個塊首個key極其索引;Leaf Index記錄塊內每個record的索引;intermediate index記錄每個塊最后的key極其索引。(Since the index is moved to block level you then have a multi-level index, meaning each block has its own index (leaf-index). The last key of each block is kept to create the intermediate/index that makes the multilevel-index b+tree like.)
前向掃描和后向掃描:The block header now contains some information: The “Block Magic” field was replaced by the “Block Type” field that describes the content of the block “Data”, Leaf-Index, Bloom, Metadata, Root-Index, etc. Also three fields (compressed/uncompressed size and offset prev block) were added to allow fast backward and forward seeks.
前綴壓縮和差異壓縮(Prefix and Diff Encoding):HBase的數據是有序的,因此Key差異不大,為了提高壓縮比,引入2種針對性的壓縮算法。
HFile V3
為了進一步提高壓縮率:1)將塊內的key和value分開存儲, key存在塊前面,value存在塊后面。2)Compress timestamps。
相關文章
Hadoop I/O: Sequence, Map, Set, Array, BloomMap Files
附錄 oceanbase(類似HFile)
記錄:oceanbase的記錄value是有結構的二進制數據。格式為:keyLen(2B)+keyData+valueData。 其中valueData由一個或多個common::ObObj對象串化而成。詳見:oceanbase\src\sstable\ob_sstable_row.h
塊(Block)格式:block header + serialized rows + row index。詳見:oceanbase\src\sstable\ob_sstable_block_builder.h
文件格式:詳見:oceanbase\src\sstable\ob_sstable_writer.h
Leveldb 實現原理:http://www.cnblogs.com/haippy/archive/2011/12/04/2276064.html
leveldb源代碼分析: http://blog.nosqlfan.com/tags/leveldb