列族在HBase的磁盘上彼此相邻放置?换句话说,HBase是面向列的吗?

问题描述

我试图了解HBase是否是面向列的数据库。 我了解HBase的一行的结构-它分为多个列族(它们是静态的并且不会改变),并且每个列族可以具有动态的列数:

row: row-key1,familyA:a1 familyA:a2... familyB:b1,familyB:b2,familyB:b3

现在,它表示列族一起存储在磁盘上。因此row:row-key1的familyA:a1 familyA:a2列将一起存储在磁盘上。

但是在两个不同行中的familyA:a1 familyA:a2值呢?他们也一个一个地存储吗?我会认为HBase是面向列的

我到处都可以看到HBase是宽列存储,它与面向列的存储相同吗?

解决方法

在回答问题之前,我想指出有关HBase用例的一件事,这将使理解HFile布局更加容易。 HBase(从读取工作负载的角度来看)针对在超长和宽表(数万亿行和数百万列)中的随机键值查找进行了优化。它也适用于基于行键前缀的扫描,但不适用于大型单列扫描。

也就是说,HBase并不是真正的列式数据库,尤其是当被视为宽列存储时。 HBase将同一行键和同一列族的所有列存储在一起。但是,不同的列族存储在不同的文件中,这赋予了HBase列式性质,即您可以独立控制每个列族的配置,并且可以扫描单个列族,而不必担心由于其他族的列而导致的读取成本。 这就是单个HFile的外观(注意,列在HBase中称为 qualifier Type 也可以是 Put 删除):

RowKey1:Family1:Qualifier1:Timestamp1:Type:Value
RowKey1:Family1:Qualifier1:Timestamp2:Type:Value
RowKey1:Family1:Qualifier2:Timestamp0:Type:Value
RowKey1:Family1:Qualifier3:Timestamp2:Type:Value
RowKey2:Family1:Qualifier1:Timestamp0:Type:Value
RowKey2:Family1:Qualifier2:Timestamp2:Type:Value

请注意, RowKey1 RowKey2 Qualifier1 不相邻。相反,同一行的所有列(即 RowKey1 键)都是相邻的。

如果您将每个列存储在其自己的列族中,则HBase将成为真正的列式存储,但是由于它提供的单行跨列ACID语义,它将无法为数百万列提供支持实施该策略的锁定策略。

修改

鉴于HFile的上述结构,HFile数据实际上是根据以下键以排序格式存储的(请注意,一个文件只能有一个家族,因此,将家族名称存储在数据本身中有些多余,但此问题还有其他用途)

RowKey:Family:Qualifier:Timestamp:Type

这种排序顺序与HFiles上的块级索引和Bloom过滤器结合在一起,使HBase能够快速找到任意随机的 RowKey RowKey,Family:Qualifier 元组,或 RowKey,Family:Qualifier,时间戳元组。