文章目录

  • 前言
  • 1. 数据模型
  • (1) NameSpace
  • (2) Table
  • (3) Row
  • (4) Column Family
  • (5) Cell
  • 2. HBASE架构
  • 2.1 基础架构
  • 2.2 RegionServer 架构
  • 2.3 写流程
  • 2.4 MemStore Flush
  • 2.5 读流程
  • 2.6 StoreFile Compaction
  • 2.7 Region Split (可能存在数据倾斜的问题,一般通过预分区手动)


前言

  HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库


1. 数据模型

In HBase, data is stored in tables, which have rows and columns. it can be helpful to think of an HBase table as a multi-dimensional map.

(1) NameSpace

  命名空间,类似于关系型数据库的database概念,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是hbase和default,hbase中存放的是HBase内置的表,default表是用户默认使用的命名空间
  命名空间的主要作用包括进行配额管理、安全管理(用户对命名空间和表的操作权限划分)

(2) Table

  类似于关系型数据库的表概念。不同的是,HBase定义表时只需要声明列族即可,不需要声明具体的列。这意味着,往HBase写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase能够轻松应对字段变更的场景

(3) Row

  HBase表中的每行数据都由一个RowKey和多个Column(列)组成,数据是按照RowKey的字典顺序存储的,并且查询数据时只能根据RowKey进行检索

(4) Column Family

  HBase中的每个列都由Column Family(列族)和Column Qualifier(列限定符)进行限定,如 info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义
注:

Physically, all column family members are stored together on the filesystem. Because tunings and storage specifications are done at the column family level, it is advised that all column family members have the same general access pattern and size characteristics.

(5) Cell

  由{rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元。cell中的数据全部是字节码形式存贮

注:
Time Stamp
  用于标识数据的不同版本(version),每条数据写入时,系统会自动为其加上该字段,其值为写入HBase的时间


2. HBASE架构

2.1 基础架构

架构角色:
1)Region Server
  Region Server为 Region的管理者,其实现类为HRegionServer,主要作用:操作数据:get, put, delete;操作Region:splitRegion、compactRegion
2)Master
  Master是所有Region Server的管理者,其实现类为HMaster,主要作用:操作表:create, delete, alter;操作RegionServer:分配regions到每个RegionServer,监控每个RegionServer的状态,负载均衡和故障转移
3)Zookeeper
  HBase通过Zookeeper实现master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等
4)HDFS
  HDFS为Hbase提供最终的底层数据存储服务,同时为HBase提供高可用的支持

hbase每个region默认大小 hbase region大小_Server

2.2 RegionServer 架构

1)StoreFile
  保存实际数据的物理文件,StoreFile以Hfile的形式存储在HDFS上。每个Store会有一个或多个StoreFile(HFile),数据在每个StoreFile中都是有序的
2)MemStore
  写缓存,由于HFile中的数据要求是有序的,所以数据是先存储在MemStore中,排好序后,等到达刷写时机才会刷写到HFile,每次刷写都会形成一个新的HFile
3)WAL
  由于数据要经MemStore排序后才能刷写到HFile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Ahead logfile的文件中,然后再写入MemStore中。所以在系统出现故障的时候,数据可以通过这个日志文件重建
4)BlockCache
  读缓存,每次查询出的数据会缓存在BlockCache中,方便下次查询

hbase每个region默认大小 hbase region大小_hbase_02

2.3 写流程

1)Client先访问zookeeper,获取hbase:meta表位于哪个Region Server;

2)访问对应的Region Server,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问;

scan 'hbase:meta'

hbase每个region默认大小 hbase region大小_数据_03


webui查看:

hbase每个region默认大小 hbase region大小_默认值_04

3)与目标Region Server进行通讯;

4)将数据顺序写入(追加)到WAL;

5)将数据写入对应的MemStore,数据会在MemStore进行排序;

6)向客户端发送ack;

7)等达到MemStore的刷写时机后,将数据刷写到HFile。

hbase每个region默认大小 hbase region大小_hbase每个region默认大小_05

2.4 MemStore Flush

1.Memstore级别
  当某个memstore的大小达到了hbase.hregion.memstore.flush.size(默认值128M),其所在region的所有memstore都会刷写

2.HRegion级别
  当Region中memstore的大小达到了hbase.hregion.memstore.flush.size(默认值128M)* hbase.hregion.memstore.block.multiplier(默认值4)时,会阻止继续往该memstore写数据

Without an upper-bound, memstore fills such that when it flushes the resultant flush files take a long time to compact or split, or worse, we OOME.

3.HRegionServer级别
  当region server中memstore的总大小达到java_heapsize*hbase.regionserver.global.memstore.size(默认值0.4)*hbase.regionserver.global.memstore.size.lower.limit(默认值0.95),region会按照其所有memstore的大小顺序(由大到小)依次进行刷写。直到region server中所有memstore的总大小减小到上述值以下

  当region server中memstore的总大小达到java_heapsize*hbase.regionserver.global.memstore.size(默认值0.4)时,会阻止继续往所有的memstore写数据

