HBase工作原理

1. Region的定义与数据存储管理

这里写图片描述

  1. 如上t_product表中分为2个列族,数据存储首先根据row key进行划分,每个row key在内部以列族再次细分存储,大部分情况下HBase存储的数据都是极其庞大的(可以达到亿级以上)。

  2. HBase内部,根据row key的范围将表数据进行划分并存储到 Region中,每个Region(默认大小10G)都并由RegionServer来管理,一个RegionServer可以管理多个Region。

  3. 当客户端要对HBase数据库进行查询时,首先找到对应的RegionServer(至于如何找到的,后面会讲),然后通过RegionServer访问其内部的Region。

  4. HMaster在客户端读写操作的时候并不做任何参与,它主要是对RegionServer进行管理的。 假如在某种情况下RegionServer挂掉了,那么HMaster会将挂掉的RegionServer管理的Region交由其他的RegionServer来管理。

  5. 除此之外HMaster还有另一个作用,当一个Region的数据不断变大后,HBase会将一个Region拆分成对应的2个Region,并通过HMaster将Region分配给新的RegionServer。如下图:

    这里写图片描述

2. 细化HBase内部存储

这里写图片描述

  1. 一个Region表示特定范围的row key数据集合,而一条row key内部以列族的方式存储,这里Store描述的是某个row key集合的列族存储信息。

  2. 一个Store的容量也是极其庞大的,所以一个Store在物理上由多个StoreFile组成。StoreFile以HFile格式保存在HDFS上。这里写图片描述

    首先HFile文件是不定长的,长度固定的只有其中的两块:Trailer和FileInfo。正如图中所示的,

    Trailer中有指针指向其他数 据块的起始点。

    File Info中记录了文件的一些Meta信息,例如:AVG_KEY_LEN, AVG_VALUE_LEN, LAST_KEY, COMPARATOR, MAX_SEQ_ID_KEY等。

    Data Index和Meta Index块记录了每个Data块和Meta块的起始点

    Data Block是HBase I/O的基本单元,为了提高效率,HRegionServer中有基于LRU的Block Cache机制。每个Data块的大小可以在创建一个Table的时候通过参数指定,大号的Block有利于顺序Scan,小号Block利于随机查询。 每个Data块除了开头的Magic以外就是一个个KeyValue对拼接而成, Magic内容就是一些随机数字,目的是防止数据损坏

  3. 客户端在查询表数据的时候会附带row key,系统根据row key找到对应的RegionServer内部的Region,但如何一个Region内部还有多个Store,Store内部还有StoreFile.如果确定在哪个StoreFile内部查询数据呢,这有依赖于HBase表内部的布隆过滤器。

    这里写图片描述

  4. 当一条数据插入到StoreFile的时候,首先会将row key 映射成64bit 的二进制数据,并存储到StoreFile对应的bit数组中。

  5. 当执行查询时,根据row key的范围先确定好查询的Region,在Region内部找到对应的列族store,并遍历store内部所有的storeFile对应的数组,如果查找的row key与匹配的row key一直,则读取该stroeFile内部的数据。

3. HBase内存管理和文件合并

这里写图片描述

  1. 当客户端写入数据的时候,首先会将数据写入到MemStore中,当MemStore 达到了HBase.hRegion.MemStore.flush.size限制的值,就会将数据刷新到一个新的StoreFile,但是假如在这个过程中,MemStore所在的RegionServer挂掉了,就必须借助HLog进行数据的恢复。

    这里写图片描述

    • WAL 意为Write ahead log。用来 做灾难恢复只用,每个Region Server维护一个Hlog。
    • 当客户端往HRegionServer写入数据的时候,除了向HRegion发送写操作,还会将当前的操作异步到HLog中,而HLog存储的数据也是持久化到HDFS中的。
    • 当MemStore的数据丢失后,就可以通过HLog来进行数据的恢复
  2. 上图可以看到 HBase 的数据是存储到HDFS中的,而HDFS中的数据是不支持修改的。

    • 比如我们在客户端执行了一个删除的操作,当再次查询时数据被干掉了。而在底层,其实只是对被删除的数据做了一个标记,HDFS上的数据并未被删除掉。
    • 比如多次修改数据,可以查询到数据库中显示的数据被改变了,其实在HDFS上也并未对数据进行修改。当执行更新后,原来的数据版本还存在HDFS上。
  3. HBase为了防止小文件(被刷到磁盘的menstore)过多,以保证保证查询效率,HBase需要在必要的时候将这些小的store file合并成相对较大的store file,这个过程就称之为compaction。在HBase中,主要存在两种类型的compaction:minor compaction和major compaction。

    • minor compaction选取一些小的,临近的StoreFile,将它们重写为一个大的StoreFile。出于性能考虑的原因,minor compaction不会删除过期的或者标记要删除的数据。minor compaction的结果是在一个Store中导致更少,更大的SotreFile。

    • major compaction的结果是每个Store 生成一个StoreFile。同时在生成的过程中会删除已经标记要删除的数据。major compaction理论上会提高性能。然而,在一个高负载的系统中,major compaction会导致一些不利的影响。默认配置下,major compaction将会每7天执行一次。因此,对于大多数的线上系统,管理员可以选择在系统空闲时手动执行major compaction,以降低对业务的影响。

