登录 |  注册 |  繁體中文


hbase 数据历史版本号规则

分类: hbase 颜色:橙色 默认  字号: 阅读(5840) | 评论(0)

HBase的表结构

HBase以表的形式存储数据。表有行和列组成。列划分为若干个列族/列簇(column family)。

 

Row Key

column-family1

column-family2

column-family3

column1

column2

column1

column2

column3

column1

key1

t1:abc

t2:gdxdf

 

t4:dfads

t3:hello

t2:world

     

key2

t3:abc

t1:gdxdf

 

t4:dfads

t3:hello

 

t2:dfdsfa

t3:dfdf

 

key3

 

t2:dfadfasd

t1:dfdasddsf

     

t2:dfxxdfasd

t1:taobao.com

 

如上图所看到的,key1,key2,key3是三条记录的唯 一的row key值,column-family1,column-family2,column-family3是三个列族,每一个列族下又包含几列。比方 column-family1这个列族下包含两列,名字是column1和column2,t1:abc,t2:gdxdf是由row key1和column-family1-column1唯一确定的一个单元cell。这个cell中有两个数据,abc和gdxdf。两个值的时间戳不 一样,各自是t1,t2, hbase会返回最新时间的值给请求者。

这些名词的详细含义例如以下:

(1) Row Key

与nosql数据库们一样,row key是用来检索记录的主键。訪问hbase table中的行,仅仅有三种方式:

(1.1) 通过单个row key訪问

(1.2) 通过row key的range

(1.3) 全表扫描

Row key行键 (Row key)能够是随意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),在hbase内部,row key保存为字节数组。

存储时,数据依照Row key的字典序(byte order)排序存储。设计key时,要充分排序存储这个特性,将常常一起读取的行存储放到一起。(位置相关性)

注意:

字典序对int排序的结果是1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97,98,99。要保持整形的自然序,行键必须用0作左填充。

行的一次读写是原子操作 (不论一次读写多少列)。这个设计决策可以使用户非常easy的理解程序在对同一个行进行并发更新操作时的行为。

(2) 列族 column family

hbase表中的每一个列,都归属与某个列族。列族是表的chema的一部分(而列不是),必须在使用表之前定义。列名都以列族作为前缀。比如courses:history , courses:math 都属于 courses 这个列族。

訪问控制、磁盘和内存的使用统计都是在列族层面进行的。实际应 用中,列族上的控制权限能帮助我们管理不同类型的应用:我们同意一些应用能够加入新的基本数 据、一些应用能够读取基本数据并创建继承的列族、一些应用则仅仅同意浏览数据(甚至可能由于隐私的原因不能浏览全部数据)。

(3) 单元 Cell

