HBase设计结构和原理

2019-07-25 16:57:30 浏览数 (1)

详细介绍了Hbase各个组件功能,表数据结构

1. 数据模型

1.1 数据模型相关概念
  • 表:HBase采用表来组织数据,表由行和列组成,列划分为若干个列族。
  • 行:每个HBase表都由若干行组成,每个行由行键(row key)来标识。
  • 列族:一个HBase表被分组成许多“列族”(Column Family)的集合,它是基本的访问控制单元。
  • 列限定符:列族里的数据通过列限定符(或列)来定位。
  • 单元格:在HBase表中,通过行、列族和列限定符确定一个“单元格”(cell),单元格中存储的数据没有数据类型,总被视为字节数组byte[]。
  • 时间戳:每个单元格都保存着同一份数据的多个版本,这些版本采用时间戳进行索引。
1.2 数据坐标

HBase中需要根据行键、列族、列限定符和时间戳来确定一个单元格

2. HBase 系统架构

2.1 HBase功能组件
  • Client
    • 包含访问HBase的接口,同时在缓存中维护着已经访问过的Region位置信息,用来加快后续数据访问过程
    • 通过与Zookeeper通信在获得Region的存储位置信息后,直接从Region Server上读取数据
    • 与Hmaster通信进行管理类操作
  • 一个Master Server
    • 维护元数据信息
    • 在Region分裂或合并后,负责重新调整Region的分布。
    • 对发生故障失效的Region服务器上的Region进行迁移。
  • 多个Region Server
    • 负责存储和维护分配给自己的Region,处理来自客户端的读写请求
    • Region由RegionServer管理。所有用户数据的读写请求,都是和RegionServer上的Region进行交互
    • Region可以在RegionServer之间迁移
  • Zookeeper服务器
    • 选举出一个Master作为集群的总管,并保证在任何时刻总有唯一一个Master在运行,这就避免了Master的“单点失效”问题
    • 获得Region位置信息返回给客户端,大多数客户端甚至从来不和Master通信,这种设计方式使得Master负载很小。
2.2 Region Server 概念
  • Region :用于存放数据信息
  • Store:一个Region由一个或多个Store组成。每个Store对应图中的一个Column Family。
  • MemStore:一个Store包含一个MemStore,客户端向Region插入的数据缓存到MemStore。
  • StoreFile:MemStore的数据Flush到HDFS后成为StoreFile
  • HFile:HBase中keyvalue数据的存储格式,HFile是Hadoop二进制格式文件,实际上是storefile对hfile做了轻量级包装
  • HLog:HBase中WAL的存储格式,物理上是Hadoop的sequence file。保证了当RegionServer故障的情况下用户写入的数据不丢失。RegionServer的即可以多个Region共享一个相同的Hlog,也可以每个Region拥有一个Hlog。
2.2.1 Store 工作原理
  • Store是Region服务器的核心。
  • storefile的数量增长到一定的阈值会触发compact合并操作
  • 单个StoreFile过大时,即当前达到Region设置的阈值,会触发split操作,即把当前的region分成2个region
  • HBase只是增加数据,更新和删除操作都是在compact阶段做
  • 是为了减少同一个Region中的同一个ColumnFamily下面的小文件(HFile)数目,从而提升读取的性能
2.2.2 Hlog工作原理
  • 分布式环境必须要考虑系统出错。HBase采用HLog保证系统恢复。
  • HBase系统为每个Region服务器配置了一个HLog文件,它是一种预写式日志(Write Ahead Log,WAL)
  • 用户更新数据先写入MemStore缓存再写入日志
  • 出现故障
    • Zookeeper会实时监测每个Region服务器的状态,当某个Region服务器发生故障时,Zookeeper会通知Master
    • Master首先会处理该故障Region服务器上面遗留的HLog文件,这个遗留的HLog文件中包含了来自多个Region对象的日志记录
    • 系统会根据每条日志记录所属的Region对象对HLog数据进行拆分,分别放到相应Region对象的目录下,然后,再将失效的Region重新分配到可用的Region Server中,并把与该Region对象相关的HLog日志记录也发送给相应的Region Server
    • Region Servrt获得分配给自己的Region对象以及与之相关的HLog日志记录以后,会重新做一遍日志记录中的各种操作,把日志记录中的数据写入到MemStore缓存中,然后,刷新到磁盘的StoreFile文件中,完成数据恢复。