主要角色总结:

Client
1 包含访问HBase的接口,client维护着一些cache来加快对HBase的访问,比如Regione的位置信息。

Zookeeper
1 保证任何时候,集群中只有一个master
2 存贮所有Region的寻址入口----root表在哪台服务器上。
3 实时监控Region Server的状态,将Region server的上线和下线信息实时通知给Master
4 存储HBase的schema,包括有哪些table,每个table有哪些column family

Master职责
1 为Region server分配Region
2 负责Region server的负载均衡
3 发现失效的Region server并重新分配其上的Region
4 HDFS上的垃圾文件回收
5 处理schema更新请求

Region Server职责
1 Region server维护Master分配给它的Region,处理对这些Region的IO请求
2 Region server负责切分在运行过程中变得过大的Region
可以看到,client访问HBase上数据的过程并不需要master参与(寻址访问zookeeper和Region server,数据读写访问Regione server),master仅仅维护者table和Region的元数据信息,负载很低。

基本存储的总结:

1 Table中的所有行都按照row key的字典序排列。

2 Table 在行的方向上分割为多个HRegion。

3 Region按大小分割的(默认10G),每个表一开始只有一个Region,随着数据不断插入表,Region不断增大,当增大到一个阀值的时候,HRegion就会等分会两个新的HRegion。当table中的行不断增多,就会有越来越多的HRegion。

4 HRegion是HBase中分布式存储和负载均衡的最小单元。最小单元就表示不同的HRegion可以分布在不同的HRegion server上。但一个HRegion是不会拆分到多个server上的。

5 HRegion虽然是负载均衡的最小单元,但并不是物理存储的最小单元。事实上,HRegion由一个或者多个Store组成,每个store保存一个column family。每个Strore又由一个MemStore和0至多个StoreFile组成。

6 一个Region由多个store组成,每个store包含一个列族的所有数据;Store包括位于内存的MemStore和位于硬盘的storefile

​ 写操作先写入MemStore,当MemStore中的数据量达到某个阈值,HRegionserver启动flashcache进程写入storefile,每次写入形成单独一个storefile;当storefile大小超过一定阈值后,会把当前的Region分割成两个,并由Hmaster分配给相应的Region服务器,实现负载均衡

客户端检索数据时,先在MemStore找,找不到再找storefile。

4. HBase客户端搜索RegionServer

这里写图片描述

如下有2张表(table1为大表,table2为小表),假设要查询的数据是table2的RK15000行数据。Client并不知道存储该行数据的Region存放在哪个RegionServer中。系统是如何查找到该RegionServer的呢?

  1. 首先HBase内部内置了一张.META表,该表记录了用户表的每个Region信息,重要的两行分别是Row KeyServer。而对于Row Key内部需要存储 用户表tableName,用户的每个Region的start key,时间戳。对于Server则是存储该Region存放在哪个RegionServer中。
  2. .客户端在查询、删除、插入的时候,首先通过.META表找到对应的RegionServer.在该RegionServer中遍历Region。

上面的执行过程中存在一个新的问题,.META表本身就是一张HBase表,要查询表中的数据需要知道存储该数据的RegionServer存放在哪里,为了解决这个问题,引入了Zookeeper,将所有RegionServer存储到Zookeeper中。

解决上面的问题后出现了一个新的问题,当table1表的内容变得特别大的情况下,那么记录该表的META表内容也跟着增大;随着META表内容变大,所需要的RegionServer(Region变大)也跟着变大。也就是查询一条数据,在Zookeeper中会有越来越多的RegionServer要逐一遍历。为了解决这个问题,系统引入了一张叫做-ROOT-的表。

示意图如下:

这里写图片描述

如果-ROOT-表太大了,要被分成多个Region怎么办?HBase认为-ROOT-表不会大到那个程度,因此-ROOT-只会有一个Region,这个Region的信息也是被存在HBase内部的。完整的步骤应该是这样的:

  1. Client假设要查询表2,发出命令 get ‘table2’,’RK500’; 首先会去Zookeeper中查找-ROOT-表的唯一的RegionServer。并匹配到META.table2.RK0,RK20000,timestamp的Row key,找到对应的RS20(RegionServer)。
  2. 找到RegionServer 20后根据row key”RK500”匹配到 table2.RK0.timestamp的RegionServer 1。
  3. 在RegionServer中根据BloomFilter找到对应的的StoreFile并查询数据。

注意:

  1. 为了提高效率,META表中的数据会存储到内存中。
  2. client会将查询过的位置信息缓存起来。缓存不会主动失效。

5. HBase读写过程

读请求过程:
1 客户端通过zookeeper以及root表和meta表找到目标数据所在的Regionserver
2 联系Regionserver查询目标数据
3 Regionserver定位到目标数据所在的Region,发出查询请求
4 Region先在MemStore中查找,命中则返回
5 如果在MemStore中找不到,则在storefile中扫描;如果内部有很多storefile,可以使用bloomfilter

写请求过程: 1 client向Region server提交写请求 2 Region server找到目标Region 3 Region检查数据是否与schema一致 4 如果客户端没有指定版本,则获取当前系统时间作为数据版本 5 将更新写入WAL log 6 将更新写入MemStore 7 判断MemStore的是否需要flush为Store文件。

相关文章
相关标签/搜索