HBase基础教程--1.2.X版本--基础知识篇(二)

来源:互联网 发布:mac 好用的卸载软件 编辑:程序博客网 时间:2024/05/17 13:07

基础知识篇(二)


HBase数据模型

在HBase里,表有rows(行)和columns(列),数据就存储在表中。row和column的术语与关系型数据库中的术语正好是重叠的,但这并不是一个有用的类比。反而,把HBase的表想象成多维度映射可能更能帮助我们理解。


1. 基本概念

  • Table
    一个HBase table是由许多个行组成的
  • Row
    HBase中的行由一个行键(row key)和一个或者多个列组成,这些列上带有相关联的值。行的存储是以行键(row key)来按照字母顺序排列的。因此,对行键的设计就非常重要。行键设计的目标是使得数据存储是以相关联的行为分区存储的,相关的行是存储在一起的,彼此邻近。一个常见的行键模式是使用网站的域名,并且使用反序排列域名的方式来使用域名作为行键。例如:org.apache.www,org.apache.mail,org.apache.jira等。正如例子中所见,用这种方式,我们可以保证所有的apache域名作为行键的行在表中都是彼此相邻的,而不会因为子域名的首字母不同,而被分开。
  • Column
    HBase中的列是由一个列族前缀和一个修饰符(qualifier)组成,并且两者通过冒号:隔开。
  • Column Family 列族
    HBase中列族是一些列的集合,包括列的值。每一个列族都有自己的一套存储属性,例如列中的值是否应该缓存在内存中,数据如何压缩以及行键如何编码等等。尽管给定的某一行可能不会把所有的数据都存储在一个给定的列族中,但是在某一张表里的某一行都会含有相同的列族(细细理解下)。

  • Column Qualifier 列修饰符
    一个列修饰符会被放在一个列族前缀后面,他提供了给定数据片段的索引支持。给定一个列族content ,一个列修饰符可以是content:html 或者content:pdf .与列族是定义在表创建时就固定了不同,列修饰符更加灵活可变,而且在行之间会很不一样。

  • Cell 单元
    一个单元是由行、列族已经列修饰符组成的,并且包含一个值,已经一个时间戳。这个时间戳用来表示该值的版本。

  • Timestamp 时间戳
    时间戳是写在每个值旁边的,并且是一个给定版本的值的标识符。默认情况下,时间戳展示了数据被写入到该分区服务器上的时间,但是在把数据写入到cell中时,可以指定一个不同的时间戳给值。

2. 概念视图

为了帮助我们更好的了解HBase的schema设计原理,我们可以去看两篇论文:Understanding HBase and BigTable和Introduction to Basic Schema Design

这里我们通过一个例子来了解本部分内容,这个例子是从BigTable论文中修改而来的。
有一张表webtable ,表中有两个行(com.cnn.www and com.example.www)以及三个列族(contentsanchor and people )。对于第一个行(com.cnn.www ),anchor 列族有两列(anchor:cssnsi.com ,anchor:my.look.ca ),contents 列族有一列(contents:html )。com.cnn.www 行有五个版本,com.example.www 行有一个版本。contents:html 列修饰符包含了给定网站的全部HTML内容。anchor 列族中的每一个列修饰符都包含行所表示的网站的外链,连同在连接的anchor 中使用的文本。people 列族展示了与改行网站相关的people信息。

Column Names:
出于习俗,一个列的名字是由列族的前缀加上修饰符来组成的。例如,contents:html 就是有列族content 和修饰符qualifier 组成的。冒号“:”将列族前缀content 和修饰符”html“分隔开。

以上描述的表webtable制表如下表示:

Row Key TimeStamp ColumnFamily contents ColumnFamily anchor ColumnFamily people “com.cnn.www” t9 anchor:cnnsi.com=”CNN” “com.cnn.www” t8 anchor:cnnsi.com=”CNN.com” “com.cnn.www” t6 contents:html=”……” “com.cnn.www” t5 contents:html=”……” “com.cnn.www” t3 contents:html=”……” “com.example.www” t5 contents:html=”……” people:author=”JohnDoe”

Cell中空的部分在表中是不占用空间的,所以HBase是稀疏的。
我们还可以用多维映射的表示方式来表示HBase里的数据。

{  "com.cnn.www": {    contents: {      t6: contents:html: "<html>..."      t5: contents:html: "<html>..."      t3: contents:html: "<html>..."    }    anchor: {      t9: anchor:cnnsi.com = "CNN"      t8: anchor:my.look.ca = "CNN.com"    }    people: {}  }  "com.example.www": {    contents: {      t5: contents:html: "<html>..."    }    anchor: {}    people: {      t5: people:author: "John Doe"    }  }}

3.物理视图

