列族是否在HBase中的磁盘上一个接一个地放置?换句话说,HBase是面向列的吗?

列族是否在HBase中的磁盘上一个接一个地放置?换句话说,HBase是面向列的吗?,hbase,bigtable,column-oriented,wide-column-store,Hbase,Bigtable,Column Oriented,Wide Column Store,我试图理解HBase是否是一个面向列的数据库。 我了解一行HBase的结构-它分为列族(静态且不变),每个列族可以有动态的列数: row: row-key1, familyA:a1 familyA:a2... familyB:b1,familyB:b2,familyB:b3 现在它表明一个列族一起存储在磁盘上。因此,行:row-key1的familyA:a1 familyA:a2列将一起存储在磁盘上 但是两行不同的familyA:a1 familyA:a2值呢?它们是否也一个接一个地存储?这会

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

row: row-key1, familyA:a1 familyA:a2... familyB:b1,familyB:b2,familyB:b3
现在它表明一个列族一起存储在磁盘上。因此,行:row-key1的familyA:a1 familyA:a2列将一起存储在磁盘上

但是两行不同的familyA:a1 familyA:a2值呢?它们是否也一个接一个地存储?这会告诉我HBase是面向列的


无论我在哪里看到HBase都是宽列存储,它与面向列的存储相同吗?

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

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

请注意,限定符1与RowKey1和RowKey2不相邻。相反,同一行(即RowKey1键)的所有列都是相邻的

如果您将每一列存储在它自己的列系列中,HBase将成为一个真正的列存储,但是由于它提供了跨列的单行酸性符号,它将无法为数百万列提供支持,因为它采用了锁定策略来实现这一点

编辑

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


这种排序顺序,再加上HFiles上的块级索引和bloom过滤器,使得HBase能够快速定位任意随机行键、行键、族:限定符元组或行键、族:限定符、时间戳元组。

Ashu Pachauri-但是如果列族像您的示例那样一个接一个地存储,它不是针对顺序读取而不是随机读取进行了优化吗?@nadavgam我想你的意思是“列一个接一个地存储”,因为族存储在不同的文件中。由于同一行键的列存储在一起,因此获取单个行键的所有列非常快。这就是为什么我说“随机键值查找”。由于块级索引和bloom筛选器,以及文件中的rowkey有序数据存储,在hbase中查找特定的rowkey的速度非常快。但是,扫描一个列的速度非常慢。我编辑了我的答案,以提供更多关于如何在HBase中优化随机KV查找的详细信息。我要补充的是,HBase不能很好地处理多个CFs,除非访问模式非常具体。《HBase指南》中对此有免责声明。
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
RowKey:Family:Qualifier:Timestamp:Type