2.3 写入操作
  1. Client通过访问ZK来获取到HBase:meta.的地址信息
  2. ZK通过访问HBase:meta.表来获取具体的RS返回给Client
  3. Client端获取到目标地址(RegionServer、Region、Rowkey)后,然后直接向该地址发送数据请求。
  4. 向指定RS的对应region进行数据写入
    1. 获取Region操作锁。(读写锁)
    2. 一次获取各行行锁。
    3. 写入到MemStore中。(一个内存排序集合)
    4. 释放以获取的行锁。
    5. 写数据到WAL中。(Write-Ahead-Log)
    6. 释放Region锁。

    既然是Write-Ahead-Log,为何先写内存再写WAL? 先写内存的原因:HBase提供了一个MVCC机制,来保障些数据阶段的数据可见性。先写MemStore再写WAL,是为了一些特殊场景下,内存中的数据能够更及时的返回。如果先写WAL失败的话,MemStore助攻的数据会被回滚。

  5. Flush
    • 达到Region设置MemStore的阈值
    • MemStore占用内存的总量和RegionServer总内存的比值超出来了预设的阈值大小
    • HBase定期刷新MemStore
    • WALs中文件数量达到阈值
    • 通过shell命令分别对一个表或者一个Region进行Flush
  6. Compaction Compaction分为Minor、Major两类:
    • Minor合并:多个小文件重写为数量较少的大文件。有最少和最大的数量限制,通常会选择一些连续时间范围内的小文件进行合并,受磁盘IO的影响
    • Major合并:将Region中的一个列族的所有hfile重写为一个新的hfile,过程如下图
      • 扫描所有的Row Key,顺序重写全部数据
      • 重写数据的过程中可能删除掉标记过的数据和超出版本号的数据,删不删除根据实际情景而定
  7. Region Split
    • Region的大小超出了预设的阈值,则需要将该Region自动分裂成为两个Region
    • 分裂过程中,被分裂的Region会暂停读写服务。父Region的数据文件并不会真正的分裂,而是仅仅通过更改引用方式,来实现快速分裂,即通过新的访问方式访问源文件,HBase后台会自己进行分裂操作
    • 客户端册所缓存的父Region的路由信息需要被更新
2.4 读操作
  1. 客户端发起请求
    • Get操作在精准的Key值的情形下,读取单行用户数据。
    • Sacn操作时为了批量扫描限定KEy值范围的用户数据。
  2. Scanner定位Region(读取顺序)
    • memstore
    • blockacache(每个Region Server只有一个)
    • hfile
2.5 Region 概念
  • 将一个表的数据按RowKey的范围划分为一个或多个子表,实现分布式存储
  • 每个子表在Region Server中被称为Region
  • 每一个Region都关联一个Key值范围,即一个使用StartKey和EndKey描述的区间,其实只需要记录StarKey就完事了
  • Region是HBase分布式存储的最基本单元
  • Region分为元数据Region以及用户Region两类
    • Meta Region记录了每一个User Region的路由信息

补充:hbase:meta表相关介绍

1. 基本介绍
  • HBase 0.96 以前
    • -root- 表位置信息存放在Zookeeper上,内容为meta的存放信息
    • .meta存放在regionserver上,存储用户表的region信息。
  • HBase 0.96以后
    • 移除root表,用hbase:meta 代表 .meta 表,hbase:meta表的存放信息直接存放在zookeeper的/hbase/meta-region-server
2. 表内容
2.1 hbase:meta 表结构

存储的是用户的表的region信息

Key:

代码语言:javascript复制
Region key的格式是:[table],[region start key],[region id]

Value:

代码语言:javascript复制
info:regioninfo: 序列化的当前region的HRegionInfo实例。

info:server:存储这个region的regionserver的server:port

info:serverstartcode:该Regionserver拥用该region的起始时间
2.2 数据访问流程
  • 0.9.6以前的版本

Client———>zookeeper———>-ROOT-(单region)—–>.META.————->用户表region

  • 0.9.6及以后的版本

Client———>zookeeper——–>hbase:meta———>用户表region

Client的会从Zookeeper找到hbase:meta的位置,然后扫描该表找到我们需要请求的region信息,直接跟存储该region的regionserver建立连接,请求数据,而不是经由master。这些信息会被客户端缓存,避免多次请求

3. Shell操作

Shell 命令操作

参考博客

  • HBase原理和设计
  • HBase技术原理
4. 预分区

默认情况下,创建一个表,hbase会为其自动分区,即Region Server会不断工作,导致Region Server负载过大,所以比较好的办法是根据业务提前对表进行分区,例如有5个region被多个Region Server管理,在插入数据的时候,会向5个region中分别插入,负载均衡

创建分区的方法:

hbase> create ‘ns1:t1’, ‘f1’, SPLITS => [‘10’, ‘20’, ‘30’, ‘40’]

​ hbase> create ‘t1’, ‘f1’, SPLITS => [‘10’, ‘20’, ‘30’, ‘40’] ​ hbase> create ‘t1’, ‘f1’, SPLITS_FILE => ‘splits.txt’, OWNER => ‘johndoe’ ​ hbase> create ‘t1’, {NAME => ‘f1’, VERSIONS => 5}, METADATA => { ‘mykey’ => ‘myvalue’ } ​ hbase> # Optionally pre-split the table into NUMREGIONS, using ​ hbase> # SPLITALGO (“HexStringSplit”, “UniformSplit” or classname) ​ hbase> create ‘t1’, ‘f1’, {NUMREGIONS => 15, SPLITALGO => ‘HexStringSplit’} ​ hbase> create ‘t1’, ‘f1’, {NUMREGIONS => 15, SPLITALGO => ‘HexStringSplit’, REGION_REPLICATION => 2, CONFIGURATION => {‘hbase.hregion.scan.loadColumnFamiliesOnDemand’ => ‘true’}} ​ hbase> create ‘t1’, {NAME => ‘f1’, DFS_REPLICATION => 1}

​ 如: ​ 1.create ‘logs’,’info’,SPLITS => [‘20181010’,’20181020’,’20181030’] ​ 2.指定分隔文件 ​ create ‘logs’,’info’,SPLITS => ‘opt/datas/logs_split.txt’ ​ 3.指定多少分区,十六进制字符串分割 ​ create ‘t1’, ‘f1’, {NUMREGIONS => 3, SPLITALGO => ‘HexStringSplit’}

0 人点赞