4.HLog级别
  当WAL文件的数量超过hbase.regionserver.max.logs,region会按照时间顺序依次进行刷写,直到WAL文件数量减小到hbase.regionserver.max.logs以下(该属性名已经废弃,现无需手动设置,最大值为32)

5.定期刷写
  到达自动刷写的时间,也会触发memstore flush。自动刷新的时间间隔由该属性进行配置hbase.regionserver.optionalcacheflushinterval(默认1小时) 指当前MemStore最后一次编辑的时间

6.手动刷写
  通过命令 flush

hbase每个region默认大小 hbase region大小_hbase_06

2.5 读流程

1)Client先访问zookeeper,获取hbase:meta表位于哪个Region Server

2)访问对应的Region Server,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问

3)与目标Region Server进行通讯;

4)分别在MemStore和Store File(HFile)中查询目标数据,并将查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不同的类型(Put/Delete)

5)将查询到的新的数据块(Block,HFile数据存储单元,默认大小为64KB)缓存到Block Cache(LRU算法 最近最少使用)

6)将合并后的最终结果返回给客户端

hbase每个region默认大小 hbase region大小_hbase每个region默认大小_07


hbase每个region默认大小 hbase region大小_默认值_08

2.6 StoreFile Compaction

  由于memstore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp)和不同类型(Put/Delete)有可能会分布在不同的HFile中,因此查询时需要遍历所有的HFile。为了减少HFile的个数,以及清理掉过期和删除的数据,会进行StoreFile Compaction。
  Compaction分为两种,分别是Minor Compaction和Major Compaction:
  Minor Compaction会将临近的若干个较小的HFile合并成一个较大的HFile,并清理掉部分过期和删除的数据
  Major Compaction会将一个Store下的所有的HFile合并成一个大HFile,并且会清理掉所有过期和删除的数据

Major Compaction生产环境中一般关闭,手动合并 compact命令

<property>
    <name>hbase.hregion.majorcompaction</name>
    <value>604800000</value>
    <description>Time between major compactions, expressed in milliseconds. Set to 0 to disable
      time-based automatic major compactions. User-requested and size-based major compactions will
      still run. This value is multiplied by hbase.hregion.majorcompaction.jitter to cause
      compaction to start at a somewhat-random time during a given window of time. The default value
      is 7 days, expressed in milliseconds. If major compactions are causing disruption in your
      environment, you can configure them to run at off-peak times for your deployment, or disable
      time-based major compactions by setting this parameter to 0, and run major compactions in a
      cron job or by another external mechanism.</description>
  </property>
    <property>
    <name>hbase.hregion.majorcompaction.jitter</name>
    <value>0.50</value>
    <description>A multiplier applied to hbase.hregion.majorcompaction to cause compaction to occur
      a given amount of time either side of hbase.hregion.majorcompaction. The smaller the number,
      the closer the compactions will happen to the hbase.hregion.majorcompaction
      interval.</description>
  </property>
    <property>
    <name>hbase.hstore.compactionThreshold</name>
    <value>3</value>
    <description> If more than this number of StoreFiles exist in any one Store
      (one StoreFile is written per flush of MemStore), a compaction is run to rewrite all
      StoreFiles into a single StoreFile. Larger values delay compaction, but when compaction does
      occur, it takes longer to complete.</description>
  </property>

hbase每个region默认大小 hbase region大小_Server_09

注:
  flush只清理内存中过期删除的数据,不会访问磁盘中的数据;

2.7 Region Split (可能存在数据倾斜的问题,一般通过预分区手动)

  默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的Region Server,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的Region Server
Region Split时机:
1.当1个region中的某个Store下所有StoreFile的总大小超过hbase.hregion.max.filesize,该Region就会进行拆分(0.94版本之前)。
2.当1个region中的某个Store下所有StoreFile的总大小超过Min(initialSize*R^3 ,hbase.hregion.max.filesize"),该Region就会进行拆分。其中initialSize的默认值为2*hbase.hregion.memstore.flush.size,R为当前Region Server中属于该Table的Region个数(0.94版本之后)

具体的切分策略为:

第一次split:1^3 * 256 = 256MB 第二次split:2^3 * 256 = 2048MB

第三次split:3^3 * 256 = 6912MB

第四次split:4^3 * 256 = 16384MB > 10GB,因此取较小的值10GB

后面每次split的size都是10GB

3.Hbase 2.0引入了新的split策略:如果当前RegionServer上该表只有一个Region,按照2 * hbase.hregion.memstore.flush.size分裂,否则按照hbase.hregion.max.filesize分裂

hbase每个region默认大小 hbase region大小_Server_10