一、简介
1、HBase是什么
HBase,Hadoop Database,是一个基于Hadoop HDFS作为其文件存储的分布式数据库
高可用性,高扩展性、面向列的数据库
NoSql数据库
2、HBase的特点
无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列,空列不占用存储空间,表可以很稀疏
数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳
数据类型单一:HBase中的数据类型都是byte[](底层所有数据的存储都是字节数组)
可靠的自动扩展:当Region中的数据太多时会自动分割,使用HDFS分布存储并备份数据
3、HBase的适用场景
写密集型而读相对数量较小的应用,比如天网日志系统写密集型(HBase不适合大范围数据查询)
不需要复杂条件查询的数据的应用,HBase只支持一级索引(只支持对RowKey的查询)
对海量数据存储可扩展性高的应用,HBase支持在线扩展(基于HDFS实现)
二、架构组成
1、HBase架构
物理上,HBase由三种类型服务器的主从模式构成:
Zookeeper:维护集群的状态,包括服务器之间的数据同步操作和master的选举
HMaster:负责Region的分配和HBase库表的创建、删除
Region Server:负责数据的读写服务
2、Zookeeper
维持集群里服务器的同步信息,选举Master,为HBase提供故障容错机制
存储.Root.表的位置信息,.Root.表存储了所有.META.表的Region信息
监控Region Server的状态,及时将Region Server的上线下线状态通知给HMaster
存储 HBase 的 Schema,包括有哪些 Table,每个 Table 有哪些 Column Family
3、HMaster
HMaster主要负责:
-
管理Region Server
集群启动的时候分配Region,在恢复服务或需要负载均衡的时候重新分配Region
监控Region Server的状态,当发现Region Server下线后,分配其所在的Region
管理HBase数据库,提供对HBase访问、修改、删除表的外部服务
4、Region Server
负责维护HMaster分配给它的Region,处理客户端对这些Region的IO请求
负责对Region的分割(当数据量越来越大的时候),负责对HFile的合并操作(Minor Compact 和Major Compact)
5、Region
HBase表是根据RowKey的值水平分割成Region的,所以Region包含了RowKey的起始键值和结束键值之前的所有行。Region在集群中被Region Server管理,一个Region Server可以管理多个Region,负责数据的读写服务。
每个Region由以下信息标识:<表名,startRowKey,创建时间> 由目录表(-ROOT-和.META.)记录该Region的endRowKey
6、HLog
HLog(WAL log):WAL意为write ahead log,用来做灾难恢复,HLog记录数据的所有变更,一旦Region Server 宕机,就可以从log中进行恢复。
每个 Region Server 维护一个 Hlog,而不是每个 Region 一个。这样不同 Region(来自不同 Table) 的日志会混在一起,这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减 少磁盘寻址次数,因此可以提高对 Table 的写性能。带来的麻烦是,如果一台 Region Server 下线,为了恢复其上的 Region,需要将 Region Server 上的 log 进行拆分,然后分发到其它 Region Server 上进行恢复。
7、HBase各组件的协同合作
Region Server和HMaster与Zookeeper连接,Zookeeper通过心跳信息协调HBase集群里各节点的状态信息,为活跃的节点维持对应的znode
每一个Region Server都在Zookeeper中创建对应的ephemeral node,HMaster通过监控这些znode的状态来确认Region Server的上下线状态,如果发现有Region Server下线后,会重新分配Region Server来恢复服务。
HMaster通过互相竞争创建Active Master锁来进行master选举,Zookeeper会选出其中的第一个创建成功的作为唯一的一个活跃HMaster,活跃的HMaster会发送心跳信息给Zookeeper来表明自己的在线状态,非活跃的HMaster会监听活跃的HMaster状态,并在其下线后进行重新选举。
三、读写过程
1、Region寻址
sequenceDiagram
participant Client
participant ZK
participant RS1(.ROOT.)
participant RS2(.META.)
participant RS3(Region3)
Client->>ZK: ROOT表在哪
ZK-->>Client: ROOT表在RS1上
Client->>RS1(.ROOT.): 读取ROOT表,哪个META表可以访问到User表的001行
RS1(.ROOT.)-->>Client: RS2的META表
Client->>RS2(.META.): 读取META表,哪个RS上可以读取到User表的001行
RS2(.META.)-->>Client: RS3的Region3能够找到
Client->>RS3(Region3): 访问RS3,读取User表的001行
RS3(Region3)-->>Client: 提供读取服务
第②步,Client会缓存-ROOT-表的相关信息,以便下一次的快速访问
第④步,Client会缓存.META.表的相关信息,以便下一次的快速访问
2、写操作
2.1、写过程
Client发出一个写请求,Client根据RowKey找到对应Region所在的RegionServer
Client向RegionServer提交对应的写请求
数据写入WAL log(直接写入,无排序)
RegionServer找到目标RowKey的Region,将数据写入Memstore(写入内存的数据是已经排好序的),并且通知Client写入成功
2.2、Region Flush
-
MemStore存储在内存中,当Memstore中的数据大小达到阈值后,会触发RegionServer进行数据刷入磁盘的操作。
-
Memstore的数据达到阈值后,需要刷到磁盘。RegionServer会创建一个新的Memstore,再由一个单独的线程把老的Memstore刷到HFile,成为一个StoreFile
Memstore中的数据是已经排好序的,所以这是一个顺序写的过程,避免了大量的磁盘寻址过程,这个过程非常高效
在Zookeeper中记录一个checkpoint,表示这个时刻前的数据都已经持久化了,HLog也会对应删除旧文件。如果后续数据写入失败导致Memstore丢失数据,HMaster会通过Zookeeper感知,此时就会将HLog根据不同的Region进行拆分,分发到相应的Region目录下,然后再将失效的Region(带有拆分的log)重新分配给RegionServer,这些RegionServer之后会把对应的日志数据刷到Memstore然后flush到磁盘中完成恢复
-
-
HBase表的一个ColumnFamily对应一个Store,一个Store对应一个Memstore,既一个列簇对应一个Memstore,所以不建议表建过多的列簇,引用以下官方的文档:
A typical schema has between 1 and 3 column families per table. HBase tables should not be designed to mimic RDBMS tables.
HBase currently does not do well with anything above two or three column families so keep the number of column families in your schema low.
主要原因是:
过多的列簇会产生更多的Memstore,当Memstore需要Flush到HFile时,Flush是针对Region操作的,既其他未达到阈值的小的Memstore也会被Flush到HFile,导致持久化到磁盘的文件很多,同时产生小文件也很多,刷磁盘也涉及到更多的IO操作
过多的列簇会对RegionServer产生过多的开销。当Region过大进行Split的时候,Split操作是针对所有的列簇进行的,再小的列簇也会进一步拆分成更小的文件,导致更多的小文件产生影响性能
2.3、Region Compact
HBase的Compact分以下两种:
- minor compact:当小的StoreFile达到一定量时,HBase会进行这些小文件的合并,写入到一个大的HFile中,同时进行版本的合并和数据的删除
- major compact:将一个ColumnFamily的所有HFile进行重新合并成一个HFile,进行数据的更新和删除过期cell,这一合并过程也叫做写放大,包含了大量的IO操作和网络数据通信。major compact会把当前Region所服务的所有远程数据下载到本地RegionServer上,这些远程数据可能由于服务器故障或者负载均衡等原因而存储在于远端服务器上。
2.4、Region Split
当StoreFile也来越大,Region的大小也达到一定的阈值后,会触发Region Split操作,一个Region会分割成两个大小相同的Region,原来的Region会下线,同时新的Region会被HMaster分配到相应的RegionServer上,出于负载均衡的原因,新产生的Region可能会被分配到其他的RegionServer,这就是为什么Region Compact过程中可能会产生大量通信的原因。
3、读请求
上面所说的Region寻址方式
RegionServer上的Block cache会将经常被读的数据缓存起来提高数据的读取效率,当缓存空间被占满的时候,读取频率低的会被推出,LRU算法
当读取的数据存放在不同的存储介质时(最近被读取的数据放在Block cache,最近更新的数据放在Memstore,旧的数据刷入到了HFile,HBase对存在不同介质的数据进行读合并操作)
当从Memstore找不到数据的时候,如果需要读取的数据是被多次刷入到了不同的HFile,那么HBase会根据索引和boom filter从HFile中寻找到数据,这个就是读放大