概念
HBase是基于hadoop的数据库工具,来源于Google三篇论文之一 BIGTABLE,APACHE做了开源的实现就是 HBASE 技术
是一种NoSQL的菲关系型数据库,不符合关系数据库的范式
适合存储半结构化和非结构化的数据
适合存储稀疏的数据,空的数据不占用空间
面向列族存储
可以提供实时的增删改查操作
可以存储海量的数据,性能非常优良
不支持严格的事务控制,只能在行级别保证事务
HBase是一个高可靠,高性能,面向列的可伸缩的分布式存储系统,利用hbase技术可以在廉价的机器上搭建大规模结构化的存储集群
使用HadoopHDFS进行数据存储,使用MapReduce来处理数据,使用zookeeper来作为协调工具
逻辑结构:
使用表来存储数据(命名空间,表,行键,列族,列,值)
行键:RowKey
相当于hbase中的主键,Hbase中所有的数据都要有行键
所有数据都是按照行键的字段顺序排序后存储
对HBase中的数据的查询只有三种:
根据制定行键查询,查询制定范围的行键,全表扫描查询
列族:columnFamily
是Hbase中垂直方向保存数据的结构,列族是Hbase表的元数据的一部分,要在创建表的时候就指定具有哪些列族,列族中可以包含一个或多个列
列:column
一个列族可以有多个列,列不是元数据的一部分,不需要在创建的时候事先定义,而是后续使用表时随时为表的列族动态增加的列
单元格和时间戳
在HBase表中,水平方向的行 和 垂直方向的列 交汇 就得到了HBase中的一个存储单元,而在这个存储单元中,可以存储数据,并且可以保存数据的多个版本,这些个版本之间通过时间戳来进行区分
单元格中的数据都以二进制进行存储,没有数据类型的区别
HBase的原理
Hbase表中的数据按照行键的字典顺序进行排列
HBase表最初只有一个HRegion保存数据,随着数据写入,HRegion越来越大,达到一定的阈值后会自动分裂为两个Hregion,随着这个过程不停的进行,HBase表中的数据会被划分为若干个HRegion进行管理
HRegion是HBase表中的数据分布式存储和负载均衡的基本单元
Hbase中的数据会以HRegion为单位分布式的存储在HRegionServer中,从而实现了分布式存储和负载均衡
Region的存储,Region中存储了多个store,一个列族对应一个store,
store内部有一个memStore和0个或者多个fileStore,storeFile的本质是存在于HDFS中的HFile的文件
memStore的持久化依赖于HLog(本质是存储在HDFS中的一个文件,追加数据记录操作日志)
Hbase写数据的流程
客户端要存储数据时,根据表名和行键来确定要操作哪一个HRegion,找到存储该HRegion的HRegioinServer,对该HRegion进行操作,根据列族来确定操作哪一个Store。向store中的memStore中写入数据,到达阈值后会写出到hdfs中Hfile文件中,并在HLog中记录向memStore的操作日志,防止数据丢失
内存满了怎么办?
store中的memStore被填满时,会产生一个新的memStore继续工作,并启动一个独立的线程,将memStore中的数据写到Hfile中取,将数据持久化到HDFS中
在不停的产生HFile过程中,同一个Store的先后产生的多个HFile中可能存在对同一个数据的多个不同的版本,其中旧的版本的数据很可能已经是失效的垃圾数据了,但是由于HDFS只能一次写入多次读取不支持行级别的增删改,这些垃圾数据无法及时清理。最终造成浪费存储空间,降低查询性能。
当Hfile的数量达到一定的量,或者时间达到一定间隔,HBase会触发Hfile的合并操作,将同一个store先后产生的数据进行合并,在合并的过程中将垃圾数据清理掉, 多个HFile合并成了一个
当合并成了一定大小的HFile时,HFile会被拆分成若干个小的HFile,防止HFile过大
内存断电丢失怎么办?
在HBase的HRegionServer中存在名为HLog的日志文件,在向memStore写入数据时,数据需要同时写入HLog中记录操作日志。
这个HLog文件本质上是存在于HDFS中的一个文件,通过对HDFS中的这个文件不停的追加数据记录操作日志
而在memStore满了溢写到HFile中完成后,HBase会将最后一条持久化到HFile中的日志的编号记录到Zookeeper中redo point
这样一旦断电丢失内存数据,只需要到Zookeeper中找到最后一条持久化的日志的编号,再从HLog中将这个编号之后的数据恢复到内存中即可以找回所有的数据。
为了防止HLog文件过多,分摊写入性能,HBase中一个HRegionServer一个HLog,这个HRegionServer中的所有的HRegion的日志都会记在这同一个HLog文件中。
HFile的文件结构
StoreFile分为DataBlock,MetaBlock,FileInfo,DataIndex,MetaIndex,Trailer
Data Blocks:
保存表中的数据,可以被压缩,DataBlocks中存放了大量的DataBlock,其中以键值对的形式保存着表的数据,其中键是行键,值是该行的某一个列的值,所以一个HBase表中的一个行可能在底层存在多键值对保存
MetaBlock:
保存用户自定义的kv对,可以被压缩
FileInfo:
HFile的元数据,不可被压缩,用户可以在这一部分添加自己的元信息
Data Block Index
Data Block的索引
Meta Block Index
MetaBlock的索引
Trailer
这一段是定长的,保存了每一段的偏移量,读取一个HFile时,会首先读取Trailer,Trailer保存了每个段的起始位置
HBase读数据的流程
当客户端要读取某一张表时,Hbase会根据表和行键确定出HRegion,找出存有该HRegion的HRegionServer,找到HRegion,根据要查找的列族,找出对应的Store(一个列族对应一个Store)。
首先在memStore中寻找要查询的数据,如果能查到直接返回查询到的数据,查询结束。
如果在memStore中找不到要查询的数据,要查询该store对应的所有的storeFile;
在这个过程中,解析storeFile,先读取storeFile中的Trailer块,找到DataBlockIndex,根据索引判断要找的数据在当前storeFile中是否存在,如果不存在直接返回空 ,如果存在则根据索引快速找到对应的DataBlocks中的DataBlock返回。
这样多个storeFile可能返回了多个DataBlock,其中包含着多个版本的查询的数据结果,之后在内存中将这些DataBlock信息合并,得到最新的数据返回,完成查询
在理想的情况下 ,HBase的查询可以基于内存完成,效率很高,在最不理想的情况下,需要大量的查询底层的HDFS文件,性能会有所下降,但是,由于这些storeFile都增加了索引,所以查询的速度仍然是有保证的,但是仍然会比最理想的情况慢大概一个数量级
HBase的HRegion寻址过程
在HBase中存在一张特殊的表hbase:meta,其中存放着HBase的元数据信息,包括HBase中有哪些表,表中哪些Region,每个Region分布在哪个HRegionServer中meta表很特殊,永远有且仅有一个HRegion,这个HRegion存放在某一个HRegionServer中,并且会将这个持有meta表的Region的HRegionServer的地址存放在Zookeeper中meta-region-server节点下。所以当在进行HBase表的读写操作时,需要先根据表名 和 行键确 定位到HRegion,这个过程就是HRegion的寻址过程。
HRgion的寻址过程首先由客户端开始,访问zookeeper 得到其中meta-region-server的值,根据该值找到meta表唯一的HRegion存储的HRegionServer,得到meta表唯一HRegion,从中读取真正要查询的表和行键对应的HRgion的地址,再根据该地址,找到真正的操作的HRegionServer和HRegion,完成HRgion的定位,继续读写操作。
如果客户端之前已经查找过HRegion的地址信息,之后的Region定位中,如果能在本地缓存中找到地址,就直接使用该地址提高性能
三种常见的存储系统
Hash存储
哈希存储引擎 是哈希表的持久化实现,支持增、删、改以及随机读取操作,但不支持顺序扫描,对应的存储系统为key-value存储系统。
对于key-value的插入以及查询,哈希表的复杂度都是O(1),明显比树的操作O(n)快,如果不需要有序的遍历数据,哈希表就是最好的方案。
案例:HashMap
B树存储
B树存储引擎是B树的持久化实现,不仅支持单条记录的增、删、读、改操作,还支持顺序扫描(B+树的叶子节点之间的指针)。
案例:MySql
LSM树存储
LSM树(Log-Structured Merge Tree)存储引擎和B树存储引擎一样,同样支持增、删、读、改、顺序扫描操作。而且通过批量存储技术规避磁盘随机写入问题。当然凡事有利有弊,LSM树和B+树相比,LSM树牺牲了部分读性能,用来大幅提高写性能。
LSM树的设计思想非常朴素:将对数据的修改增量保持在内存中,达到指定的大小限制后将这些修改操作批量写入磁盘,不过读取的时候稍微麻烦,需要合并磁盘中历史数据和内存中最近修改操作,所以写入性能大大提升,读取时可能需要先看是否命中内存,否则需要访问较多的磁盘文件。极端的说,基于LSM树实现的HBase的写性能比Mysql高了一个数量级,读性能低了一个数量级。
案例:Hbase
HBase的系统结构
-
HMaster
为RegionServer分配Region
为RegionServer提供负载均衡
GFS上的垃圾回收
处理对Schema的更新请求
-
Zookeeper
保证任何时候集群都只有一个master
监控RegionServer,将其上线下线信息通知给Master
存储meta表region的地址
存储HBase的元数据信息,包括有哪些表,有哪些列族等
-
HRegionServer
维护Master分配给他的region,处理这些region的IO请求
复制切分在运行过程中变大的region
HBase总结
为什么HBase可以很快?
内部有memStore做缓冲,读写都是有限基于内存实现的效率高
数据按照行键排序 查询效率高
数据从水平方向上切分为若干个HRegion 分布式是的存储 提高效率
为什么HBase可以存储很多数据?
数据最终存储在HDFS上,而HDFS是分布式的存储系统,可以动态扩容,基本可以认为容量没有限制
空的数据不占用空间,当数据比较稀疏时,不会浪费空间
hbase按列存储数据,而同一个列中的数据数据结构往往类似,可以实现高下率的数据压缩,节省空间
为什么HBase是可靠的?
数据最终存储在HDFS中,而HDFS自带多副本机制保证高可靠
存在多个HRegionServer,即使某些HRegionServer宕机,HBase也可以恢复数据到其他HRegionServer继续工作
HMaster提供了备用机制,自动在HMaster 和 BackUpHMaster之间切换
hbase和hive和传统的关系型数据库的比较:
比起传统的关系型数据库,可以存储半结构化非结构化的数据,可以存储和处理更大级别的数据,提供高效的查询,对于稀疏数据的处理更好,具有更好的横向扩展性,免费开源性价比很高。
但是不能支持非常好的事务特性,只支持行级的事务。只能通过行键来查询,表设计时难度更高。而mysql用来存储结构化的数据提供更好的事务控制查询数据更加灵活。
比起hive,hive只是在mapreduce上包了一层壳,本质上还是离线数据的处理的工具,实时查询性能有限,本质上是一个基于hadoop的数据的处理能力,具有完整的增删改查p的数据仓库工具,不能支持行级别的新增修改和删除。hbase可以提供实的能力,本质上是一种数据库工具。
学习中,有不正确的地方多多指教