HBase以表的形式存储数据
rowKey就像关系数据库的主键,用来检索记录。
访问hbase表的记录有三种方式,分别是
1 通过单个row key访问
2 通过row key的range
3 全表扫描
时间戳:用来区分同一份数据的版本。并且按顺序排序,每次查询都将返回最新版本的数据。
Region
table由region组成,刚开始table就一个region,随着table中的数据增大,到大到一定程度时,hbase会将region切分为两个相等大小的region, region是分布式存储和负载均衡的最小单元,即不同的region可以分别在不同的Region Server上。相同的region不能拆分。
Store
region是分布式的最小单元,单不是存储的最小单元,每一个region有一个或多个store组成,至少是一个store,hbase会把一起访问的数据放在一个store里面,即为每个ColumnFamily建一个store,也说明一个store保存一个ColumnFamily。也说明如果有几个ColumnFamily,也就有几个Store。一个Store由一个memStore和0或者多个StoreFile组成。
MemStore
memStore 是放在内存里的。保存修改的数据即keyValues。当memStore的大小达到一个阀值时,memStore会被flush到文件,即生成一个快照。目前hbase 会有一个线程来负责memStore的flush操作。存在原因:存储在HDFS上数据要安row key排序, 而HDFS是顺序读写,不许修改,也就意味着没有为将来检索优化。为解决这个问题,在持久话到HDFS之前先排序,然后写入HDFS中。注意:每次memstore的flush,都回味每一个CF创建一个新的HFile。读书据:HBase首先检查请求的数据是否在Memstore,不在的话就到HFile中查找,最终返回merged的一个结果给用户。
迫于以下几个原因,HBase用户或者管理员需要关注Memstore并且要熟悉它是如何被使用的:
1.Memstore有许多配置可以调整以取得好的性能和避免一些问题。HBase不会根据用户自己的使用模式来调整这些配置,你需要自己来调整。
2.频繁的Memstore flush会严重影响HBase集群读性能,并有可能带来一些额外的负载。
3.Memstore flush的方式有可能影响你的HBase schema设计
配置memstore flush:
对Memstore Flush来说,主要有两组配置项:
1.决定Flush触发时机
2.决定Flush何时触发并且在Flush时候更新被阻断(block)
第一组是关于触发“普通”flush,这类flush发生时,并不影响并行的写请求。该类型flush的配置项有:
hbase.hregion.memstore.flush.size
<property>
<name>hbase.hregion.memstore.flush.size</name>
<value>134217728</value>
<description>
Memstore will be flushed to disk if size of the memstore
exceeds this number of bytes. Value is checked by a thread that runs
every hbase.server.thread.wakefrequency.
</description>
</property>
base.regionserver.global.memstore.lowerLimit
<property>
<name>hbase.regionserver.global.memstore.lowerLimit</name>
<value>0.35</value>
<description>Maximum size of all memstores in a region server before
flushes are forced. Defaults to 35% of heap.
This value equal to hbase.regionserver.global.memstore.upperLimit causes
the minimum possible flushing to occur when updates are blocked due to
memstore limiting.
</description>
</property>
每次的Memstore Flush都会为每个CF创建一个HFile。频繁的Flush就会创建大量的HFile。这样HBase在检索的时候,就不得不读取大量的HFile,读性能会受很大影响。
为预防打开过多HFile及避免读性能恶化,HBase有专门的HFile合并处理(HFile Compaction Process)。HBase会周期性的合并数个小HFile为一个大的HFile。明显的,有Memstore Flush产生的HFile越多,集群系统就要做更多的合并操作(额外负载)。更糟糕的是:Compaction处理是跟集群上的其他请求并行进行的。当HBase不能够跟上Compaction的时候(同样有阈值设置项),会在RS上出现“写阻塞”。像上面说到的,这是最最不希望的。
Compression & Memstore Flush
HBase建议压缩存储在HDFS上的数据(比如HFiles)。除了节省硬盘空间,同样也会显著地减少硬盘和网络IO。使用压缩,当Memstore flush并将数据写入HDFS时候,数据会被压缩。压缩不会减慢多少flush的处理过程,却会大大减少以上所述问题,例如因为Memstore变大(超过 upper limit)而引起的“写阻塞”等等。
压缩库建议使用Snappy。有关Snappy的介绍及安装,可分别参考:《Hadoop压缩-SNAPPY算法》和《Hadoop HBase 配置 安装 Snappy 终极教程
http://shitouer.cn/2013/01/hadoop-hbase-snappy-setup-final-tutorial/
StoreFile
memStore内存中的数据写到文件后就是StoreFile,StoreFile是一HFile的格式保存。
HFile
HFile是HBase的存储格式。是键值对的格式,键值对都是字节数组。HFile除了存储键值对,还需要存储键值对的索引信息,主要包含六个部分。
Data Block 段–保存表中的数据,这部分可以被压缩
Meta Block 段 (可选的)–保存用户自定义的kv对,可以被压缩。
File Info 段–Hfile的元信息,不被压缩,用户也可以在这一部分添加自己的元信息。
Data Block Index 段–Data Block的索引。每条索引的key是被索引的block的第一条记录的key。
Meta Block Index段 (可选的)–Meta Block的索引。
Trailer– 这一段是定长的。保存了每一段的偏移量,读取一个HFile时,会首先读取Trailer,Trailer保存了每个段的起始位置(段的Magic Number用来做安全check),然后,DataBlock Index会被读取到内存中,这样,当检索某个key时,不需要扫描整个HFile,而只需从内存中找到key所在的block,通过一次磁盘io将整个 block读取到内存中,再找到需要的key。DataBlock Index采用LRU机制淘汰。
HFile的Data Block,Meta Block通常采用压缩方式存储,压缩之后可以大大减少网络IO和磁盘IO,随之而来的开销当然是需要花费cpu进行压缩和解压缩
【转】HBase 存储结构 数据模型
最新推荐文章于 2024-08-29 20:19:53 发布