概念
hbase是一个分布式的、面向列式存储的、高可扩展高性能的非关系型数据库,其技术是仿照了Google的文件系统Bigtable,是建立在hadoop集群的基础之上并利用hdfs实现了分布式存储,基于hadoop的hdfs进行存储的同时也利用了hdfs的容错实现了高容错性,hbase具有对数据进行实时的读写的能力,内部使用哈希表存储索引,所以可以在hdfs中快速查找数据。
场景
Hadoop 只能执行批量处理,并且只以顺序方式访问数据。这意味着必须搜索整个数据集, 即使是最简单的搜索工作。 当处理结果在另一个庞大的数据集,也是按顺序处理一个巨大的数据集。在这一点上,一个 新的解决方案,需要访问数据中的任何点(随机访问)单元
hbase可以作为Hadoop的随机存取数据库,适用于非结构化数据的存储,不适用于存储关系复杂的数据模型,是建立在 HDFS 之上,被设计用来提供高可靠性、高性能、列存储、可伸缩、多版本的 NoSQL 的分布式数据存储系统,实现对大型数据的实时、随机的读写访问
HBase 中的表特点
1、大表:一个表可以有上十亿行,上百万列
2、面向列:面向列(族)的存储和权限控制。
3、稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。
4、无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一 张表中不同的行可以有截然不同的列

Rowkey的概念
由于Hbase只支持3中查询方式:
1、基于Rowkey的单行查询
2、基于Rowkey的范围扫描
3、全表扫描
因此,Rowkey对Hbase的性能影响非常大,Rowkey的设计就显得尤为的重要。设计的时候要兼顾基于Rowkey的单行查询也要键入Rowkey的范围扫描。具体Rowkey要如何设计后续会整理相关的文章做进一步的描述。这里大家只要有一个概念就是Rowkey的设计极为重要。
rowkey 行键可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),最好是 16。在 HBase 内部,rowkey 保存为字节数组。HBase 会对表中的数据按照 rowkey 排序 (字典顺序)
Column的概念
列,可理解成MySQL列。
ColumnFamily的概念
列族, HBase引入的概念。
Hbase通过列族划分数据的存储,列族下面可以包含任意多的列,实现灵活的数据存取。就像是家族的概念,我们知道一个家族是由于很多个的家庭组成的。列族也类似,列族是由一个一个的列组成(任意多)。
Hbase表的创建的时候就必须指定列族。就像关系型数据库创建的时候必须指定具体的列是一样的。
Hbase的列族不是越多越好,官方推荐的是列族最好小于或者等于3。我们使用的场景一般是1个列族。
TimeStamp的概念
TimeStamp对Hbase来说至关重要,因为它是实现Hbase多版本的关键。在Hbase中使用不同的timestame来标识相同rowkey行对应的不通版本的数据。
HBase 中通过 rowkey 和 columns 确定的为一个存储单元称为 cell。每个 cell 都保存着同一份 数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64 位整型。时间戳可以由 hbase在数据写入时自动赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。 每个 cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。
为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,hbase 提供了两种数据版 本回收方式:
- 保存数据的最后 n 个版本
- 保存最近一段时间内的版本(设置数据的生命周期 TTL)。
用户可以针对每个列簇进行设置。
单元格(Cell)
由{rowkey, column( = + ), version} 唯一确定的单元。 Cell 中的数据是没有类型的,全部是字节码形式存贮。
-
HBASE具体的表结构
根据hbase的结构,我们可以简单的列出几个增删改的语句
创建表
# 语法:create <table>, {NAME => <family>, VERSIONS => <VERSIONS>}
# 例如:创建表t1,有两个family name:f1,f2,且版本数均为2
hbase(main)> create 't1',{NAME => 'f1', VERSIONS => 2},{NAME => 'f2', VERSIONS => 2}
添加数据
# 语法:put <table>,<rowkey>,<family:column>,<value>,<timestamp>
# 例如:给表t1的添加一行记录:rowkey是rowkey001,family name:f1,column name:col1,value:value01,timestamp:系统默认
hbase(main)> put 't1','rowkey001','f1:col1','value01'
查询数据
a)查询某行记录
# 语法:get <table>,<rowkey>,[<family:column>,....]
# 例如:查询表t1,rowkey001中的f1下的col1的值
hbase(main)> get 't1','rowkey001', 'f1:col1'
# 或者:
hbase(main)> get 't1','rowkey001', {COLUMN=>'f1:col1'}
# 查询表t1,rowke002中的f1下的所有列值
hbase(main)> get 't1','rowkey001'
b)扫描表
# 语法:scan <table>, {COLUMNS => [ <family:column>,.... ], LIMIT => num}
# 另外,还可以添加STARTROW、TIMERANGE和FITLER等高级功能
# 例如:扫描表t1的前5条数据
hbase(main)> scan 't1',{LIMIT=>5}
c)查询表中的数据行数
# 语法:count <table>, {INTERVAL => intervalNum, CACHE => cacheNum}
# INTERVAL设置多少行显示一次及对应的rowkey,默认1000;CACHE每次去取的缓存区大小,默认是10,调整该参数可提高查询速度
# 例如,查询表t1中的行数,每100条显示一次,缓存区为500
hbase(main)> count 't1', {INTERVAL => 100, CACHE => 500}
删除数据
a )删除行中的某个列值
# 语法:delete <table>, <rowkey>, <family:column> , <timestamp>,必须指定列名
# 例如:删除表t1,rowkey001中的f1:col1的数据
hbase(main)> delete 't1','rowkey001','f1:col1'
注:将删除改行f1:col1列所有版本的数据
b )删除行
# 语法:deleteall <table>, <rowkey>, <family:column> , <timestamp>,可以不指定列名,删除整行数据
# 例如:删除表t1,rowk001的数据
hbase(main)> deleteall 't1','rowkey001'
c)删除表中的所有数据
# 语法: truncate <table>
# 其具体过程是:disable table -> drop table -> create table
# 例如:删除表t1的所有数据
hbase(main)> truncate 't1'
表的管理
1)查看有哪些表
hbase(main)> list
2)创建表
# 语法:create <table>, {NAME => <family>, VERSIONS => <VERSIONS>}
# 例如:创建表t1,有两个family name:f1,f2,且版本数均为2
hbase(main)> create 't1',{NAME => 'f1', VERSIONS => 2},{NAME => 'f2', VERSIONS => 2}
3)删除表
分两步:首先disable,然后drop
例如:删除表t1
hbase(main)> disable 't1'
hbase(main)> drop 't1'
4)查看表的结构
# 语法:describe <table>
# 例如:查看表t1的结构
hbase(main)> describe 't1'
5)修改表结构
修改表结构必须先disable
# 语法:alter 't1', {NAME => 'f1'}, {NAME => 'f2', METHOD => 'delete'}
# 例如:修改表test1的cf的TTL为180天
hbase(main)> disable 'test1'
hbase(main)> alter 'test1',{NAME=>'body',TTL=>'15552000'},{NAME=>'meta', TTL=>'15552000'}
hbase(main)> enable 'test1'
hbase架构
HBase 依赖于 HDFS 做底层的数据存储,HBase 依赖于 MapReduce 做数据计算,HBase 依赖于 ZooKeeper 做服务协调
hbases是java编写的,通过java api实现了提供内部的各个功能,hbases架构是一个典型的M-Z-S(Master-Zookeeper-Slaves)体系架构,主要进行存储工作的还是hdfs,所以说hbase的存储是基于hdfs实现的,写入到hbase的数据最终是会落地到hdfs中

