HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。
与FUJITSU Cliq等商用大数据产品不同,HBase是Google Bigtable的开源实现,类似Google Bigtable利用GFS作为其文件存储系统,HBase利用Hadoop HDFS作为其文件存储系统;Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据;Google Bigtable利用 Chubby作为协同服务,HBase利用Zookeeper作为对应。
- HBase适用于简单数据写入(如“消息类”应用)和海量、结构简单数据的查询(如“详单类”应用),适合稀疏表;
- 作为大数据MapReduce的后台数据源,以支撑离线分析型应用;
- 基于HDFS分布式文件系统, 可扩展性+;
- Facebook的消息类应用,包括Messages、Chats、Emails和SMS系统,用的都是HBase;
使用场景:
对象存储:不少的头条类、新闻类的新闻、网页、图片存储在 HBase 之中,一些病毒公司的病毒库也是存储在 HBase 之中。
时序数据:HBase 之上有 OpenTSDB 模块,可以满足时序类场景的需求。
时空数据:不少车联网企业,数据都是存在 HBase 之中。
消息/订单:Facebook 用 HBase 存储在线消息,每天数据量近百亿,每月数据量250 ~ 300T, HBase 读写比基本在1:1,吞吐量150w qps。
Feeds 流:典型的应用如微信朋友圈。
概念: 表, 行, 列族, 列, 版本
- 行(Row): HBase 中的一行包含一个行键和一个或多个与其相关的值的列。在存储行时,行按字母顺序排序。
出于这个原因,行键的设计非常重要。目标是以相关行相互靠近的方式存储数据。常用的行键模式是网站域。如果你的行键是域名,则你可能应该将它们存储在相反的位置(org.apache.www,org.apache.mail,org.apache.jira)。这样,表中的所有 Apache 域都彼此靠近,而不是根据子域的第一个字母分布。 - 列(Column): HBase 中的列由一个列族和一个列限定符组成,它们由
:
字符分隔。- 列族(Column Family): 出于性能原因,列族在物理上共同存在一组列和它们的值。在 HBase 中每个列族都有一组存储属性,例如其值是否应缓存在内存中,数据如何压缩或其行编码是如何编码的等等。表中的每一行都有相同的列族,但给定的行可能不会在给定的列族中存储任何内容。列族一旦确定后,就不能轻易修改,因为它会影响到 HBase 真实的物理存储结构,但是列族中的列标识(Column Qualifier)以及其对应的值可以动态增删。
- 列限定符(Column Qualifier): 列限定符被添加到列族中,以提供给定数据段的索引。鉴于列族的content,列限定符可能是content:html,而另一个可能是content:pdf。虽然列族在创建表时是固定的,但列限定符是可变的,并且在行之间可能差别很大。
- 单元格(Cell) 单元格是行、列族和列限定符的组合,并且包含值和时间戳,它表示值的版本。
- 时间戳(Timestamp) 时间戳与每个值一起编写,并且是给定版本的值的标识符。默认情况下,时间戳表示写入数据时 RegionServer 上的时间,但可以在将数据放入单元格时指定不同的时间戳值。
概念视图
上面的数据有相同的Row key = “com.cnn.www”, 每行表示一个数据版本, 共有5个版本(Time Stamp表示),
有两个列族 contents 和 anchor, 两个列族下分别有contents:html, anchor:cnnsi.com, anchor:my.look.ca三个列,
用json格式表示概念视图:
"com.cnn.www": [ // 行键 |
物理视图
物理存储是按照列族(family)分布的, 相同的列族在连续的物理空间存储.
如下图, 一张表里有不同的列族 CF1, CF2, 每个列族下面有自己的qualifier, 可以看到一张表的数据被按照列族分布在不同的物理位置。
TTL
HBase的生存时间(TTL)是针对列族设置的, 一旦达到到期时间,HBase 将自动删除行。修改一个列族的TTL如下:disable 'table1' #先禁用表
alter 'table1', {NAME=>'col_family1', TTL => '100'} #指明修改哪个列族, 100的单位是秒
enable 'table1'
从上面可以看到, TTL虽然是针对列族的参数, 但是给某个列族修改/增加TTL需要暂时disable表, 所以在生产环境里最好还是在建表的时候就给每个列族指定好TTL