一、什么是hbase
hbase 全称Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩、实时读写的分布式数据库
hbase利用hadoop hdfs作为其文件存储系统,利用hadoop MapReduce来处理hbase中的海量数据、利用zookeeper作为其分布式协同服务
主要用来存储非结构化数据(视频语音等二进制文件)和半结构化数据(json)的松散数据(列式存储 NoSQL数据库)
二、hbase的原理
2.1数据存储模式
先介绍一下各个节点及其任务:
- client
- 负责JavaAPI、hbase shell等
- 发起读写请求
- 缓存数据:主要包括两类 - 缓存region的位置信息 -缓存meta(元数据)表的region位置
- zookeeper
- 存储Hbase的元数据
- 负责HMaster的高可用
- HMaster
- 为RegionServer分配Region
- 负责RegionServer的负载均衡
- 发现失效的RegionServer并重新分配其上的region
- 管理用户对table的增删改操作
- RegionServer
- RegionServer负责维护Region,处理对这些region的IO请求
- RegionServer负责切分在运行过程中变得过大的region
- Region
- hbase会自动将表划分成多个region,每个region保存一个表中某段连续的数据。
- 每个创建的时候默认有一个region,随着数据的不断加入,region
会逐渐变大,当数据到达一定值时,region等分(裂变 )- 当table中的数据不断增多,region会越来越大最后被保存在一个或者多个RegionServer上
- MemStore
- 内存中存储数据的地方,在写数据或是读数据时,会首先向memstore中存储/获取数据。
- 在写入数据时,如果memstore数据达到阈值,会将数据写入到storefile中,每一次都形成一个单独的storefile
- StoreFile
- storefile是存储在磁盘中的hbase数据
- 当storefile文件的数量增长到一定的阈值后,系统会进行合并操作形成更大的storefile
- 当一个region所有storefile的大小和数量超过一定阈值后(10G),会把当前的region分割为两个,并由hmaster分配到相应的regionserver服务器,实现负载均衡
- Hlog(WAL log)
- WAL 意为Write ahead log用来做灾难恢复使用,Hlog 记录数据的所有变更,一旦数据修改,就可以从log 中进行恢复。
- 每个Region Server 维护一个Hlog。这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减少磁盘寻址次数,因此可以提高对table 的写性能。
- 首先客户端连接zk获取meta region所在的节点(meta只有一个region)
- 然后开始检索获取rowkey所在的RegionServer位置
- 查询hbase:meta(hbase:meta中记录了所有表region信息,region开始key和结束key,region所在节点)
- 判断当前rowkey在哪一个region中
- 连接对应region所在的RegionServer
2.2 数据存储
客户端向zk发送请求获取meta region所在的节点
- 先将修改和插入的操作保存到Hlog中
- 然后数据开始写入到Memstore中
- 当数据在memstore中达到阈值时,会出现溢写,将数据写入到storefile中
2.3数据读取
- 先从memstore中获取数据
- 如果memstore中没有数据,向storefile中获取数据
- 如果建表时设置了in-memory,数据会保存在缓存中
2.4数据模型
- hbase在存储数据的时候会按照rowkey字典升序排序
- hbase会将一个表切分成多个region,region是hbase负载均衡的最小单元
- 表刚创建的时候只有一个region,当不停的插入数据,达到一定的阈值之后会切分成两个。(大小,时间,手动触发split)
- 每个region中有多个store,每个store有一个memstore和多个storefile,store实际上就是hdfs中的一个Hfile文件
- 当store文件的数量达到阈值之后会触发合并操作,在合并的过程中,删除过期和已经删除的数据
hbase中的数据三维有序
- rowkey字典升序
- 列名字典升序
- 版本号自然降序(默认当前系统时间)
三、hbase shell
- 创建和删除命名空间
create_namespace '名称'
drop_namespace '名称'
- 创建表
create <table>, {NAME => <family>, VERSIONS => <VERSIONS>}
//例
create 'User','info'//(表名,列簇名)
- 查看所有表
list
- 查看表详情
describe '表名'
- 修改表
//删除指定的列簇
alter '表名', 'delete' => '列簇名'
//例:
alter 'user','delete' => 'info'
//增加新的列簇
alter '表名', NAME => '列簇名'
//例:
alter 'user', NAME =>'info'
- 插入数据
put <table>,<rowkey>,<family:column>,<value>
//例:
put 'user','001','info:name','tjf'
- 查询数据
get <table>,<rowkey>,[<family:column>,....]
//例:
get 'user','001'
- 查询所有记录
scan <table>, {COLUMNS => [ <family:column>,.... ], LIMIT => num}
//扫描所有:
scan 'user'
//扫描前两条:
scan 'user', {LIMIT => 2}
//范围查询:
scan 'user', {STARTROW => '001'}
scan 'user', {STARTROW => '001', ENDROW => '002'}
- 删除
//删除列:
delete 'user', '001', 'info:age'
//指定rowkey删除:
deleteall 'user', 'row2'
//删除表中所有数据:
truncate 'user'
//删除表:
drop 'user'
//(在删除表之前,首先需要禁用表)
//禁用表:
disable 'user'
//启用表:
enable 'user'
//测试表是否存在:
exists 'user'
四、hbase JavaAPI
- 通过Java写入hbase中只需要在打开连接然后写入需求即可
- 两个工具
- 比较器
- RegexStringComparator :支持正则表达式的值比较
- SubStringComparator:用于监测一个子串是否存在于值中,并且不区分大小写。
- BinaryPrefixComparator:前缀二进制比较器。只比较前缀是否相同。
- BinaryComparator:二进制比较器,用于按字典顺序比较 Byte 数据值。
- 过滤器
- 列值过滤器:
列值过滤器:效率较低,需要做全表扫描
SingleColumnValueFilter:用于测试值的情况(相等,不等,范围 、、、)- 列簇过滤器:
FamilyFilter:用于过滤列族(通常在 Scan 过程中通过设定某些列族来实现该功能,而不是直接使用该过滤器)。- 列名过滤器:
QualifierFilter:用于列名(Qualifier)过滤。- 行键过滤器:效率较高,行键前缀过滤效率较高
RowFilter:行键过滤器,一般来讲,执行 Scan 使用 startRow/stopRow 方式比较好,而 RowFilter 过滤器也可以完成对某一行的过滤。
在代码运行的过程中,主要分为以下几个方面
- 建立hbase连接
- 根据需求,获取目标表名或者设置表名
- 如果需要上传表,则使用put方法
- 如果需要获取表内容,则使用比较器对比需求的rowkey然后使用过滤器获取数据
预分区
hbase表刚创建的时候只有一个分区
如果插入海量的数据,会导致节点瓶颈,插入效率低
步骤
- 统计rowkey的分布情况
- 编写预分区文件 split.txt(任意名称)
例如150010000到150010100的数据
可以写split.txt文件如下
15001000|
15001001|
15001002|
15001003|
15001004|
15001005|
15001006|
15001007|
15001008|
15001009|
| 表示一个最大的边界,在二进制中他的ASCII值高于所有数字和字母
- 文件上传到服务器,创建预分区表
create 'stu','info',{SPLITS_FILE => 'split.txt'}
- 如果表已经创建完成可以使用以下方式
split ‘表名’,‘rowkey’
(如果HMaster挂了之后,split还可以使用,但是会等到HMaster重启之后运行)