标签:也有 ali max 没有 规则 对象 地方 元组 tag
HBase的核心存储结构是KeyValue类。这个类定义了HBase的数据模型,并贯穿了HBase的整个读写链路。同时,HBase自身的元数据管理也是使用了业务表相同的模式。所以,从底层了解KeyValue的格式和设计,会加深我们对HBase基础架构的理解,从而更好的使用和管理HBase。
HBase的数据模型是一个松散表结构,所谓松散,包含两个方面的含义
所以,我们说HBase是schema-free的,可以任意添加列。这些能力的基础就是KeyValue的设计。
KeyValue对使用者而言是一个六元组,即(rowkey, family, qualifier, timestamp, type, value)。在1.x版本之后,添加了tags支持,变成了7元组,即(rowkey, family, qualifier, timestamp, type, value, tags)。但其设计思想是没有变的,即key-value的方式进行存储,从业务逻辑上看,key就是rowkey;value除了值本身,还包含了value的一些描述信息,即family、qualifier、timestamp和type。
所以,KeyValue本身在可以独立的描述一行中的一列数据。因为带上了列名信息,所以,不需要事先定义好一行有哪些列(schema)。也因为如此,一行中可以存在任意的列,每行的列都可以完全不同。这个能力相比传统的RDBMS而言无疑是非常强大的,目前诸多的NoSQL系统几乎都提供这种schema-free的能力。这个能力比较常见的应用可以是:
天下没有免费的午餐,在获得上述强大能力的同时,要付出的代价也是巨大的,即数据冗余,包括:
如果表是直接从RDBMS迁移过来的,每行都有相同的列,那无疑列名的重复会额外占用很多空间,尤其是一行中列较多的时候。这也是为什么在表设计时,要选取尽可能短小的family名字和列名。另外,rowkey的重复也有同样的问题。我们有一些技术可以有效的解决这些问题。
下面,我们来看一下KeyValue的数据格式。
KeyValue本身就是一串二进制数据,即byte[],通过一些编码规则,将二进制数据映射为六元组或七元组。下面,我们先看看094版本的KeyValue格式。
0.94版本的KeyValue的byte数组由3部分组成。
其中,key包括了rowkey,family,qualifier,timestamp,type,这5个部分。
末尾是value字段,其长度由开始的ValueLength字段来定义。最大是Integer#MAX_VALUE,即4GB。但实际上,超过1MB的KV通常就会导致严重的性能问题了,超过64MB的KV一般来说Protobuffer很可能都无法支持其进行序列化和反序列化。所以,单纯从这个意义上看,HBase本身并不适合存储大对象(还有其他很多因素导致HBase不适合管理大块数据,这里不展开)。
由上面的KeyValue格式定义可见,这个格式还是很直观、符合直觉的,易理解,代码也容易懂,没有玩什么奇技淫巧。
与094版本相比,末尾多了一个tag区段,可以存储任意数量的tag。tag提供了一个扩展KeyValue能力的途径,比如行级/列级TTL,可以通过将TTL记录在tag中来实现。用户也可以存储一些自定义的信息。
KeyValue的格式是了解HBase底层存储结构的第一步,还有其他一些关键的设计,包括:
后续会慢慢对这些问题和设计进行整理和分析。
标签:也有 ali max 没有 规则 对象 地方 元组 tag
原文地址:https://www.cnblogs.com/yhxx511/p/9571053.html