-
Zookeeper:集群协调器,在hbase集群启动时HMaster会向zookeeper提供集群的加载表,其中包括了region、HMaster、RegionServer的等信息,zookeeper实际调度着region该到哪个HRegionServer进行读写
Zookeeper记录HMaster地址,避免HMaster单点问题HRegionServer把自己的信息注册到Zookeeper中,HMaster随时感知各个HRegionServer的健康状况 -
HRegion:HRegion是HBase中分布式存储和负载均衡的最小单元,即不同的HRegion可以分别在不同的HRegionServer上,但同一个Region是不会拆分到多个server上。
HRegion按大小分隔,每个表一般是只有一个HRegion。随着数据不断插入表,HRegion不断增大,当HRegion的某个列族达到一个阀值(默认256M)时就会分成两个新的HRegion。- table和region的关系:
table默认最初只有一个region,随着记录数的不断增加而变大,起初的region会逐渐分裂成多个region,一个region有【startKey, endKey】表示,不同的region会被master分配给相应的regionserver管理。region是hbase分布式存储和负载均衡的最小单元,不同的region分不到不同的regionServer。region虽然是分布式存储的最小单元,但并不是存储的最小单元。region是由一个或者多个store组成的,每个store就是一个column family。每个store又由memStore和1至多个store file 组成(memstore到一个阀值会刷新,写入到storefile,有hlog来保证数据的安全性,一个regionServer有且只有一个hlog)
- table和region的关系:
-
HMaster:HMaster没有单点问题,HBase可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master在运行。
主要负责Table和Region的管理工作,在hbase架构中充当主节点,负责监控集群中从节点RegionServer的信息,包括健康状况信息,管理着哪些region的信息分布在哪些RegionServer,在RegionServer挂掉时HMaster会将挂掉的RegionServer中的region转移到其他的RegionServer中;
HMaster还负责管理用户对hbase表的增删改操作,维护和管理HBase表的结构、和各个Region的元数据信息,可以决定分配哪些region到哪个RegionServer节点,从而协调集群的负载达到负载均衡;
HMaster不会进行处理读写请求。hbase支持HA集群模式,所以hbase集群是有多个HMaster存在的,但是处于活跃状态的就只有一个,活跃的HMaster宕机时,会从其他备用的HMaster选举一个作为活跃的HMaster,实现了hbase的高可用。
-
主要作用如下:
- 管理用户对表的增删改查操作
- 管理HRegionServer的负载均衡,调整Region分布
- Region Split后,负责新Region的分布
-
在HRegionServer停机后,负责失效HRegionServer上Region迁移
HMaster实现的负载均衡
-
HRegionServer:HBase中最核心的模块,主要负责响应用户I/O请求,向HDFS文件系统中读写。
HRegionServer管理一些列HRegion对象,每个HRegion对应Table中一个Region,HRegion由多个HStore组成,每个HStore对应Table中一个Column Family的存储。
HRegionServer处理region的读写,region会随着插入的数据越来越多,会进行拆分,默认大小是10G一个,

