如何创建filter,如何创建file文件

  

  本文主要介绍HBase的一些背景知识,希望通过本文能对HBase有一个大致的轮廓。   

  

  在LSM之前,通常使用三种基本存储引擎,即   

  

  哈希LSM树(日志结构合并树)   

  

  Hash engine是哈希表的持久化实现,支持添加、删除、更改和随机读取操作,但不支持顺序扫描。相应的存储系统是一个键值存储系统,比如Bitcask。它只支持追加操作,delete只通过将value标识为特殊值并定期压缩来实现垃圾回收。B 树   

  

  B树存储引擎是B树的持久化实现,它不仅支持增加、删除、读取和改变单个记录的操作,还支持顺序扫描。相应的存储系统是关系数据库。通过数据库中的索引来访问数据。在Mysql InnoDB中,有一种叫做聚簇索引的东西,其中行的数据被存储并组织成B树结构。有关B树的更多信息,请参考这里。   

  

  聚焦LSM-TreeLSM树酒店   

  

     

  

  图片来源LSM-树纸。LSM树原理将一棵大树分成N棵小树,它们首先被写入内存。随着小树越来越大,内存中的小树会刷新到磁盘,磁盘中的树可以定期合并成一棵大树,以优化读取性能。内存树的一部分与磁盘中的一级树合并,直接更新磁盘中的树可能会破坏物理块的连续性。然而,在实际应用中,通常有多个lsm层。当磁盘中的小树合并成一棵大树时,可以重新排列顺序,使写块连续,优化读取性能。   

  

  HBase存储引擎采用LSM树架构,总体示意图如下   

  

     

  

  当区域服务器(RS)接收到写请求时,RS将把请求传送到相应的区域。每个区域存储一些列(一组行)。根据不同的列族,这些列数据存储在相应的列族(CF)中。不同CFs中的数据存储在各自的H Stores中,H Stores由一个Memstore和一系列Storefiles组成(Storefiles是HFfiles的轻量级打包,即HFfiles在Storefiles的底层)。Memstore位于RS的主存中,而HFiles写入HDFS。当RS处理一个写请求时,数据首先被写入Memstore,然后当Memstore达到一定阈值时,Memstore中的数据会被刷新到HFile中。当HFile达到一定阈值时,将触发压缩操作,执行文件删除操作。   

  

  补充:HBase存储引擎没有使用Tree实现有序存储,而是使用了Doug Lea的跳转表(Memstore是一种排序并发skiplist映射)。   

  

  使用Memstore的主要原因是存储在HDFS上的数据需要按行键排序。HDFS本身设计为顺序读/写,因此不允许修改。这样HBase就不能有效地写数据了,因为要写到HBase的数据不会被排序,也就是说没有针对以后的检索进行优化。为了解决这个问题,HBase将最近收到的数据缓存在Memstore中,在持久化到HDFS之前对其进行排序,然后按顺序快速写入HDFS。需要注意的一点是,在实际的HFile中,不仅仅是简单排序的列数据的列表。下面将详细介绍HFileV2。   

  

  Hadoop天生具有SequenceFile格式,因此可以通过追加键/值对来存储文件。由于hdfs的仅附加功能,不允许修改插入的文件格式。如果你想找到一个特定的关键,那么你必须促进整个文件,直到你找到这个关键。   

  

  在这种情况下,您必须通过顺序读/写模式来处理它。那么问题来了,像HBase,如果想做随机、低延迟的读写访问,怎么玩呢?   

  

  补充:在h base 0 . 2 . 0之前的早期版本中使用MapFile。详见HBASE-61。   

  

  参见下面的HFIle。   

  

  HFile v1   

  

  在HBase0.2.0中,映射文件被HFile取代,HFile是为HBase数据存储的映射。HFile的想法来自于MapFile,但它比一个简单的键/值文件增加了更多的功能。例如,HFile增加了元数据和索引   

