HBase原理分析

HBase原理分析

参考:
https://blog.csdn.net/u010330043/article/details/51291934
https://blog.csdn.net/chlaws/article/details/16918913
https://www.cnblogs.com/163yun/p/9014762.html
https://blog.csdn.net/wangshuminjava/article/details/80575864

一、HBase是什么

 HBase是高可用、面向列的分布式存储,底层数据存储通过HDFS实现,因为是分布式的结构设计,所以支持横向扩展,通过加机器就能够达到扩容的目的。
 与传统的数据库数据区别:

  • 传统数据库一般通过集群的方式部署,这样做虽然能做到读写分离、双机热备,但并不支持横向扩展,随着数据量的增大,很容易达到瓶颈。
  • HBase的查询只能通过rowkey,不支持SQL操作,因此使用于特定的场景,比如按照商品ID获取商品信息、商家ID获取商家信息、订单ID获取订单信息……(也支持全表扫描的scan操作,但效率较差)
  • HBase的表结构通过列族进行定义,列族内字段可以灵活添加,而并不需要修改表结构。

二、架构分析

 从架构图中可以看到,HBase的结构分为 Zookeeper、HMaster、HRegionServer、Region、Store、MemStore、StoreFile、HFile、HLog、DFS Client、HDFS
HBase架构图
 HBase的每张表都按照rowkey的字典顺序进行存储,并按照相应的阈值被切分为多个子表(HRegion),默认每个子表的大小为256M。

HMaster的作用:

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

HRegionServer作用:

1、 维护HMaster分配给他的region,处理对这些region的io请求(即读写)。
2、 负责切分正在运行过程中变的过大的region。
3、 HRegionServer存取一个子表时,会创建一个HRegion对象,然后对表的每个列族创建一个Store实例,每个Store都会有一个MemStore和0个或多个StoreFile与之对应,每个StoreFile都会对应一个HFile, HFile就是实际的存储文件。因此,一个HRegion有多少个列族就有多少个Store。 一个HRegionServer会有多个HRegion和一个HLog。

HRegion

 table在行的方向上分隔为多个HRegion。HRegion是HBase中分布式存储和负载均衡的最小单元,即不同的HRegion可以分别在不同的HRegionServer上,但同一个HRegion是不会拆分到多个server上。
 Region按大小分隔,每个表一般默认是只有一个HRegion。随着数据不断插入表,HRegion不断增大,当HRegion的某个列族达到一个阈值(默认256M)时就会分成两个新的region(当然切分策略并不是这一种,这个case只是说明默认情况下)。

Store

 每一个HRegion由一个或多个store组成,至少是一个store,HBase会把一起访问的数据放在一个store里面,即为每个ColumnFamily建一个store,如果有几个ColumnFamily,也就有几个Store。一个Store由一个memStore和0或者多个StoreFile组成。 HBase以store的大小来判断是否需要切分region。

MemStore

 memStore 是放在内存里的。保存修改的数据即keyValues。当memStore的大小达到一个阀值(默认64MB)时,memStore会被flush到文件,即生成一个快照。目前hbase 会有一个线程来负责memStore的flush操作。

StoreFile

 memStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存。

HFile

 HBase中KeyValue数据的存储格式,是hadoop的二进制格式文件。

HLog

 HLog(WAL log):WAL意为write ahead log,用来做灾难恢复使用,HLog记录数据的所有变更,一旦region server 宕机,就可以从log中进行恢复。

三、切分(分片、split)原理

 Region自动切分是HBase能够拥有良好扩张性的最重要因素之一,也必然是所有分布式系统追求无限扩展性的一副良药。 Region切分触发策略 在最新稳定版(1.2.6)中,HBase已经有多达6种切分触发策略。当然,每种触发策略都有各自的适用场景,用户可以根据业务在表级别选择不同的切分触发策略。常见的切分策略如下图:
HBase切分策略