-
HStore:HBase存储的核心。由MemStore和StoreFile组成。MemStore是Sorted Memory Buffer。用户写入数据的流程:
- Client通过Zookeeper的调度,向RegionServer发出写数据请求,在Region中写数据;
- 数据被写入Region的MemStore,知道MemStore达到预设阀值(即MemStore满);
- MemStore中的数据被Flush成一个StoreFile;
- 随着StoreFile文件的不断增多,当其数量增长到一定阀值后,触发Compact合并操作,将多个StoreFile合并成一个StoreFile,同时进行版本合并和数据删除;
- StoreFiles通过不断的Compact合并操作,逐步形成越来越大的StoreFile;
- 单个StoreFile大小超过一定阀值后,触发Split操作,把当前Region Split成2个新的Region。父Region会下线,新Split出的2个子Region会被HMaster分配到相应的RegionServer上,使得原先1个Region的压力得以分流到2个Region上。

HBase中的所有数据文件都存储在Hadoop HDFS文件系统上,格式主要有两种:
- HFile,HBase中Key-Value数据的存储格式,HFile是Hadoop的二进制格式文件,实际上StoreFile就是对HFile做了轻量级包装,即StoreFile底层就是HFile。
- HLog File,HBase中WAL(Write Ahead Log)的存储格式,物理上是Hadoop的Sequence File
HFile
工作流程
写流程
客户端发向Zoopeeker发起写请求获取RegionServer的地址,客户端获取到RegionServer的地址后向地址的RegionServer发起写请求,RegionServer接收到写请求后先会检查本机的region的状态,检查完成后会就会对region中的memstore进行写入操作,这一过程是原子性的要全部失败要么全部成功,当memstore达到预期的大小后,就会进行Flush操作,将缓存中的数据写入文件形成一个个storeFile文件,当storeFile到达一定数量会进行合并(Compaction),Compaction将多个storeFile合并成一个大的storeFile,当storeFile文件大小超过预定值一般为10G,就会触发拆分(split),split操作会把一个region分为两份,HMaster会对这两份region分配给相应的RegionServer,在写操作完成后会将storeFile落地到hdfs中存储


读流程
客户端发向Zoopeeker发起读请求获取RegionServer的地址,客户端获取到RegionServer的地址后向地址的RegionServer发起读请求,RegionServer接收到读请求后先会扫描自身的memstore,在扫描blockcache,如果没有找到相应的数据就会到StoreFile读取数据返回给客户端
Hbase环境搭建
先装好hadoop和jdk,完事后进行安装hbase
编辑hbase安装目录的conf目录,编辑hbase-env.sh

注释掉jdk7的配置

使用hbase自带的zk

将hadoop的core-site.xml和hdfs-site.xml拷贝到安装目录的conf目录下

编辑hbase安装目录的conf文件中的hbase-site.xml,端口配置为装好的hadoop的端口

配置好后启动hbase,进入安装目录的bin文件夹 ./start-hbase.sh 启动,jps查看是否启动成功

输入ip:16010可以查看hbase的管理界面 例如:192.168.200.128:16010

启动完成后hbase会在hdfs中创建一个目录,查看hdfs中的目录

网友评论