支持。
data blocks包含了和MapFile相同的key/value,对每个“block close operation” 操作,first key被添加到jindex,在HFile关闭时写入。
HFile文件格式添加了两个额外的“metadata” block types,即meta和FileInfo,这些两个key/value blocks在接近file关闭时写入。
Meta block被设计成保持大量数据,因此它的key类型是String,然而,FileInfo只是一个简单的Map,通过keys和values提供小量信息,因此key和values都是byte-array类型。ReginServers的StoreFile使用Meta-Blocks同存储Bloom Filter和FileInfo为支持Max SequenceId, Major compaction key and Timerange info。这些很好的优化避免在如下情况读文件。

  

file没有变化(key不存在Boom Filter,如果开启了Boom Filter)file is too old(Max SequenceId)或者这个文件太新(Timerange)没有包含我们正在查找的key。HFile v2
motivation
在regionserver中HFile format的large Bloom filters和block indexes导致消耗了大量的内存后和启动慢。每个HFile 100M,当超过20个regions时Bloom Filters增长到2GB,Block indexes增长到6GB。region会直到它的所有block index data加载完毕才会open。Large Bloom filters会产生可能的性能问题,第一次get请求需要查找Bloom filter会有潜在的可能性导致加载整个Bloom filter bit数组。
为了加速regionserver启动,于是将Bloom filters和block indexes分成成multiple blocks,并且在他们fill up时写进他们的blocks。这样可以减少HFile写内存的占用。在Bloom filter情况下,“filling up a block” 指累积到固定bit array大小的keys。现在称Bloom filter blocks and index blocks为“inline blocks”,“inline blocks”使用data blocks散列,与此同时,我们我再依赖block offsets的值推断data block长度(在v1版本中用block之间的block offset去推断data block长度)。
HFile被设计成low leve的文件存储格式,它不应该处理程序特定的细节,比如Bloom filters,它在StoreFile层次上被处理。因此,我们在HFile中叫Bloom filter为 “inline” blocks。我们也提供HFile的接口去写它们的inline blocks。
另外一个文件格式是通过使用contiguous “load-on-open” 加载打开HFile必须的部分,目的在于减少regionserver启动时间。目前,当HFile打开,会有独立的seek操作去读取trailer、data/meta和file info。有超过两个seek操作读取Bloom filter的“data”和“meta”部分,在v2,我们只需一次seek去读取trailer,然后再次从contiguous block去seek我们需要打开file的部分。

  

在HBase0.92中引入了HFile v2(HBASE-3857),对大量数据存储在性能上有很大的提升,主要问题是HFile v1需要在内存中加载所有的indexes和大量的Bloom Filters,在v2中引入multi-level indexes和block-level Bloom Filter。总而言之,HFile v2提升了在速度、内存和cache使用。
HFile v2主要特性是引入了Bloom filter blocks and index blocks被称为 “inline blocks”,通过这个来分裂每个block的index 和Bloom Filter,而不是在内存中加载所有的 index和Bloom Filter。通过这个方式,你可以加载你需要的。
因为index被移动到block层次,于是有了multi-level index,表示对每个block都有自己的index(leaf-index)。对每个block被保持并且被创建index作为multilevel-index b+tree。
现在在block header就添加一些信息,“Block Magic” 字段被替换为 “Block Type”,表示这个block是“Data”,Leaf-Index, Bloom, Metadata, Root-Index等等。当然, compressed、uncompressed size和offset prev block这三个字段也被添加用于快速的backward和forward seeks。看下overview图

  


HFile具体得文件格式包括7部分

  

Unified version 2 block formatBlock index in version 2Root block index format in version 2Non-root block index format in version 2Bloom filters in version 2File Info format in versions 1 and 2Fixed file trailer format differences between versions 1 and 21.version 2版本每个block的data section都包含的字段
2.HFile version 2中有三种类型的block indexes,使用root and non-root两种方式存储
Data index — version 2 multi-level block index, consisting of:
o Version 2 root index, stored in the data block index section of the file
o Optionally, version 2 intermediate levels, stored in the non-root format in the data index section of the file.
Intermediate levels can only be present if leaf level blocks are present.
o Optionally, version 2 leaf levels, stored in the non-root format inline with data blocks

  

