Hbase

目录

 

HBase的基础架构

HBase的底层原理

HMaster如何分配region

HBase的Region定位

写机制

flush

compact

split

读机制

对HBase的二级索引的理解


HBase的基础架构

1. HMaster:主节点。负责分配region,以及管理HRegionServer。

2. HRegionServer:从节点。负责管理region。

HBase的主节点有一个或多个,其中一个是活动节点,其他是备用节点。在zookeeper集群中抢占到唯一一个代表active master锁的就是活动节点,其他备用节点对zookeeper集群中的这个锁设置观察,等待锁释放,以伺机抢占锁。

从节点启动时,在zookeeper上的server目录下建立代表自己的临时节点。由于主节点订阅了server目录上的变更消息,当server目录下的文件出现新增或删除操作时,主节点可以得到来自zookeeper的实时通知。因此一旦从节点上线,主节点能马上得到消息。

HBase的底层原理

参考资料

HBase的Region定位

深入HBase架构解析(一)

深入HBase架构解析(二)

HMaster如何分配region

1 扫描zookeeper上的server父节点,获得当前可用的region server列表。

2 和每个region server通信,获得当前已分配的region和region server的对应关系。

3 扫描.META.region的集合,计算得到当前还未分配的region,将他们放入待分配region列表。

4 有一个region server上有可用空间时,master就给这个region server发送一个装载请求,把region分配给这个region server。region server得到请求后,就开始对此region提供服务。

5  当region server下线时,它和zookeeper的会话断开,zookeeper自动释放代表这台region server的独占锁。master就可以确定region server无法继续为它的region提供服务了,此时master会将这台region server的region分配给其它还活着的region server。

HBase的Region定位

在一个RegionServer中可以管理多个不同的region。Hbase表会根据RowKey值被切分成不同的分片region,region是Hbase负载均衡的最小单元。最小单元就表示不同的region可以由不同的Region server管理,但一个region只能由一个region  server管理。

在HBase 0.96以前,HBase有两个特殊的表:-ROOT-和.META,其中-ROOT表的位置存储在ZooKeeper,它存储了.META表的RegionInfo信息,并且它只能存在一个HRegion,而.META表则存储了用户所有表的RegionInfo信息,它可以被切分成多个HRegion,因而对第一次访问用户Table流程如下:

  1. 从ZooKeeper中读取-ROOT所在HRegionServer,缓存该位置信息
  2. 从该HRegionServer中根据请求的TableName,RowKey读取.META所在HRegionServer,缓存该位置信息
  3. 从该HRegionServer中读取.META. Table的内容而获取此次请求需要访问的HRegion所在的位置,缓存该位置信息
  4. 访问该HRegionSever,获取请求的数据

这需要三次请求才能找到用户Table所在的位置,然后第四次请求开始获取真正的数据。当然为了提升性能,客户端会缓存-ROOT和.META的位置信息以及内容。

可是即使客户端有缓存,在初始阶段需要三次请求才能找到用户Table真正所在的位置,性能比较低下。实际上现在的HRegion的最大大小都会设置的比较大,一个HRegion完全装得下完整的.meta表,所以HBase 0.96以后去掉了-ROOT- Table,只剩下这个特殊的目录表叫做Meta Table(hbase:meta),它存储了集群中所有用户HRegion的位置信息,而ZooKeeper的节点中(/hbase/meta-region-server)存储的则直接是这个Meta Table的位置,并且这个Meta Table和以前的-ROOT- Table一样是不可split的,只存在一个HRegion中。这样,客户端在第一次访问用户Table的流程就变成了:

  1. 从ZooKeeper(/hbase/meta-region-server)中读取hbase:meta所在的HRegionServer,缓存该位置信息。
  2. 从该HRegionServer中读取hbase:meta的内容而获取此次请求需要访问的HRegion所在的HRegionServer,缓存该位置信息。
  3. 访问该HRegionSever,获取请求的数据

从这个过程中,我们发现客户会缓存这些位置信息,然而第二步它只是缓存当前RowKey对应的HRegion的位置,因而如果下一个要查的RowKey不在同一个HRegion中,则需要继续查询hbase:meta所在的HRegion,然而随着时间的推移,客户端缓存的位置信息越来越多,以至于不需要再次查找hbase:meta表的信息,除非某个HRegion因为宕机或Split被移动,此时需要重新查询并且更新缓存。

写机制

客户端定位到相应的region server后,开始将数据写入到对应的region里面去。

第一步将数据写入HLog中

