1

1. 概念相关

为什么有HDFS还要用HBase?
  • 延迟: Mapreduce编程框架延迟较高,无法满足大规模数据实时处理应用的需求
  • 访问: HDFS面向批量访问而不是随机访问
为什么用HBase而不用传统关系型数据库? / 关系型数据库和HBase有什么区别?
  • 数据类型: 传统关系型数据库有丰富的数据类型,HBase把数据存储为未经解释的字符串
  • 数据操作: 关系数据库包含了丰富的操作,可涉及复杂的多表连接,而HBase只有简单的插入查询删除清空等,不涉及表与表的连接
  • 存储模式: 关系数据库基于行存储,HBase基于列存储
  • 数据索引: 关系数据库可构建复杂的多个索引以提高检索效率;HBase只有一个索引:行键(RowKey),经过巧妙地设计,通过rowkey索引或扫描,不会使系统慢下来
  • 数据维护: 关系数据库更新会覆盖原值,HBase则是生成一个新的版本,旧数据依然保留
  • 可伸缩性: 关系数据库很难实现横向扩展,而HBase能够容易地通过在集群中增加或减少硬件实现性能地伸缩

HBase架构

image.png

图1
image.png
图2

  • 客户端:客户端包含访问HBase的接口,同时在缓存中维护着已经访问过的Region位置信息,用来加快后续数据访问过程
  • Zookeeper服务器: 可以帮助选举出一个Master作为集群的总管,并保证在任何时刻总有唯一一个Master在运行,这就避免了Master的“单点失效”问题;保存了记录了META表的位置(元数据入口地址);
  • Master: 主服务器Master主要负责表和Region的管理工作:
    –管理用户对表的增加、删除、修改、查询等操作
    –实现不同Region服务器之间的负载均衡
    –在Region分裂或合并后,负责重新调整Region的分布
    –对发生故障失效的Region服务器上的Region进行迁移
    1. Region服务器 , 负责维护分配给自己的Region,和HDFS交互,Region的拆分(是否拆分由HMaster决定),StoreFile合并,响应用户的读写请求

一些个人理解:

  • 一个HBase表, 由多个Region组成,这些Region可以不在一个Region Server上
  • 根据RowKey切分Region,某个或某个连续范围内的RowKey会被切分到一个Region
  • 一个Store 对应 一个列族的数据,但一个列族由于Region的切分,可能对应多个store
  • 寻址过程客户端只需要询问Zookeeper服务器,不需要连接Master服务器
某个Region Server失效/宕机会怎么处理

某个Region Server宕机,其元数据信息仍存在,其数据在HDFS上(Store File)也存在副本。那么HMaster会根据元数据信息,将该Region Server 管理的数据分给其他Region Server;而Memory Store 中的数据不可恢复,但产生Memory Store数据的操作保存在了HLog中,那么HMaster还需要把HLog拆分,并把对应得HLog分给对应的Region Server。

HBase 读写

读流程

image.png

  1. 客户端向ZK询问元数据所在的Region Server是哪一个
  2. ZK返回元数据所在的RS
  3. 客户端向该RS请求元数据
  4. 返回元数据,客户端根据RowKey和元数据找到要RowKey对应数据所在的RS
  5. 客户端对该RS发起读请求
  6. 该RS先去Block Cache中找RowKey对应的数据,如果不存在,再去MemoryStore中找(MemoryStore的数据最新,所以先找该位置),MemroyStore不存在 再去StoreFile找,找到后把该数据刷写到Block Cache中,便于下次直接从缓存中读取,再返回
写流程

image.png

Flush 刷写

hbase-default.xml配置文件

  • hbase.regionserver.global.memorystore.size: 触发刷写到storefile的整个RegionServer最大内存,默认是堆的40%
  • optionalcacheflushinterval: RegionServer中任一Region的MemoryStore时间间隔达到该值,触发刷写,默认1小时

注意 这两个刷写机制会触发整个RegionServer的所有MemoryStore刷写

  • hbase.hregion.memstore.flush.size: 单个region的memory store达到某个上限,会触发该memory store刷写,默认128MB
Compacy 合并小文件

因为可能有一些memory store数据量很少的时候被刷写,因此可能存在刷写到磁盘的小文件,这就需要定时进行合并

  • hbase.hregion.majorcompaction: 默认是7天,但该操作非常耗资源,因此生产环境下应该关闭,空闲时手动打开
  • hbase.hstore.compactionThreshold: 当一个region的storeFile个数超过一定数量,自动进行合并,默认是3

优化相关

预分区

默认的Region拆分方式是每次根据Region个数的平方 * 128MB 作为拆分的最大上限,那么可能导致刚开始的拆分的region很小,后面region很大才会拆分,这样会导致负载不均衡.
所以需要根据业务需求,根据RowKey设置预分区策略

RowKey设计

既然预分区策略和RowKey相关 那么RowKey的设计也至关重要
一般来说,rowkey要保证唯一性,我们都会为它加上一个插入时的时间戳,和一些业务需求常用的字段的值
为了防止数据倾斜,直观的做法是在RowKey前加上一个随机数,再根据这个随机数%预分区数来预分区,保证每个Region大小基本均衡。

但这样带来一个问题就是,当需要查询时,因为我们没办法确定插入数据时的随机数,所以我们需要自定义一个生成哈希值的函数,我们选取一些字段值经过Hash/MD5得到一个数,根据这个数%预分区数,将其添加到RowKey前,将其划分到某个Region。

这样我们需要查询时只需要重复这个过程即可得到其RowKey,再去根据该RowKey读取数据.

除此之外,还要考虑集中性,因为业务有可能是集中读取某一个范围内的数据,那么就要根据这个字段集中存储数据,同时要考虑避免集中带来的数据倾斜


猛男落泪为offer
22 声望5 粉丝

半路出家大数据


引用和评论

0 条评论