读书笔记-HBase in Action-第一部分 HBase fundamentals


新项目准备上HBase。HBase目前由组里某牛负责。本着学会使用HBase的目标,先阅读下HBase in Action,一共十章组织成三部分,需要学习的内容包括HBase基本实现原理,使用方法,Schema设计原则和实战等。借用Michael Stack(HBase Chair)的话,“At a highlevel, HBase is like theatomic bomb. Its basic operation can be explained onthe back of a napkin over adrink (or two). Its deployment is another matter。(HBase像原子弹一样,它的基本操作可以写在一张餐巾纸的背面,但是它的部署就是另一回事了。)

首先,HBase可以理解为Database on Hadoop,即山寨版的BigTable on GFS,具备以下几个主要特点:Key-Value分布式存储、面向列、实时随机读写。

基本概念&基本操作

以下是HBase的一些基本术语:

基本操作包括5种:

Put(存储或者修改单行记录)/Get(读取单行记录,可以指定列族、列等)/Delete(删除单行记录,由于底层存储不可变,实现为添加墓碑记录)/Scan(返回行集合,可以指定扫描起止row key,过滤条件等)/Increment(增加某个单元值,原子操作)

数据模型

逻辑上,可以把HBase数据理解成有序Map。其中记录行按照row key升序存储,version降序存储。

Map<RowKey, Map<ColumnFamily,Map<Column,Map<Version, Data>>>>

物理上(Region及HDFS细节下一节介绍),数据存储在HFile中,HFile只包含某一个列族数据,而每一个列族可能使用多个HFile。HFile使用列式存储。下图是HFile存储示意图,TheRealMT为row key,info为列族,email/name/password为列名,后两列为时间戳版本号cell值(注:由于使用列式存储,HBase不用存储null值)。

        

数据读写过程

HBase数据同时写入到WAL(wrete-ahead log)和MemStore。每个列族都有一个MemStore缓存区,用于提高写入性能,数据定期同步到HFile;WAL用于保障可靠性,出问题时,如果MemStore数据没有同步到HFile中,可以从WAL回放恢复(WAL日志顺序写入,写入性能尚可)。

数据读取使用BlockCache/MemStore提高性能。


HBase与HDFS

理论上,HBase能运行在各种分布式文件系统之上,实际上,HBase和HDFS紧耦合在一起。HDFS提供可扩展性和容错性。HBase表可以存储数十亿行数据,每行可以包含成百上千个字段。Table随着记录数不断增加变大,会逐渐分裂成多个Region。Region由RegionServer进行管理。借用一张淘宝技术博客的图。在实际生产环境中,RegionServer可以部署在HDFS DataNode节点上,节省网络IO。


从高层次来讲,通过HDFS引入统一命名空间,也保障了HBase的可用性,当某台RegionServer挂掉,其他ReginServer可以读取HDFS上数据。

Region分裂带来一个新问题:怎么查找特定Region。HBase通过两张特殊表-ROOT-和.META来实现。其中-ROOT-表记录了.META表Region信息,-ROOT-表只有一个Region,其位置记录在ZooKeeper上。.META表记录用户表Region信息,可以有多个Region。可以把查找Region看做是在高度为3的B+Tree树中查找叶子节点的过程。


HBase与MapReduce

HBase主要用于低延迟访问场景,如果应用强调吞吐量,不关心延迟时间,可以考虑使用MapReduce进行数据处理。TableMapper和TableReduer封装了访问HBase数据的细节。Map和Reduce方法签名如下:

protected void map(ImmutableBytesWritable rowkey,Resultresult,Context context);
protected void reduce(ImmutableBytesWritablerowkey,Iterable<Put> values,Context context);

还需要使用TableMapReduceUtil帮助类初始化Job,指定HBase表名等参数。

TableMapReduceUtil.initTableMapperJob(
  "twits",
  scan,
  Map.class,
  ImmutableBytesWritable.class,
  Result.class,
  job);

另外,由于HBase天然是Key-Value存储,可以把它看做是一个分布式Map,利用HBase随机访问高性能特性,使用Get和小范围的Scan操作帮助实现Map-Join,如下图所示:

 

相关内容

    暂无相关文章