HBase (2)---数据存储结构

在本文中的HBase术语:
基于列:column-oriented
行:row
列组:column families
列:column
单元:cell

 

理解HBase(一个开源的Google的BigTable实际应用)最大的困难是HBase的数据结构概念究竟是什么?首先HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库.另一个不同的是HBase基于列的而不是基于行的模式.

Google's BigTable论文 清楚地解释了什么是BigTable:
Bigtable是一个疏松的分布式的持久的多维排序的map,这个map被行键,列键,和时间戳索引.每一个值都是连续的byte数组.(ABigtable is a sparse, distributed, persistent multidimensional sortedmap. The map is indexed by a row key, column key, and a timestamp; eachvalue in the map is an uninterpreted array of bytes.)

Hadoop wiki的HBase架构 页面提到:
HBase使用和Bigtable非常相同的数据模型.用户存储数据行在一个表里.一个数据行拥有一个可选择的键和任意数量的列.表是疏松的存储的,因此用户可以给行定义各种不同的列.(HBase uses a data model very similar to that ofBigtable. Users store data rows in labelled tables. A data row has asortable key and an arbitrary number of columns. The table is storedsparsely, so that rows in the same table can have crazily-varyingcolumns, if the user likes.)

 

实质上,HBase和BigTable是个map.相同于数组(PHP),词典(Pyhton),Hash(Ruby)或者Object(Javascript)中的表现形式.所以每一行是一个map,这个map中还可以有多个map(基于列组).获取一个数据就像你从map中获取数据一样.给定一个行名(即从这个map中获取数据),然后给定一个key(列组名+限定词)来取得数据.

HBase 和BigTable都是在分布式文件系统上构建的,所以基础的文件存储能够散布在分布式文件系统的机器上.
HBase使用Hadoop's Distributed File System(HDFS) 或 Amazon's Simple StorageService(S3),Kosmos Distributed File System(KFS), 与此一样BigTable使用GoogleFile System(GFS).数据被复制到多个节点就像数据被存储在一个RAID系统上.

不像大多数的map应用,在HBase和BigTable中,key/value是非常严格地按字母次序排列的.那就是意味着键值为"aaaaa"的行下一个行的键值为"aaaab",但是和键值为"zzzzz"的行离的很远.因为这些系统都是非常庞大和分布式的, 这些特性是非常重要的. 空间接近的列保证当你确定要浏览表时,你感兴趣的行将会靠近这行.当你选择行的键值时,这是非常重要的事情.例子:考虑你表中的列是域名.最好是倒过来的(因此"com.jimbojw.www"比"www.jimbojw.com"更好),因为你的子域名将会靠近你的主域名.注意在HBase中排序仅仅是kay排序,value是不排序的.

在下面的JSON数据中,我们看到整个数据结构是一个map,并且map中每一个key对应一个包含"A"和"B"的map.假设整个下面数据是一个table,那么它有"1"."aaaaa","aaaab","xyz","zzzzz"这几个行,每一个行有一个"A"和"B"的map.在HBase的术语中, 称"A"和"B"为列组.

{
  "1" : {
    "A" : "x",
    "B" : "z"
  },
  "aaaaa" : {
    "A" : "y",
    "B" : "w"
  },
  "aaaab" : {
    "A" : "world",
    "B" : "ocean"
  },
  "xyz" : {
    "A" : "hello",
    "B" : "there"
  },
  "zzzzz" : {
    "A" : "woot",
    "B" : "1337"
  }
}

在HBase中一个列组通过限定词或叫做标签使每一个列组能够包含许多的列.

{
  "aaaaa" : {
    "A" : {
      "foo" : "y",
      "bar" : "d"
    },
    "B" : {
      "" : "w"
    }
  },
  "aaaab" : {
    "A" : {
      "foo" : "world",
      "bar" : "domination"
    },
    "B" : {
      "" : "ocean"
    }
  },
  "zzzzz" : {
    "A" : {
      "catch_phrase" : "woot",
    }
    "B" : {
      "" : "1337"
    }
  }
}

在上面的例子中,在"aaaaa"的行中,列组"A"包含两个列:"foo"和"bar",列组"B"仅仅有一个限定词为空字符窜""的列.当我们向HBase获取数据时,你必须提供完整的列名字"<列组>:<限定词>".因此上面的例子中行"aaaaa"和"aaaab"都包含三个列:"A:foo","A:bar"和"B:".尽管在行中列组是固定的,但是同一个列中限定词可以是不同的,就像行"zzzzz"中列组"A"中只有一个列"catch_phrase".最后的维度是时间戳(timestamp).所有的在HBase中存储的数据都有一个用时间戳表示的版本或者你自己通过指定时间戳来插入或获取数据.

{
  "aaaaa" : {
    "A" : {
       "foo" : {
        15 : "y",
        4 : "m"
      },
      "bar" : {
        15 : "d",
      }
    },
    "B" : {
      "" : {
        6 : "w"
        3 : "o"
        1 : "w"
      }
    }
  }
}

每一个列可以指定多少版本的数据被保存在每一个单元.在上面的例子中行"aaaaa"的列"A:foo"包含两个倒序时间戳排列的数据15和4,列"B"包含由三个倒序时间戳排列的数据.一般的应用程序只是简单(不通过时间戳)的请求一个单元的数据.在这种条件下,HBase只是简单地返回最新的版本,即时间戳最大的版本.要获取"A:foo"返回"y",要获取"B"返回"w".如果应用程序在一个行中请求时带上时间戳,HBase将会返回小于或等于请求时间戳的数据.接着上面的例子如果程序请求"A:foo"带上时间戳10,返回"m",加上时间戳3,返回null.

每一个行可以多个列族,每一个列族可以包含无数个列,每一个列都可以有一个不同于其他列的时间戳.在通用数据库中当表创建时我们就已经定义了列,如果修改表结构的话会非常困难(比如:添加一列).在HBase中我们可以很轻松地添加一个列族或列.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值