使用HBase已有半年时间,最近在公司内部组织了一场HBase的分享会,没想到引起了很多同学的热烈讨论。但是由于功课没做好,加之底层的原理没有完全搞懂,很多同学的提问不能很好的给予解答,不免有些遗憾。
今天特地整理一下ppt上的内容,希望能给第一次接触HBase的同学一点帮助。
HBase 官方文档 https://hbase.apache.org/book.html
本文主要从以下几个方面介绍下HBase
1.基本概念
HBase 是建立在HDFS之上,提供高可靠、高性能、列存储、可伸缩、实时读写NoSql的分布式数据库系统。
- HDFS为HBase提供底层数据存储服务
- Zookeeper为HBase提供稳定服务和fail-over机制
- LSM提供了高性能支持
- WAL提供了可靠性
2.HBase 特性
- 面向列,面向列(族)的存储和权限控制,列(族)独立检索
- 容量巨大,单表可以有百亿行,百万列
- 无模式,同一张表中不同的行可以有截然不同的列
- LSM数据结构(Log-Structured Merge-Tree)
- WAL(Write-Ahead-Log)预写日志机制
- Row Key有序排列(字典排序)
- 稀疏性,空值不占用存储空间
- TTL(Time to Live)
- 数据多版本,每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳
- 数据类型单一,Hbase中的数据都是字符串(byte[])
3.HBase 架构
图片来源网络Client
- 包含访问HBase的接口,并维护cache来加快对HBase的访问,比如region的位置信息
Master
- 为Region server分配region
- 负责Region server的负载均衡
- 发现失效的Region server并重新分配其上的region
- 管理用户对table的增删改查操作
Region Server
- Regionserver维护region,处理对这些region的IO请求
- Regionserver负责切分在运行过程中变得过大的region
4.HBase 逻辑视图
图片来源网络- 隐形主键,rowkey
- 数据单一,type[]
- 无模式,列不固定,列由列族管理和检索
- 多版本,一个单元列内不同时间戳对应不同的数值
5.HBase 物理模型
图片来源网络- Table中所有行都按照row key的字典序排列
- Table在行的方向上分割为多个Region
- Region按大小分割的,每个表开始只有一个region,随着数据增多,region不断增大,当增大到一个阈值的时候,region就会等分会两个新的region,之后会有越来越多的region
- Region是Hbase中分布式存储和负载均衡的最小单元,不同Region分布到不同RegionServer上
- Region虽然是分布式存储的最小单元,但并不是存储的最小单元
6.HBase 容错和恢复WAL
图片来源网络Store
每一个region由一个或多个store组成,至少是一个store,hbase会把一起访问的数据放在一个store里面,即为每个ColumnFamily建一个store,如果有几个ColumnFamily,也就有几个Store。一个Store由一个memStore和0或者多个StoreFile组成。 思考:为什么不建议一张表创建多个列族?
MemStore
memStore 是放在内存里的。保存修改的数据即keyValues。当memStore的大小达到一个阈值时,memStore会被flush到文件,即生成一个快照。目前hbase 会有一个线程来负责memStore的flush操作。
StoreFile
memStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存。
HFile
HBase中KeyValue数据的存储格式,是hadoop的二进制格式文件。HBase 的写入最先会放入内存中,提供实时的查询,当 Memstore 中数据达到一定量的阈值(128MB),会通过 Flush 操作生成 HFile 持久化到 HDFS 中,随着用户的写入,生成的 HFile 数目会逐步增多,这会影响用户的读操作,同时也会系统占用(HDFS 层 block 的数目, regionserver 服务器的文件描述符占用), region split 操作,region reopen 操作也会受到不同程度影响。 HBase 通过 Compaction 机制将多个 HFile 合并成一个 HFile 以控制每个 Region 内的 HFile 的数目在一定范围内
HLog
HLog文件就是一个普通的Hadoop Sequence File, Sequence File的key是HLogKey对象,其中记录了写入数据的归属信息,除了table和region名字外,还同时包括sequence number和timestamp,timestamp是写入时间,sequence number的起始值为0,或者是最近一次存入文件系统中的sequencenumber。 Sequence File的value是HBase的KeyValue对象,即对应HFile中的KeyValue。
LogFlusher
定期将内存中kv数据同步到hlog
LogRoller
定期滚动更新日志,删除旧日志。每个regionserver维护一个HLog,而不是每一个region一个,这样不同region(来自不同的table)的日志会混在一起,这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减少磁盘寻址次数,因此可以提高table的写性能。带来麻烦的时,如果一个regionserver下线,为了恢复其上的region,需要将region server上的log进行拆分,然后分发到其他regionserver上进行恢复。
容错
每个HRegionServer中都有一个HLog对象,HLog是一个实现Write Ahead Log的类。在每次用户操作写入MemStore的同时,也会写一份数据到HLog文件中。HLog文件定期会滚动更新,并删除旧的文件(已持久化到StoreFile中的数据)。
恢复
当HRegionServer意外终止后,HMaster会通过Zookeeper感知到,HMaster首先会处理遗留的 HLog文件,将其中不同Region的Log数据进行拆分,分别放到相应region的目录下,然后再将失效的region重新分配,领取到这些region的HRegionServer在Load Region的过程中,会发现有历史HLog需要处理,因此会Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。
7.HBase 一次查询过程
图片来源网络-ROOT-表和.META.表是hbase内置的两张表,结构相同。
一张表可能有多个分区,Hbase查询一条数据首先要知道这条记录存放在哪个分区region,.META.表就是记录用户信息与分区的关系数据。
.META.表由regionServer 管理,当分区足够多时.META.也会分区,这就意味着可能有多个regionServer在管理.META.信息,要想知道是哪个分区存储了这条记录,就要先知道这个.META.由哪个regionServer 管理。
-ROOT-表有着和meta表一样的数据结构,它是用来存储meta 与分区关系的表,-ROOT-表只有一份,由zk管理地址。
8.HBase 应用场景
- 大数据量存储,大数据量高并发操作
- 高并发写入,瞬间写入量很大
- 业务场景简单(无交叉列,交叉表,事务, 连接等)
- 可以优雅的数据扩展
9.HBase RowKey设计
参见文章:RowKey行键设计规范
最后补充一些分享会上别人提出的问题
Q:HBase为什么写入会有热点,不应该是负载均衡吗?
A:HBase 写入不是直接负载均衡到各个节点的,而是去META表查询各个region的开始结束区间,以及对应的regionServer,符合某个region区间,就去连接这个region所在的server,当前缀都相同时(日期打头),数据都在相邻位置,很容易写在同一个region,所以就造成了某个server热点
Q:数据在HFile中存储,有更小的rowkey写入磁盘时,是插入到前面的HFile还是追加在后面的HFile?
A:追加在后面的HFile,多个HFile之间是允许有rowkey 交叉存储的,也就是无序的。当HFile数量到达一定阈值,就会启动合并排序,将多个小HFile合并并排序成一个大的HFile。最后删除旧的HFile。
Q:regionServer 往HLog写日志是同步的吗?如果同步写怎么做到高并发的?
A:是同步的。昨天我有说有缓冲区,这个是不对的,抱歉!因为写log数据是只追加,不更新,因此io的消耗并不大,足够支撑hbase高并发。
参考资料:
HBase原理、基本概念、基本架构 https://blog.csdn.net/woshiwanxin102213/article/details/17584043
HBase基本概念
https://www.cnblogs.com/SuKiWX/p/8861993.html
HBase -ROOT-和.META.表结构(region定位原理) https://blog.csdn.net/chlaws/article/details/16918913
网友评论