HBase中通过row 和columns确定的为一个存贮单元称为cell。由{row key, column( = + 

(4) 时间戳 timestamp

每一个cell都保存着同一份数据的多个版本号。版本号通过时 间戳来索引。时间戳的类型是 64位整型。时间戳能够由hbase(在数据写入时自己主动 )赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也能够由客户显式赋值。假设应用程序要避免数据版本号冲突,就必须自己生成具有唯一性的时间戳。每 一个cell中,不同版本号的数据依照时间倒序排序,即最新的数据排在最前面。

 

为了避免数据存在过多版本号造成的的管理 (包含存贮和索引)负担,hbase提供了两种数据版本号回收方式。一是保存数据的最后n个版本号,二是保存近期一段时间内的版本号(比方近期七天)。用户能够针对每一个列族进行设置。

 

测试实例如下

1 首先,先创建一张表,然后添加两条记录

 

  1. hbase(main):079:0> create 'scores','course'
  2. 0 row(s) in 0.9590 seconds
  3.  hbase(main):080:0> put 'scores','Tom','course:math',97
  4. 0 row(s) in 0.0100 seconds
  1. hbase(main):081:0> scan 'scores'
  2. ROW COLUMN+CELL 
  3. Tom column=course:math, timestamp=1394097631387, value=97 
  4. 1 row(s) in 0.0190 seconds
  5.  
  6. hbase(main):082:0> put 'scores','Tom','course:math',100
  7. 0 row(s) in 0.0080 seconds
  8.  
  9. hbase(main):026:0> scan 'scores'
  10. ROW COLUMN+CELL 
  11. Tom column=course:math, timestamp=1394097651029, value=100 
  12. 1 row(s) in 0.0110 seconds
  13.  
  14. hbase(main):027:0> scan 'scores',{TIMERANGE=>[1394097631387,1394097651029]}
  15. ROW COLUMN+CELL 
  16. Tom column=course:math, timestamp=1394097631387, value=97 
  17. 1 row(s) in 0.0210 seconds
  18.  
  19. hbase(main):028:0> scan 'scores',{TIMERANGE=>[1394097631387,1394097651030]}
  20. ROW COLUMN+CELL 
  21. Tom column=course:math, timestamp=1394097651029, value=100 
  22. 1 row(s) in 0.0100 seconds

从上面可以看到,HBASE默认scan出来的结果是最后一条时间戳的记录,那么如何把这两条都scan出来呢,


这时候可以加入VERSIONS这个约束条件:

  1. hbase(main):032:0> scan 'scores',{VERSIONS=>2}
  2. ROW COLUMN+CELL 
  3. Tom column=course:math, timestamp=1394097651029, value=100 
  4. Tom column=course:math, timestamp=1394097631387, value=97 
  5. 1 row(s) in 0.0130 seconds

 上面的命令,已经把这条记录都scan出来了。

再看下面的例子:

 

  1. scan scores,{TIMERANGE=>[1394097631386,1394097651029],VERSIONS=>2}
  2. ROW COLUMN+CELL 
  3.  Tom column=course:math, timestamp=1394097631387, value=97 
  4. 1 row(s) in 0.0130 seconds

 从上面的结果只scan出一条记录。可知,TIMERANGE表示的是”>=开始时间 and <结束时间“的。再看:

  1. hbase(main):003:0> scan scores,{TIMERANGE=>[1394097631386,1394097651030],VERSIONS=>2}
  2. ROW COLUMN+CELL 
  3.  Tom column=course:math, timestamp=1394097651029, value=100 
  4.  Tom column=course:math, timestamp=1394097631387, value=97 
  5. 1 row(s) in 0.0100 seconds

 OK,这样就明白了。


不过上面的加了VERSIONS=>2,就可以查到历史的数据了,但是必须再创建表的时候加上VERSIONS,否则无效,看下面的例子:


 

  1. hbase(main):082:0> create member,address,info
  2. 0 row(s) in 0.4140 seconds
  3.  
  4. => Hbase::Table - member
  1. hbase(main):093:0> put member,wanglei,info:age,24
  2. 0 row(s) in 0.0730 seconds
  1. hbase(main):093:1>get member,wanglei,{COLUMN=>info:age}
  2. COLUMN         CELL 
  3.  info:age timestamp=1394438746187, value=24
  4. hbase(main):093:7> put member,wanglei,info:age,100
  5. 0 row(s) in 0.0730 seconds
  6. hbase(main):093:18> get member,wanglei,{COLUMN=>info:age}
  7. COLUMN                             CELL
  8. info:age                          timestamp=1394439539837, value=100 

 

  1. hbase(main):022:0> get member,wanglei,{COLUMN=>info:age,TIMERANGE=>[1394438746187,1394439539838],VERSIONS=>2}
  2. COLUMN CELL 
  3.  info:age imestamp=1394439539837, value=100 
  4. 1 row(s) in 0.0050 seconds

 可以看到,虽然加了VERSIONS,但get的结果是1条;这就是因为建表时默认的VERSION是1.


修改VERSIONS:

  1. hbase(main):029:0> alter member,{NAME=>info,VERSIONS=>2}
  2. Updating all regions with the new schema...
  3. 0/1 regions updated.
  4. 1/1 regions updated.
  5. Done.
  6. 0 row(s) in 2.1680 seconds
  1. hbase(main):046:0> put member,wanglei,info:age,101
  2. 0 row(s) in 0.0590 seconds
  3.  
  4. hbase(main):047:0> get member,wanglei,{COLUMN=>info:age}
  5. COLUMN CELL 
  6.  info:age timestamp=1394441161595, value=101 
  7. 1 row(s) in 0.0120 seconds

   那么现在就可以把倆条记录get出来了,如下:

  1. hbase(main):049:0> get member,wanglei,{COLUMN=>info:age,TIMERANGE=>[1394439539837,1394441161596],VERSIONS=>2}
  2. COLUMN CELL 
  3.  info:age timestamp=1394441161595, value=101 
  4.  info:age timestamp=1394439539837, value=100 
  5. 2 row(s) in 0.0080 seconds    




姓 名: *
邮 箱:
内 容: *
验证码: 点击刷新 *   

回到顶部