一、HBase是什么?
HBase,全称Hadoop Database,最开始是受 Google 的 BigTable 启发而开发是一个高可靠、高性能、面向列、可伸缩、实时读写的分布式数据库。其主要特点有:
利用Hadoop HDFS作为其文件存储系统;
利用ZooKeeper作为其分布式协同服务;
面向列的K-V数据库,支持上亿行、百万列,主要用来存储结构化半结构化的松散数据。
二、HBase的数据模型
掌握HBase数据模型中的概念,决定我们对HBase的设计、读写流程以及表结构的设计水平。
类似于数据库中的database和table的概念,HBase将之称为namespace和table,一个namespace包含多个表。
HBase表由以下几个元素组成:
RowKey: 表中每条记录的主键,是定位该行数据的索引,按字典序排序存储,最多能存储64k字节的数据;
Column Famliy 列族(以下写成CF),数据表的纵向切分:
1. CF属于schema的一部分,每行数据具有相同的CF,列族必须作为表模式定义的一部分预先给出;
2. 每个CF可包含无数个动态列;
3. 权限控制、存储以及调优都是在列族层面进行的;
4. 同一列族里面的数据存储在同一目录下,由几个文件保存
Column qualifier:CF内部列标识,每列数据可通过family:qualifier(如:CF1:col1)唯一标识;
Cell单元格
1. 由行和列的坐标交叉决定, 由{row key, CF+cloumn qualifier, version)}确定唯一单元格;
2. 单元格是有版本的;
3. 单元格的内容是未解析的字节数组, 意味着数据是没有类型的,类型信息客户端来维护;
HBase采用多版本控制来处理数据更新问题。对于更新操作只能追加,同时会加入版本号,客户端查询只会取到最新的数据。这里版本号就是时间戳。
Timestamp时间戳
1. 在Hbase每个cell存储单元对同一份数据有多个版本,根据唯一的时间戳来区分版本之间的差异,不同版本的数据按照倒序排序,最新的数据版本排在最前面;
2. 时间戳的类型是64位整数;
3. 时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间;
4. 时间戳也可以由用户显式赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。
Region:数据分区,表的水平切分;
1. HBase自动把表水平分成多个region,每个region保存着一个表里的某段连续的数据
2. 每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阈值的时候,region会等分两个新的region
3. 当table的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个regionserver上。
数据表的逻辑视图
综上所述,一个Hbase数据表我们看到逻辑视图如下,开发者要对图中概念非常的清晰。

数据表的物理存储
HBase以CF为单位存储数据,每个CF内部数据以key value格式保存的,key value组成如下:
[row key, column family, column qualifier, timestamp] => value
于是一张表会存成以下形式保存。

从格式上来看,每行数据不同版本的cell会重复保存rowkey,column family和column qulifier,因此在满足业务需要的情况下应该尽可能短,以节省存储空间。
三、HBase架构

一个 HBase 集群由一个 Master(也可以把两个 Master 做成 HighAvailable)和多个 RegionServer 组成。
Master:
1. 为Region server分配region
2.负责Region server的负载均衡
3. 发现失效的region server并重新分配其上的region
4. 管理用户table的增删改操作
RegionServer:
1. Region server维护region,处理对这些region的IO请求
2. Region server负责切分在运行过程中变得过大的region
ZooKeeper:
1. 保证任何时候,集群只有一个活跃的master
2. 存储所有region的寻址入口
3. 实时监控Region server的上线与下线信息,并实时通知master
4. 存储HBase的schema和table的元数据
HBase Meta表

Mata表是HBase
RegionServer内部结构特殊的表,其维护了每个用户表中rowkey区间与region存放位置的映射关系
RegionServer内部结构

每个regionserver包含:
HLog(WAL Log):HLog文件就是一个普通的Hadoop Sequence File, 当写入操作到达RegionServer时,先把操作写入到HLog,再写入Memstore。
Memstore与storefile
1. 一个region由多个store组成,一个store对应一个列族;
2. store包含位于内存中的memstore和位于磁盘的storefile,写操作先写入memstore,当memestore中的数据达到某个阈值时,regionserver会启动flashcache进程写入storefile,每次写入形成单独的一个storefile;
3. 当storefile文件的数量增长到一定阈值后,系统会进行合并(minor、major、compaction),在合并过程中会进行版本合并与删除(major),形成更大的storefile;
4. 当一个region所有storefile的大小和数量超过一定阈值后,会把当前region分割为两个,并由master分配到相应的regionserver服务器,实现负载均衡;
5. 客户端检索数据,先在memstore找,找不到再找blockcache,最后再找storefile。
HBase Region的定位
HBase的读写操作首先要解决的问题是region的定位:给定一个rowkey或rowkey区间,如何获取rowkey所在的regionserver?

region定位基本步骤如下:
1. 客户端从ZK中获取meta系统表所在的RegionServer;
2. 客户端与meta表所在的RegionServer交互,获取rowkey所在的RegionServer
3. 客户端 与rowkey所在的RegionServer交互,执行相关rowkey操作。
RegionServer的写入流程:
先将数据追加写到WAL中;
持久化WAL之后,再写到memstore中;
两者都写完返回ACK到客户端;
四、 HBase standalone开发环境的搭建
在平时开发中一般可在本地测试,所以需熟悉hbase单机模式部署。单机模式部署比较简单,官方文档有详尽介绍。具体步骤包含以下几点:
将Hbase bin目录加入环境变量
将JAVA_HOME加入hbase-env.sh
在hbase-site.xml中配置HBase数据存储目录、ZK数据存储目录
安装完成后可进入http://localhost:16010查看HBase Web UI。
注意: 单机模式存储目录配置本地目录,另外不需要单独启动ZK, HBase内置了ZK。
五、HBase Shell基本操作
登录shell: hbase shell
查看帮助: help
创建表:create
hbase(main):038:0> create 'test2', 'cf1', 'cf2'# 表名 列族名
查看所有表:list
描述表信息:describe
hbase(main):048:0> describe 'test'
删除表:drop,删除之前需要将表disable
hbase(main):053:0> disable 'test2'hbase(main):010:0> is_disabled 'user'truehbase(main):054:0> drop 'test2'
插入数据:put '表名', 'rowkey', 'CF:qualifier', 'value'
hbase(main):062:0> put 'test', 'row1', 'cf1:name', 'hero'
查询数据:get '表名', 'rowkey'
hbase(main):063:0> get 'test', 'row1'
删除某列:delete '表名', 'rowkey', 'CF:qualifier'
hbase(main):064:0> delete 'test', 'row1', 'cf1:name'Took 0.0062 seconds
扫描表:scan '表名'
hbase(main):066:0> scan 'test'
获取个数:count '表名'
hbase(main):067:0> count 'test'
参考资料:
1. https://www.edureka.co/blog/hbase-architecture/
2. HBase官方文档