HLog是HBase的日志文件,类似于MySQL的binlog。当对HBase写数据的时候,数据不是直接写进磁盘,它会在内存中保留一段时间(时间以及数据量阈值可以设定)。但把数据保存在内存中很有可能引起数据丢失,为了解决这个问题,数据会先写在一个叫做HLog(Write-Ahead logfile)的文件中,然后再写入内存中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。HLog文件是存储在HDFS上的,也就是说,region server直接操作HDFS写HLog。

第二步写memoryStore。这两步写入成功,数据就算写入成功。

写memoryStore过程涉及到HBase的三个重要机制:flush、compact、split

flush

memoryStore(In Memory Sorted Buffer)是写缓存,位于region server上的内存存储,用来保存当前的数据操作,所以当数据保存在HLog中之后,RegsionServer会在内存中存储键值对。一个region对应多个memoryStore,一个memoryStore对应一个列族。数据一直往memoryStore里面写,等到memoryStore写到一定的阈值的时候,启动线程进行flush过程,flush到HDFS中,形成storeFile。

flush涉及属性:

hbase.hregion.memstore.flush.size134217728

即:128M就是当前region对应所有Memstore大小总和的默认阈值

hbase.regionserver.global.memstore.upperLimit0.4

hbase.regionserver.global.memstore.lowerLimit0.38

即:这两个参数是全局所有的Memstore大小总和所占内存百分比,Memstore大小总和超过0.4,就开始由大到小依次flush Memstore,直到Memstore大小总和小于0.38为止

compact

storeFile是store中小的HFile格式的文件。

数据持久化存储的体现形式是Hfile,存放于DataNode中,被ResionServer以region的形式进行管理。

store就是region中对应列族的存储数据,来自同一个memoryStore的所有storeFile就包含了同一个列族的数据。随着storeFile的增多,region server 将 region内所有的,不仅限于同一个列族的 storeFile合并成为一个大的HFile,这一个过程叫做compact机制,适应了hdfs擅长保存大文件的特点。

在storeFile合并的过程当中,标记为Deleted的Cell会被删除,已经过期的、超过最多版本数的Cell会被丢弃。HBase中,删除一条记录并不是修改HFile里面的内容,而是写新的文件,待HBase做合并的时候,把这些文件合并成一个HFile,用时间比较新的文件覆盖旧的文件。HBase这样做的根本原因是,HDFS不支持修改文件。

split

region的大小是有上限的,其阈值由hbase.hregion.max.filesize指定,默认为10G。regoin中的HFile越来越大,一旦达到阈值,region server会将region切开,分为两个region,这是split机制。

HRegionServer拆分region的步骤是,先将该region下线,然后拆分,将其子region加入到hbase:meta表中,再将他们加入到原本的HRegionServer中。region server 更新 znode  的状态为SPLIT。master就能知道状态更新了,master的平衡机制会判断是否需要把子region 分配到其他region server 中。在split之后,meta和HDFS依然会有引用指向父region. 当compact 操作发生在子regions中,会重写数据文件,这个时候引用就会被逐渐的去掉。垃圾回收任务会定时检测子regions是否还有引用指向父文件,如果没有引用指向父文件的话,父region 就会被删除。

读机制

客户端定位到相应的region server后,开始访问对应的HRegionServer。

HRegionServer优先扫描的顺序是BlockCache、memoryStore、storeFile和HFile,获取数据后将数据合并,响应给客户端。

其中StoreFile的扫描先会使用Bloom Filter过滤那些不可能符合条件的数据,然后使用Block Index快速定位Cell,并将其加载到BlockCache中,然后从BlockCache中读取。BlockCache是读缓存,位于region server上的内存存储,利用了“引用局部性”原理,将数据预读取到内存中,以提升读的性能。“引用局部性”分为空间局部性和时间局部性。空间局部性是指CPU在某一时刻需要某个数据,那么有很大的概率在一下时刻它需要的数据在其附近;时间局部性是指某个数据在被访问过一次后,它有很大的概率在不久的将来会被再次的访问。

对HBase的二级索引的理解

HBase的一级索引是rowkey(行键),在hbase客户端直接做条件查询时,只能通过get或scan查询指定的rowkey。如果想以column(字段)内容作为查询条件,往往要通过MapReduce/Spark等分布式计算框架进行,硬件资源消耗和时间延迟都会比较高。为了让HBase的数据查询更高效、适应更多的场景, 诸如使用非rowkey字段检索也能做到秒级响应,或者支持各个字段进行模糊查询和多字段组合查询等, 因此需要在HBase上面构建二级索引, 以满足现实中更复杂多样的业务需求。

常用的解决方案是以空间换时间,把常用查询字段作为二级索引,将该字段下的数据冗余保存一份到es或者solr里面去,作为二级索引表。查询的时候首先查索引表,获取行键后再到hbase查询详情。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值