在HBase中,数据存储在具有行和列的表中,这是与关系数据库(RDBMS)类似的模型,但与之不同的是其具备结构松散、多维有序映射的特点,它的索引排序键由行+列+时间戳组成,HBase表可以被看做一个“稀疏的、分布式的、持久的、多维度有序Map”。
相关术语
命名空间(Namespace):对表的逻辑分组,类似于关系型数据库中的Database概念。Namespace可以帮助用户在多租户场景下做到更好的资源和数据隔离。
表(Table):HBase会将数据组织进一张张的表里面,一个HBase 表由多行组成。
行(Row):HBase中的一行包含一个行键和一个或多个与其相关的值的列。在存储行时,行按字母顺序排序。出于这个原因,行键的设计非常重要。目标是以相关行相互靠近的方式存储数据。常用的行键模式是网站域。如果你的行键是域名,则你可能应该将它们存储在相反的位置。这样表中的所有Apache域都彼此靠近,而不是根据子域的第一个字母分布。
列(Column):HBase中的列由一个列族和一个列限定符组成,它们由冒号(:)字符分隔。
列族(Column Family):由于性能原因,列族在物理上共同存在一组列和它们的值。在HBase中每个列族都有一组存储属性,例如其值是否应缓存在内存中,数据如何压缩或其行编码是如何编码的等等。表中的每一行都有相同的列族,但给定的行可能不会在给定的列族中存储任何内容。列族一旦确定后,就不能轻易修改,因为它会影响到HBase真实的物理存储结构,但是列族中的列标识(Column Qualifier)以及其对应的值可以动态增删。
列限定符(Column Qualifier):列限定符被添加到列族中,以提供给定数据段的索引。鉴于列族的content,列限定符可能是content:html,而另一个可能是content:pdf。虽然列族在创建表时是固定的,但列限定符是可变的,并且在行之间可能差别很大。
单元格(Cell):单元格是行、列族和列限定符的组合,并且包含值和时间戳,它表示值的版本。
时间戳(Timestamp):时间戳与每个值一起编写,并且是给定版本的值的标识符。默认情况下,时间戳表示写入数据时RegionServer上的时间,但可以在将数据放入单元格时指定不同的时间戳值。
概念视图
本节示例是根据BigTable论文进行修改后的示例,在本节的示例中有一个名为表 webtable,其中包含两行(com.test.www 和 com.example.www)以及名为 contents、anchor 和 people 的三个列族。在本例中,对于第一行(com.test.www), anchor 包含两列(anchor:example.com,anchor:test.ca),并且 contents 包含一列(contents:html)。本示例包含具有行键 com.test.www 的行的5个版本,以及具有行键 com.example.www 的行的一个版本。contents:html 列限定符包含给定网站的整个HTML。anchor列族的列限定符每个包含与该行所表示的站点链接的外部站点以及它在其链接的锚点中使用的文本。people 列族代表与该网站相关的人员。
列名称:按照约定,列名由其列族前缀和限定符组成。例如,列内容:html 由列族contents和html限定符组成。冒号(:)从列族限定符分隔列族。
webtable表如下所示:
Row Key | Time Stamp | ColumnFamily contents | ColumnFamily anchor | ColumnFamily people |
“com.test.www” | T9 | (-) | anchor:example1.com =“CNNtest” | (-) |
“com.test.www” | T8 | (-) | anchor:test.ca =“CNNtest.com” | (-) |
“com.test.www” | T6 | contents:html = “…” | (-) | (-) |
“com.test.www” | T5 | contents:html = “…” | (-) | (-) |
“com.test.www” | T3 | contents:html =“ ……” | (-) | (-) |
“com.example.www” | T5 | contents:html =“ ……” | (-) | people:author =“John Doe” |
此表中显示为-的单元格在HBase中不占用空间或实际上存在,这正是使HBase“稀疏”的原因。表格视图并不是查看HBase数据的唯一可能的方法,甚至是最准确的,以下代表与多维Map相同的信息。这只是用于说明目的模拟,可能并不严格准确。
{
"com.test.www": {
contents: {
t6: contents:html: "<html>..."
t5: contents:html: "<html>..."
t3: contents:html: "<html>..."
}
anchor: {
t9: anchor:example1.com = "CNNtest"
t8: anchor:test.ca = "CNNtest.com"
}
people: {}
}
"com.example.www": {
contents: {
t5: contents:html: "<html>..."
}
anchor: {}
people: {
t5: people:author: "John Doe"
}
}
}
物理视图
尽管在HBase概念视图中,表格被视为一组稀疏的行的集合,但它们是按列族进行物理存储的。可以随时将新的列限定符(column_family:column_qualifier)添加到现有的列族。
ColumnFamily anchor:
Row Key | Time Stamp | ColumnFamily anchor |
“com.test.www” | T9 | anchor:example1.com = “CNNtest” |
“com.test.www” | T8 | anchor:test.ca = “CNNtest.com” |
ColumnFamily contents:
Row Key | Time Stamp | ColumnFamily contents |
“com.test.www” | T6 | contents:html = “…” |
“com.test.www” | T5 | contents:html = “…” |
“com.test.www” | T3 | contents:html = “…” |
HBase概念视图中显示的空单元根本不存储。因此,对时间戳为t8的contents:html列值的请求将不返回任何值。同样,在时间戳为t9中一个anchor:test.ca值的请求也不会返回任何值。但是,如果未提供时间戳,则会返回特定列的最新值。给定多个版本,最近的也是第一个找到的,因为时间戳按降序存储。因此,如果没有指定时间戳,则对行com.test.www中所有列的值的请求将是:时间戳t6中的contents:html,时间戳t9中anchor:example1.com的值,时间戳t8中anchor:test.ca的值。
数据排序
所有数据模型操作HBase以排序顺序返回数据。首先按行,然后按列族(ColumnFamily),然后是列限定符,最后是时间戳(反向排序,因此首先返回最新的记录)。
列元数据
ColumnFamily的内部KeyValue实例之外不存储列元数据。因此,尽管HBase不仅可以支持每行大量的列数,而且还能对行之间的一组异构列进行维护,但您有责任跟踪列名。
获得ColumnFamily存在的一组完整列的唯一方法是处理所有行。
ACID
ACID,指数据库事务正确执行的四个基本要素的缩写,即:原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability)。
HBase支持单行操作下的ACID,即对同一行的Put操作保证完全的ACID。