Meta index — version 2 root index format only, stored in the meta index section of the file

  

Bloom index — version 2 root index format only, stored in the “load-on-open” section as part of Bloom filter metadata.

  

3.root index format
4.Non-root block index format
5.与version 1对比,version 2 HFile Bloom filter metadata被存储在HFile的load-on-open section提高启动速度。
6.File Info format in versions 1 and 2
hfile.LASTKEY The last key of the file (byte array)
hfile.AVG_KEY_LEN The average key length in the file (int)
hfile.AVG_VALUE_LEN The average value length in the file (int)
在version 2中,File info format没有改变,但是我们移动这个file info到文件的最后section,在HFile被opend时能被加载。同时,我们在verson 2 file info不再存储comparator,取而代之的是我们存储它到固定的trailer,这是因为当我们在解析HFile的load-on-open section时需要知道comparator。
7.Fixed file trailer format differences between versions 1 and 2

  

其中,Unified version 2 block format中存储数据keyvalue,format格式如下

  

  

大致分为三块,key/value length, key和value。

  

关于HFileV2详细设计文档可以看HBASE-3857

  

hbase hfile命令查看HFile文件

  

usage: HFile <-a> <-b> <-e> <-f | -r > <-h> <-k> <-m> <-p>
<-s> <-v> <-w >
-a,–checkfamily 开启family check
-b,–printblocks 打印block index meta data
-e,–printkey 只打印keys
-f,–file 按文件路径scan; e.g. hdfs://a:9000/hbase/hbase:meta/12/34
-h,–printblockheaders 打印每个block的header文件
-k,–checkrow Enable row order check; looks for out-of-order keys
-m,–printmeta 打印hfile的meta数据
-p,–printkv 打印keyvalue
-r,–region Region to scan. Pass region name; e.g. ‘hbase:meta,1’
-s,–stats 打印统计个数
-v,–verbose 详细模式,打印分隔符
-w,–seekToRow 搜索这个rowkey,并打印这个rowkey的所有keyvalue

  

1)打印hfile meta
bin/hbase hfile -m -h -f /dev_hbase/data/default/ycsb_basic/18d4f5fde73f4dda5f376b47ef467333/family/4a2c8ee46edc47f8a2310e22bb384d5c
2)打印hfile kv
bin/hbase hfile -k -f /dev_hbase/data/default/ycsb_basic/18d4f5fde73f4dda5f376b47ef467333/family/4a2c8ee46edc47f8a2310e22bb384d5c
3)打印meta表信息
bin/hbase hfile -p -f /hbase/data/hbase/meta/1588230740/info/8fdd2e7beb0942d4bd84fb62a48dc028

  

其中
1)18d4f5fde73f4dda5f376b47ef467333就是encoded region;
2)family为Column Family;
3)4a2c8ee46edc47f8a2310e22bb384d5c为HFile。

  

参考
<1> https://en.wikipedia.org/wiki/Log-structured_merge-tree
<2> http://blog.cloudera.com/blog/2012/06/hbase-io-hfile-input-output/
<3> http://th30z.blogspot.com/2011/02/hbase-io-hfile.html?spref=tw
<4> http://blog.cloudera.com/blog/2012/06/hbase-write-path/
<5> https://sematext.com/blog/2012/07/16/hbase-memstore-what-you-should-know/
<6> https://issues.apache.org/jira/browse/HBASE-3857
<7> https://issues.apache.org/jira/browse/HBASE-1200
<8> https://www.quora.com/How-are-bloom-filters-used-in-HBase
<9> http://hbase.apache.org/book.html#keyvalue
<10> https://en.wikipedia.org/wiki/Java_ConcurrentMap
<11> http://cloudepr.blogspot.com/2009/09/hfile-block-indexed-file-format-to.html
<12> https://mapr.com/blog/in-depth-look-hbase-architecture/

  


  

文章来源:
https://oomspot.com/post/hbase-lsm

  

欢迎访问 开发者的技术家园 - OomSpot

相关文章