尽管概念层级的图标看起来是稀疏的,但是数据实际上都是按照列族存储在物理层的。新的列修饰符可以随时被添加在一个一个已经存在的列族中。
下面就看看物理层的存储实际是怎么样的,见下面两张表:

Row Key Time Stamp Column Family anchor “com.cnn.www” t9 anchor:cnnsi.com=”CNN” “com.cnn.www” t8 anchor:my.look.ca=”CNN.com” Row Key Time Stamp Column Family contents “com.cnn.www” t6 contents:html = “…​” “com.cnn.www” t5 contents:html = “…​” “com.cnn.www” t3 contents:html = “…​”

可以看到,在概念层中的空Cell,在物理层中是没有被存储的。因此当我们对列content:html 发出一个t8 版本的值请求时,我们什么结果也得不到。同样的,当我们对列anchor:my.look.ca 发出一个版本为t9 的值请求时,我们也是一样的,什么值也不会取到。
然而,如果我们发出请求的时候,没有给出版本信息,那么就会返回所请求列的最新版本的Cell中存储的值。因此,当我们对键值为com.cnn.www 的所有列的值发出请求时,如果没有指明版本信息timestamp ,我们会收回的结果是:

  • content:htmlt6 版本的值
  • anchor:cnnsi.comt9 版本的值
  • anchor:my.look.cat8 版本的值

4.命名空间

命名空间(namespace是一个表的逻辑分组,就类似于关系型数据库中的数据库(database。这种抽象为即将到来的多租户相关的特性奠定了基础(具体哪些特性暂时不列出)。

1. Namespace management
命名空间可以被创建、删除或者修改。命名空间的成员资格是在被创建的时候通过指明一个全修饰符表名,格式如下:

<table namespace>:<table qualifier>
操作实例#创建一个命名空间create_namesapce 'my_ns'#在命名空间'my_ns'中创建表'my_table'create 'my_ns:mytable' , 'fam'#删除命名空间drop_namespace 'my_ns'#修改命名空间alter_namespace 'my_ns' , {METHOD => 'set','PROPERTY_NAME' => 'PROPERTY_VALUE'}

2.预定义好的命名空间
有两种预定义好的命名空间:

  • hbase - 系统命名空间,用来容纳hbase自身的表
  • 默认 -对于没有直接指出所在的命名空间的表就会被自动的放入到这个默认的命名空间里

5.数据模型操作方式

有四种主要的数据操作方式:GET 、PUT、Scan 、Delete

  • 1.GET
    GET方法返回指定行的属性。
  • 2.PUT
    PUT方法一方面可以在一个表中添加一个新行,另一方面可以更新已经存在的行。
  • 3.Scans
    Scans方法允许对指定的属性进行多行的迭代。
  • 4 Delete
    Delete方法从一张表中删除一行。

HBase并没有修改数据方法,所以删除操作是通过创建一个名为墓碑(tombstones )的新标记来操作实现的。也就是说,对要删除的内容标记上墓碑,标记了墓碑的内容不能够被GET和Scan命令所返回。直到进行一次大合并(major compaction),这些墓碑记录才会被删除掉,记录占用的空间才会释放。


6.版本

  • 一个{row,column,version}元组准确的表示了HBase中的一个Cell。在row和column都相同,但是在不同的版本中存储的Cell地址信息都是不同的,这种情况下,table中的cells是可以有无限个的。
  • rowscolumns都是用按照字节存储的,但是version指明需要按照长整型来表示。通常,这个长整型包含了一个时间实例,比如通过java.util.Date.getTime() or System.currentTimeMillis() 返回得到的值,该值的计算方式是:以毫秒为单位,计算出当前时间距离1970年1月1日凌晨的时间差。
  • HBase的version维度是按照降序排列的,因此当我们对表中存储的文件进行读取时,就可以取到最新的version中存储的值信息。

在HBase中,cell版本的语义很混乱。尤其表现为以下两点:
1. 如果多个写入cell的操作都有相同的版本,那么就会保存最后一个写入。
2. 可以不按照增序来写入cell信息。

在HBase中,重写某个时间戳下的值的限制已经不在存在,也就是说,可以对某个时间戳下的值进行修改

指定存储的版本的数量

一个给定的列所能存储的最大版本数量是列设计的一部分,并且是在创建表的时候就指明了,也可以通过alter 命令或者通过HColumnDescriptor.DEFAULT_VERSIONS 属性来设置完成。
在0.96版本之前的HBase,默认的版本数量是3,但是在0.96已经之后的版本中,默认的版本数量已经改变成了1.

#为一个列族修改它的最大版本数量hbase> alter 't1' , NAME='f1', VERSIONS => 5#为一个列族修改它的最小版本数量hbase> alter 't1' , NAME='f1', MIN_VERSIONS => 5

从0.98.2版本开始,我们可以通过全局默认设置来指明最大的列版本数量,该设置是对所有的新添加的列都是有效的。

原创粉丝点击