Region切分的触发条件是什么?
  • ConstantSizeRegionSplitPolicy:0.94版本前默认切分策略。一个region中** 最大store **的大小大于设置阈值之后才会触发切分。另外一个大家比较关心的问题是这里所说的store大小是压缩后的文件总大小还是未压缩文件总大小,实际实现中store大小为压缩后的文件大小(采用压缩的场景)。ConstantSizeRegionSplitPolicy相对来来说最容易想到,但是在生产线上这种切分策略却有相当大的弊 端:切分策略对于大表和小表没有明显的区分。阈值(hbase.hregion.max.filesize)设置较大对大表比较友好,但是小表就有可能不会触发分裂,极端情况下可能就1个,这对业务来说并不是什么好事。如果设置较小则对小表友好,但一个大表就会在整个集群产生大量的region,这对于集群的管理、资源使用、failover来说都不是一件好事。

  • IncreasingToUpperBoundRegionSplitPolicy: 0.94版本~2.0版本默认切分策略。这种切分策略微微有些复杂,总体来看和ConstantSizeRegionSplitPolicy思路相同,一个region中最大store大小大于设置阈值就会触发切分。但是这个阈值并不像ConstantSizeRegionSplitPolicy是一个固定的值,而是会在一定条件下不断调整,调整规则和region所属表在当前regionserver上的region个数有关系 :(#regions) * (#regions) * (#regions) * flush size * 2,当然阈值并不会无限增大, 最大值为用户设置的MaxRegionFileSize。这种切分策略很好的弥补了ConstantSizeRegionSplitPolicy的短板,能够自适应大表和小表。而且在大集群条件下对于很多大表来说表现很优秀,但并不完美,这种策略下很多小表会在大集群中产生大量小region,分散在整个集群中。而且在发生region迁移时也可能会触发region分裂。

  • SteppingSplitPolicy: 2.0版本默认切分策略。这种切分策略的切分阈值又发生了变化,相比IncreasingToUpperBoundRegionSplitPolicy简单了一些,依然和待分裂region所属表在当前regionserver上的region个 数有关系,如果region个数等于1,切分阈值为flush size * 2,否则为MaxRegionFileSize。这种切分策略对于大集群中的大表、小表会比IncreasingToUpperBoundRegionSplitPolicy更加友好,小表不会再产生大量的小region,而是适可而止。

Region切分的切分点在哪里?

整个region中最大store中的最大文件中最中心的一个block的首个rowkey。

四、HRegion定位原理

client对HBase上数据的读写是通过HRegionServer来和HRegion交互完成的。

HRegion被分配给哪个HRegionServer是完全动态的,所以需要机制来定位HRegion具体在哪个HRegionServer。

举例说明:
client在通过rowkey=PK20001查找表Table1的记录时,HBase使用三层结构来定位HRegion:
首先要理解ROOT表和META表跟普通的用户表是一个概念,只不过存储的数据是系统级别的信息,不是用户级别的信息,类似于MySQL数据库中的information_schema
   1、 通过zk里的文件/hbase/rs得到-ROOT-表的位置,根据-ROOT-表查找表Table1所在的 .META.表的HRegionServer为RS1。-ROOT-表记录了HBase中有哪些表,每个表一行记录,比如表Table1,表Table2……。如下图:
   ROOT表
   2、通过RS1得到了.META.表中Table1的数据,通过rowkey=PK2001得到所在的HRegionServer为RS3。META表中的每一个region在-ROOT-表中都是一行记录,即META表记录数:ROOT表记录数 = N : 1,META表结构如下:
   META表
  3、 通过和RS3交互得到了rowkey=PK20001所在的用户表region的位置,拿到对应的数据。用户表中的每个region在.META.表中都是一行记录,即META表记录数 : 用户表记录数 = N : 1

** Attetion: **
1.在整个路由过程中并没有涉及到MasterServer,也就是说HBase日常的数据操作并不需要MasterServer,不会造成MasterServer的负担。
2. Client端并不会每次数据操作都做这整个路由过程,很多数据都会被Cache起来。在后续访问时直接通过缓存拿数据,当Region重新分区后,通过缓存拿就会报错(因为按照原来的位置去访问找不到了嘛),这时候就再重复以上过程,重新读取,并缓存。

五、rowkey原则

 先假设我们的rowkey是按照时间顺序生成的,那么在往节点添加数据的时候,他们会被分配到相同的节点,进而造成热key的问题,即所有读写的请求基本在同一个HRegionServer,导致该HRregionServer的性能下降,不能发挥分布式的优势。那如何解决这种问题呢?有如下几种方案:

  • Salt加盐
     Salting是将每一个Rowkey加一个前缀,前缀使用一些随机字符,使得数据分散在多个不同的Region,达到Region负载均衡的目标。
    比如在一个有4个Region(注:以 [ ,a)、[a,b)、[b,c)、[c, )为Region起至)的HBase表中,
    加Salt前的Rowkey:abc001、abc002、abc003
    我们分别加上a、b、c前缀,加Salt后Rowkey为:a-abc001、b-abc002、c-abc003
    可以看到,加盐前的Rowkey默认会在第2个region中,加盐后的Rowkey数据会分布在3个region中,理论上处理后的吞吐量应是之前的3倍。由于前缀是随机的,读这些数据时需要耗费更多的时间,所以Salt增加了写操作的吞吐量,不过缺点是同时增加了读操作的开销。
  • Reverse反转
     针对固定长度的Rowkey反转后存储,这样可以使Rowkey中经常改变的部分放在最前面,可以有效的随机Rowkey。
    反转Rowkey的例子通常以手机举例,可以将手机号反转后的字符串作为Rowkey,这样的就避免了以手机号那样比较固定开头(137x、15x等)导致热点问题,
    这样做的缺点是牺牲了Rowkey的有序性。这种和加盐的本质其实是一样的。增加了写的吞吐量,但是因为无序也增加了读的开销。
  • Hash散列或者Mod
    用Hash散列来替代随机Salt前缀的好处是能让一个给定的行有相同的前缀,这在分散了Region负载的同时,使读操作也能够推断。确定性Hash(比如md5后取前4位做前缀)能让客户端重建完整的RowKey,可以使用get操作直接get想要的行。
    例如将上述的原始Rowkey经过hash处理,此处我们采用md5散列算法取前4位做前缀,结果如下
    9bf0-abc001 (abc001在md5后是9bf049097142c168c38a94c626eddf3d,取前4位是9bf0)
    7006-abc002
    95e6-abc003
    若以前4个字符作为不同分区的起止,上面几个Rowkey数据会分布在3个region中。实际应用场景是当数据量越来越大的时候,这种设计会使得分区之间更加均衡。
    如果Rowkey是数字类型的,也可以考虑Mod方法。

六、zookeeper的作用

  1. HRegionServer 向zookeeper注册,提供HRegionServer状态信息(是否在线),HMaster监听HRegionServer变化,如果挂掉,则对数据重新分配
  2. HMaster启动后会向zookeeper注册ROOT表信息,client请求时会先从zookeeper读取ROOT表位置
  3. 保证HMaster不会出现单点故障。通过zookeeper的选举机制,保证总会有一个HMaster正常运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值