最近做项目接触到了HDFS、mapreduce以及Hbase,有了实战机会,今天打算将这些知识好好总结下,以备不时之需。首先从Hbase开始吧。

  Hbase是建立在HDFS上的分布式数据库,下图是Hbase表的模型:

Hbase学习笔记01

Hbase这个数据库其实和传统关系数据库还是有很多类似之处,而不是像mongodb,memcached以及redis完全脱离了表的概念,只不过hbase是以列为中心的数据库,而传统关系数据库则是以行为中心的数据库。不过hbase这个列并非我们传统意义的列,而是列族。列族是hbase最小的存储单位,换句话说hbase底层数据都是以列族来进行组织的。

学习hbase我最大的收获我个人觉得是对数据库的一种新的认识,数据库作用还是快速的检索出我们想要数据,也就是数据库的主要作用还是为了实时查询,如果一个存储数据的系统检索数据的速度很慢,那么这个系统应该称之为数据仓库,hbase是一种数据库,是一种用来弥补传统关系数据库在海量数据中快速检索数据的能力不足。不过受制于持久存储系统的检索数据的速度以及海量数据存储是分散到各个服务器上,因此解决海量数据实时检索的方式只有根据实际的业务场景重新组织数据存储的模型,并且加上合理的索引来解决的。那么hbase是如何解决这个问题的呢?

Hbase首先打破关系数据库里的避免数据冗余的机制,将经常需要一起查询的记录聚集在一起存储,例如商户的订单信息,这里我们用order代表订单信息,orderId为订单号,spId为商品订单号,spNm为商品名字,num为数量其他字段就略去,在hbase里我们可以把order定义为一个列族,orderId这些字段就是列的名字,在底层存储系统里我们将order这个列族下所有的列数据聚集在一起存储,那么当我们查询订单信息就可以直接找到这些聚集在一起的存储订单信息,那么就可以快速查询出订单信息。这一点相比关系数据库,关系数据库很难将一些经常查询出来的信息聚集在一起存储,这也就是hbase对于关系数据库的一大优势。这也就是为什么hbase是围绕列族的数据库,因为列族就是将一些经常会被一起查询出来的数据的逻辑抽象,所以底层物理存储机制都是围绕列族进行,这也就是hbase里的hfile了,hfile是hbase物理存储的最小单位,而hfile都是按照列族聚集在一起的。

前面我说道想要在海量数据下做到实时查询数据,一个要解决的问题就是如何将经常查询的数据聚集在一起存储,另一个就是建立索引了,下面我就要讲讲hbase的索引是如何设计。Hbase的索引是靠rowkey完成,也就是行主键,还是以商户订单为例,我们通过设计列族将这些数据聚集在一起存储,但是实际查询里我们经常会根据不同商户,或者不同商品查询订单信息,那么我们就得要有手段能快速从聚集的订单信息里查询出所需要查询的订单信息,那么这时候就靠rowkey的作用了,在hbase物理存储里最小存储单位是hfile,hfile之上则是region,每个region里聚集很多hfile(当然实际hbase底层存储比这个复杂,还有memstore,这是根据LSM存储原理设计,不过本文就以hfile代表整个列族存储),而region则是根据rowkey来进行构建和拆分的,换个说法就是region的名字或者代号就是rowkey,现在我们回到订单的例子,我们可以在rowkey的设计时候加入商户号,当用户查询时候可以根据商户号快速定位到region,然后再在region里进一步查找具体的列族信息,这样就完成了一个快速检索数据的目的。

最近学习hbase一直有个问题困惑我,那就是为何hbase的rowkey要按照字典顺序设计,而不是按顺序设计,这个疑惑的源头是很多hbase资料里说hbase是一个有利于顺序查询的数据库,那么rowkey设计为顺序格式不是更好吗?

对于这个问题我其实还没完全理解清楚,不过字典顺序也是一种顺序,在字典顺序之上还是可以很好设计出按照数字顺序的rowkey,不过hbase的rowkey是有别于关系数据库的主键,关系数据库下,一个行的主键只能查询出一条数据,而hbase一个rowkey能查询出许多数据,因此对于实时查询而言rowkey的数字顺序相比关系数据库的行意义小的多。这两个原因有点不痛不痒了,下面原因是个很重要的原因了,hbase里的region是hbase对客户端提供相关操作的单位,而rowkey是按照数字顺序排序,那么region则会根据顺序进行拆分,如果这个rowkey包含了时间因素,那么当大量客户端只做最近时间查询,就会导致时间最近那个region负载压力很大,为了达到负载均衡能力,我们最好将客户端的查询分布在各个不同的region上,那么我们最好让不同的region存储的数据应对查询是分布均衡的,而这个就是要靠rowkey设计实现的。不管怎么说hbase的使用里hbase的作用很关键。