HBase

4 篇文章 0 订阅
2 篇文章 0 订阅

1.HBase 概述

1.1 HBase 数据模型

In HBase, data is stored in tables, which have rows and columns. This is a terminology overlap with relational databases (RDBMSs), but this is not a helpful analogy. Instead, it can be helpful to think of an HBase table as a multi-dimensional map.

1.1.1 HBase 逻辑视图

  • NameSpace :命名空间,类似于关系型数据库的 DatabBase 概念,每个命名空间下有多个表。HBase 有两个自带的命名空间,分别是 hbase 和 default,hbase 中存放的是 HBase 内置的表,default 表是用户默认使用的命名空间。

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

  • table:表,一个表包含多行数据。

  • row:行,一行数据包含一个唯一标识rowkey、多个column以及对应的值。在HBase中,一张表中所有row都按照rowkey的字典序由小到大排序。

  • column:列,与关系型数据库中的列不同,HBase中的column由column family(列簇)以及qualifier(列名)两部分组成,两者中间使用":"相连。
    比如contents:html,其中contents为列簇,html为列簇下具体的一列。column family在表创建的时候需要指定,用户不能随意增减。
    一个column family下可以设置任意多个qualifier,因此可以理解为HBase中的列可以动态增加,理论上甚至可以扩展到上百万列。

  • timestamp:时间戳,每个cell在写入HBase的时候都会默认分配一个时间戳作为该cell的版本,当然,用户也可以在写入的时候自带时间戳。
    HBase支持多版本特性,即同一rowkey、column下可以有多个value存在,这些value使用timestamp作为版本号,版本越大,表示数据越新。

  • cell ,由五元组(row, column, timestamp, type, value) 唯一确定的单元,其中type表示Put/Delete这样的操作类型,timestamp代表这个cell的版本。
    这个结构在数据库中实际是以KV结构存储的,其中(row, column, timestamp, type)是K,value字段对应KV结构的V。

在这里插入图片描述

1.1.2 多维稀疏排序Map

  • 稀疏:稀疏性是HBase一个突出特点。 在其他数据库中,对于空值的处理一般都会填充null,而对于HBase,空值不需要任何填充。
    这个特性为什么重要?因为HBase的列在理论上是允许无限扩展的,对于成百万列的表来说,通常都会存在大量的空值,如果使用填充null的策略,势必会造成大量空间的浪费。因此稀疏性是HBase的列可以无限扩展的一个重要条件。

  • 排序:构成HBase的KV在同一个文件中都是有序的,但规则并不是仅仅按照rowkey排序,而是按照KV中的key进行排序——先比较rowkey,rowkey小的排在前面;
    如果rowkey相同,再比较column,即column family:qualifier,column小的排在前面;
    如果column还相同,再比较时间戳timestamp,即版本信息,timestamp大的排在前面。这样的多维元素排序规则对于提升HBase的读取性能至关重要。

  • 分布式:很容易理解,构成HBase的所有Map并不集中在某台机器上,而是分布在整个集群中。

1.1.4 物理视图

在这里插入图片描述

1.2. HBase体系架构

1.2.1 Catalog Tables

The catalog table hbase:meta exists as an HBase table and is filtered out of the HBase shell’s list command, but is in fact a table just like any other.

hbase:meta

The hbase:meta table (previously called .META.) keeps a list of all regions in the system, and the location of hbase:meta is stored in ZooKeeper.

The hbase:meta table structure is as follows:

Key

  • Region key of the format ([table],[region start key],[region id])

Values

  • info:regioninfo (serialized HRegionInfo instance for this region)
  • info:server (server:port of the RegionServer containing this region)
  • info:serverstartcode (start-time of the RegionServer process containing this region)

When a table is in the process of splitting, two other columns will be created, called info:splitA and info:splitB. These columns represent the two daughter regions. The values for these columns are also serialized HRegionInfo instances. After the region has been split, eventually this row will be deleted.

Startup Sequencing

First, the location of hbase:meta is looked up in ZooKeeper. Next, hbase:meta is updated with server and startcode values.

For information on region-RegionServer assignment, see Region-RegionServer Assignment.

1.2.2 Client

The HBase client finds the RegionServers that are serving the particular row range of interest. It does this by querying the hbase:meta table. See hbase:meta for details. After locating the required region(s), the client contacts the RegionServer serving that region, rather than going through the master, and issues the read or write request. This information is cached in the client so that subsequent requests (后续请求)need not go through the lookup process. Should a region be reassigned either by the master load balancer or because a RegionServer has died, the client will requery the catalog tables to determine the new location of the user region.( Master 负载或 RegionServer 宕机使Region重新分配, Client 将重新查询 catalog 表, 以确定 Region 位置)

HBase客户端访问数据行之前,首先需要通过元数据表定位目标数据所在RegionServer,之后才会发送请求到该RegionServer。同时这些元数据会被缓存在客户端本地,以方便之后的请求访问。如果集群RegionServer发生宕机或者执行了负载均衡等,从而导致数据分片发生迁移,客户端需要重新请求最新的元数据并缓存在本地。

1.2.2 ZooKeeper

A distributed Apache HBase installation depends on a running ZooKeeper cluster. All participating nodes and clients need to be able to access the running ZooKeeper ensemble. Apache HBase by default manages a ZooKeeper “cluster” for you. It will start and stop the ZooKeeper ensemble as part of the HBase start/stop process. You can also manage the ZooKeeper ensemble independent of HBase and just point HBase at the cluster it should use. To toggle HBase management of ZooKeeper, use the HBASE_MANAGES_ZK variable in conf/hbase-env.sh. This variable, which defaults to true, tells HBase whether to start/stop the ZooKeeper ensemble servers as part of HBase start/stop.

在HBase系统中,ZooKeeper扮演着非常重要的角色。

  • 实现Master高可用:通常情况下系统中只有一个Master工作,一旦Active Master由于异常宕机,ZooKeeper会检测到该宕机事件,并通过一定机制选举出新的Master,保证系统正常运转。
  • 管理系统核心元数据:比如,管理当前系统中正常工作的RegionServer集合,保存系统元数据表hbase:meta所在的RegionServer地址等。
  • 参与RegionServer宕机恢复:ZooKeeper通过心跳可以感知到RegionServer是否宕机,并在宕机后通知Master进行宕机处理。
  • 实现分布式表锁:HBase中对一张表进行各种管理操作(比如alter操作)需要先加表锁,防止其他用户对同一张表进行管理操作,造成表状态不一致。和其他RDBMS表不同,HBase中的表通常都是分布式存储,ZooKeeper可以通过特定机制实现分布式表锁。

1.2.3 Master

HMaster is the implementation of the Master Server. The Master server is responsible for monitoring all RegionServer instances in the cluster, and is the interface for all metadata changes. In a distributed cluster, the Master typically runs on the NameNode. J Mohamed Zahoor goes into some more detail on the Master Architecture in this blog posting, HBase HMaster Architecture .

Interface

The methods exposed by HMasterInterface are primarily metadata-oriented methods:

  • Table (createTable, modifyTable, removeTable, enable, disable)
  • ColumnFamily (addColumn, modifyColumn, removeColumn)
  • Region (move, assign, unassign) For example, when the Admin method disableTable is invoked, it is serviced by the Master server.
Master主要负责HBase系统的各种管理工作
  • 处理用户的各种管理请求,包括建表、修改表、权限操作、切分表、合并数据分片以及Compaction等。
  • 管理、监控集群中所有RegionServer,包括RegionServer中Region的负载均衡、RegionServer的宕机恢复以及Region的迁移等。
  • 清理过期日志以及文件,Master会每隔一段时间检查HDFS中HLog是否过期、HFile是否已经被删除,并在过期之后将其删除。

1.2.4 RegionServer

HRegionServer is the RegionServer implementation. It is responsible for serving and managing regions. In a distributed cluster, a RegionServer runs on a DataNode.

Interface

The methods exposed by HRegionRegionInterface contain both data-oriented and region-maintenance methods:

  • Data (get, put, delete, next, etc.)
  • Region (splitRegion, compactRegion, etc.) For example, when the Admin method majorCompact is invoked on a table, the client is actually iterating through all regions for the specified table and requesting a major compaction directly to each region.

RegionServer主要用来响应用户的IO请求,由WAL(HLog)、BlockCache以及多个Region构成。

  • WAL(HLog):HLog在HBase中有两个核心作用——其一,用于实现数据的高可靠性,HBase数据随机写入时,并非直接写入HFile数据文件,而是先写入缓存,再异步刷新落盘。为了防止缓存数据丢失,数据写入缓存之前需要首先顺序写入HLog。其二,用于实现HBase集群间主从复制,通过回放主集群推送过来的HLog日志实现主从复制。

  • BlockCache:HBase系统中的读缓存。客户端从磁盘读取数据之后通常会将数据缓存到系统内存中,后续访问同一行数据可以直接从内存中获取而不需要访问磁盘。

  • Region:数据表的一个分片,当数据表大小超过一定阈值就会“水平切分”,分裂为两个Region。Region是集群负载均衡的基本单位。通常一张表的Region会分布在整个集群的多台RegionServer上,一个RegionServer上会管理多个Region,当然,这些Region一般来自不同的数据表

  • HDFS:HBase底层依赖HDFS组件存储实际数据,包括用户数据文件、HLog日志文件等最终都会写入HDFS落盘。HDFS是Hadoop生态圈内最成熟的组件之一,数据默认三副本存储策略可以有效保证数据的高可靠性。HBase内部封装了一个名为DFSClient的HDFS客户端组件,负责对HDFS的实际数据进行读写访问。

在这里插入图片描述

HBase体系结构图
Block Cache

2. HBase 依赖服务

2.1 Zookeeper

一个分布式HBase集群的部署运行强烈依赖于ZooKeeper,在当前的HBase系统实现中,ZooKeeper扮演了非常重要的角色。
首先,在安装HBase集群时需要在配置文件conf/hbase-site.xml中配置与ZooKeeper相关的几个重要配置项,如下所示:

  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://nameservice1:8020/user/hbase</value>
  </property>

  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>$ZK_NODES</value>
  </property>
  <property>
    <name>hbase.superuser</name>
    <value>hbase,admin</value>
  </property>


  <property>
    <name>hbase.security.authorization</name>
    <value>true</value>
  </property>

  <property>
    <name>hbase.rpc.engine</name>
    <value>org.apache.hadoop.hbase.ipc.SecureRpcEngine</value>
  </property>
  <property>
    <name>hbase.coprocessor.region.classes</name>
    <value>org.apache.hadoop.hbase.security.access.AccessController</value>
  </property>

  <property>
    <name>hbase.coprocessor.master.classes</name>
    <value>org.apache.hadoop.hbase.security.access.AccessController</value>
  </property>
  
  <property>
    <name>zookeeper.znode.parent</name>
    <value>/hbase</value>
  </property>
  
  

HBase在ZooKeeper(${zookeeper.znode.parent} 所在zk目录下)上都存储的信息

  • /hbase/meta-region-server
    存储HBase集群hbase:meta元数据表所在的RegionServer访问地址。客户端读写数据首先会从此节点读取hbase:meta元数据的访问地址,将部分元数据加载到本地,根据元数据进行数据路由。

  • /hbase/master
    ActiveMasterManager 会在ZK中创建/hbase/master短暂节点,master将其信息记录到这个节点下, 如果是备份的master会在这里阻塞,直到这个节点为空

  • /hbase/backup-masters
    通常来说生产线环境要求所有组件节点都避免单点服务,HBase使用ZooKeeper的相关特性实现了Master的高可用功能。其中Master节点是集群中对外服务的管理服务器,
    backup-masters下的子节点是集群中的备份节点,一旦对外服务的主Master节点发生了异常,备Master节点可以通过选举切换成主Master,继续对外服务。需要注意的是备Master节点可以是一个,也可以是多个。

  • /hbase/table : 集群中所有表信息。

  • /hbase/region-in-transition
    在当前HBase系统实现中,迁移Region是一个非常复杂的过程。
    首先对这个Region执行unassign操作,将此Region从open状态变为off line状态(中间涉及PENDING_CLOSE、CLOSING以及CLOSED等过渡状态),再在目标RegionServer上执行assign操作,将此Region从off line状态变成open状态。
    这个过程需要在Master上记录此Region的各个状态。
    目前,RegionServer将这些状态通知给Master是通过ZooKeeper实现的,RegionServer会在region-in-transition中变更Region的状态,Master监听ZooKeeper对应节点,以便在Region状态发生变更之后立马获得通知,得到通知后Master再去更新Region在hbase:meta中的状态和在内存中的状态。

  • /hbase/table-lock
    HBase系统使用ZooKeeper相关机制实现分布式锁。HBase中一张表的数据会以Region的形式存在于多个RegionServer上,因此对一张表的DDL操作(创建、删除、更新等操作)通常都是典型的分布式操作。
    每次执行DDL操作之前都需要首先获取相应表的表锁,防止多个DDL操作之间出现冲突,这个表锁就是分布式锁。

  • /hbase/online-snapshot
    用来实现在线snapshot操作。表级别在线snapshot同样是一个分布式操作,需要对目标表的每个Region都执行snapshot,全部成功之后才能返回成功。
    Master作为控制节点给各个相关RegionServer下达snapshot命令,对应RegionServer对目标Region执行snapshot,成功后通知Master。Master下达snapshot命令、RegionServer反馈snapshot结果都是通过ZooKeeper完成的。

  • /hbase/replication : 用来实现HBase副本功能。

  • /hbase/rs : 集群中所有运行的RegionServer

2.2 HDFS

As HBase runs on HDFS (and each StoreFile is written as a file on HDFS), it is important to have an understanding of the HDFS Architecture especially in terms of how it stores files, handles failovers, and replicates blocks.

2.2.1 HDFS在HBase系统中扮演的角色

HBase使用HDFS存储所有数据文件,从HDFS的视角看,HBase就是它的客户端。这样的架构有几点需要说明:

  • HBase本身并不存储文件,它只规定文件格式以及文件内容,实际文件存储由HDFS实现。
  • HBase不提供机制保证存储数据的高可靠,数据的高可靠性由HDFS的多副本机制保证。
  • HBase-HDFS体系是典型的计算存储分离架构。这种轻耦合架构的好处是,一方面可以非常方便地使用其他存储替代HDFS作为HBase的存储方案;另一方面对于云上服务来说,
    计算资源和存储资源可以独立扩容缩容,给云上用户带来了极大的便利。

2.2.2 HBase在HDFS中的文件布局

  • .hbase-snapshot:snapshot文件存储目录。用户执行snapshot后,相关的snapshot元数据文件存储在该目录。
  • .tmp:临时文件目录,主要用于HBase表的创建和删除操作。表创建的时候首先会在tmp目录下执行,执行成功后再将tmp目录下的表信息移动到实际表目录下。
    表删除操作会将表目录移动到tmp目录下,一定时间过后再将tmp目录下的文件真正删除。
  • MasterProcWALs:存储Master Procedure过程中的WAL文件。Master Procedure功能主要用于可恢复的分布式DDL操作。
    在早期HBase版本中,分布式DDL操作一旦在执行到中间某个状态发生宕机等异常的情况时是没有办法回滚的,这会导致集群元数据不一致。
    Master Procedure功能使用WAL记录DDL执行的中间状态,在异常发生之后可以通过WAL回放明确定位到中间状态点,继续执行后续操作以保证整个DDL操作的完整性。
  • WALs:存储集群中所有RegionServer的HLog日志文件。
  • archive:文件归档目录。这个目录主要会在以下几个场景下使用。
    • 所有对HFile文件的删除操作都会将待删除文件临时放在该目录。
    • 进行Snapshot或者升级时使用到的归档目录。
    • Compaction删除HFile的时候,也会把旧的HFile移动到这里。
  • corrupt:存储损坏的HLog文件或者HFile文件。
  • data:存储集群中所有Region的HFile数据。

在这里插入图片描述

HBase 在HDFS中文件布局图

3. RegionServer的核心模块

RegionServer是HBase系统中最核心的组件,主要负责用户数据写入、读取等基础操作。RegionServer组件实际上是一个综合体系,包含多个各司其职的核心模块:HLog、MemStore、HFile以及BlockCache。

3.1 RegionServer内部结构

在这里插入图片描述

RegionServer 的内部结构

3.2 Region

Regions are the basic element of availability and distribution for tables, and are comprised of a Store per Column Family. The hierarchy of objects is as follows:

Table                    (HBase table)
    Region               (Regions for the table)
        Store            (Store per ColumnFamily for each Region for the table)
            MemStore     (MemStore for each Store for each Region for the table)
            StoreFile    (StoreFiles for each Store for each Region for the table)
                Block    (Blocks within a StoreFile within a Store for each Region for the table)

一个RegionServer由一个HLog、一个BlockCache以及多个Region组成。

其中,

  • HLog 用来保证数据写入的可靠性;
  • BlockCache可以将数据块缓存在内存中以提升数据读取性能
  • Region是HBase中数据表的一个数据分片,一个RegionServer上通常会负责多个Region的数据读写。一个Region由多个Store组成,每个Store存放对应列簇的数据,比如一个表中有两个列簇,这个表的所有Region就都会包含两个Store。每个Store包含一个MemStore和多个HFile,用户数据写入时会将对应列簇数据写入相应的MemStore,一旦写入数据的内存大小超过设定阈值,系统就会将MemStore中的数据落盘形成HFile文件。
  • HFile存放在HDFS上,是一种定制化格式的数据存储文件,方便用户进行数据读取。

3.2.1 Region-RegionServer Assignment

Region Load Balancing
  • Balancer

The balancer is a periodic operation which is run on the master to redistribute regions on the cluster. It is configured via hbase.balancer.period and defaults to 300000 (5 minutes).

  • LoadBalancer

Periodically, and when there are no regions in transition, a load balancer will run and move regions around to balance the cluster’s load. See Balancer for configuring this property.

3.2.2 Region-RegionServer Locality

3.2.3 Region Splits

3.2.4 Online Region Merges

3.2 HLog

先看一下官网(Version3.0.0)的描述

Purpose

The Write Ahead Log (WAL) records all changes to data in HBase, to file-based storage. Under normal operations, the WAL is not needed because data changes move from the MemStore to StoreFiles. However, if a RegionServer crashes or becomes unavailable before the MemStore is flushed, the WAL ensures that the changes to the data can be replayed. If writing to the WAL fails, the entire operation to modify the data fails.

HBase uses an implementation of the WAL interface. Usually, there is only one instance of a WAL per RegionServer. An exception is the RegionServer that is carrying hbase:meta; the meta table gets its own dedicated WAL. The RegionServer records Puts and Deletes to its WAL, before recording them these Mutations MemStore for the affected Store.

说明:

WAL是以文件形式记录HBase所有的数据更新。在常规操作下不需要WAL,因为数据会从MemStore flush 到StoreFile。然而,如果MemStore flush之前,RegionServer崩溃或者不可用 ,则WAL确保可以重播对数据所做的更改。如果WAL写失败, 则整个更新操作失败。

通常,每个RegionServer 只有一个 WAL实例。

The HLog

Prior to 2.0, the interface for WALs in HBase was named HLog. In 0.94, HLog was the name of the implementation of the WAL. You will likely find references to the HLog in documentation tailored to these older versions.

HLog 文件结构

  1. 每个RegionServer拥有一个 HLog(默认只有1个,1.1版本可以开启MultiWAL功能,允许多个HLog)。每个HLog是多个Region共享的,图中Region A、Region B和Region C共享一个HLog文件。

  2. HLog中,日志单元WALEntry(图中小方框)表示一次行级更新的最小追加单元,它由HLogKey和WALEdit两部分组成,其中HLogKey由table name、region name以及sequenceid等字段构成。

在这里插入图片描述

HLog 文件结构

HLog 文件存储

/hbase/WALs存储当前还未过期的日志;/hbase/oldWALs存储已经过期的日志。

/hbase/WALs目录下通常会有多个子目录,每个子目录代表一个对应的RegionServer。以hbase17.xj.bjbj.org,60020,1505980274300为例,hbase17.xj.bjbj.org表示对应的RegionServer域名,60020为端口号,1505980274300为目录生成时的时间戳。每个子目录下存储该RegionServer内的所有HLog文件

WAL 在HDFS上的分布可看出,每个RegionServer 只有一个 WAL

在这里插入图片描述

WAL 在HDFS 上的分布

HLog 生命周期

在这里插入图片描述

HLog 生命周期
  • HLog构建:HBase的任何写入(更新、删除)操作都会先将记录追加写入到HLog文件中。
  • HLog滚动:HBase后台启动一个线程,每隔一段时间(由参数’hbase.regionserver.logroll.period’决定,默认1小时)进行日志滚动。日志滚动会新建一个新的日志文件,接收新的日志数据。日志滚动机制主要是为了方便过期日志数据能够以文件的形式直接删除。
  • HLog失效:写入数据一旦从MemStore中落盘,对应的日志数据就会失效。为了方便处理,HBase中日志失效删除总是以文件为单位执行。查看某个HLog文件是否失效只需确认该HLog文件中所有日志记录对应的数据是否已经完成落盘,如果日志中所有日志记录已经落盘,则可以认为该日志文件失效。一旦日志文件失效,就会从WALs文件夹移动到oldWALs文件夹。注意此时HLog并没有被系统删除。
  • HLog删除:Master后台会启动一个线程,每隔一段时间(参数’hbase.master.cleaner.interval’,默认1分钟)检查一次文件夹oldWALs下的所有失效日志文件,确认是否可以删除,确认可以删除之后执行删除操作。确认条件主要有两个:
    • 该HLog文件是否还在参与主从复制。对于使用HLog进行主从复制的业务,需要继续确认是否该HLog还在应用于主从复制。
    • 该HLog文件是否已经在OldWALs目录中存在10分钟。为了更加灵活地管理HLog生命周期,系统提供了参数设置日志文件的TTL(参数’hbase.master.logcleaner.ttl’,默认10分钟),默认情况下oldWALs里面的HLog文件最多可以再保存10分钟。

3.3 Store

A Store hosts a MemStore and 0 or more StoreFiles (HFiles). A Store corresponds to a column family for a table for a given region.

3.3.1 MemStore

The MemStore holds in-memory modifications to the Store. Modifications are Cells/KeyValues. When a flush is requested, the current MemStore is moved to a snapshot and is cleared. HBase continues to serve edits from the new MemStore and backing snapshot until the flusher reports that the flush succeeded. At this point, the snapshot is discarded. Note that when the flush happens, MemStores that belong to the same region will all be flushed.

HBase系统中一张表会被水平切分成多个Region,每个Region负责自己区域的数据读写请求。水平切分意味着每个Region会包含所有的列簇数据,HBase将不同列簇的数据存储在不同的Store中,每个Store由一个MemStore和一系列HFile组成

在这里插入图片描述

Region 结构组成

3.3.2 MemStore Flush

3.4 HFile

3.4.1 HFile 逻辑结构

在这里插入图片描述

HFile 逻辑结构

HFile文件主要分为4个部分:Scanned block部分、Non-scanned block部分、Load-on-open部分和Trailer。

  • Scanned Block部分:顾名思义,表示顺序扫描HFile时所有的数据块将会被读取。这个部分包含3种数据块:Data Block,Leaf Index Block以及Bloom Block。其中Data Block中存储用户的KeyValue数据,Leaf Index Block中存储索引树的叶子节点数据,BloomBlock中存储布隆过滤器相关数据。
  • Non-scanned Block部分:表示在HFile顺序扫描的时候数据不会被读取,主要包括MetaBlock和Intermediate Level Data Index Blocks两部分。
  • Load-on-open部分:这部分数据会在RegionServer打开HFile时直接加载到内存中,包括FileInfo、布隆过滤器MetaBlock、Root Data Index和Meta IndexBlock。
  • Trailer部分:这部分主要记录了HFile的版本信息、其他各个部分的偏移值和寻址信息。

3.4.2 HFile文件查看工具

>$ hbase hfile 
usage: HFile [-a] [-b] [-e] [-f <arg> | -r <arg>] [-h] [-k] [-m] [-p]
       [-s] [-v] [-w <arg>]
 -a,--checkfamily         Enable family check
 -b,--printblocks         Print block index meta data
 -e,--printkey            Print keys
 -f,--file <arg>          File to scan. Pass full-path; e.g.
                          hdfs://a:9000/hbase/hbase:meta/12/34
 -h,--printblockheaders   Print block headers for each block.
 -k,--checkrow            Enable row order check; looks for out-of-order
                          keys
 -m,--printmeta           Print meta data of file
 -p,--printkv             Print key/value pairs
 -r,--region <arg>        Region to scan. Pass region name; e.g.
                          'hbase:meta,,1'
 -s,--stats               Print statistics
 -v,--verbose             Verbose output; emits file and meta data
                          delimiters
 -w,--seekToRow <arg>     Seek to this row and print all the kvs for this
                          row only

3.5 BlockCache

4. HBase 读写流程

4.1 写流程

在这里插入图片描述

HBase 写流程

从整体架构的视角来看,写入流程可以概括为三个阶段。

  • 客户端处理阶段:客户端将用户的写入请求进行预处理,并根据集群元数据定位写入数据所在的RegionServer,将请求发送给对应的RegionServer
  • Region写入阶段:RegionServer接收到写入请求之后将数据解析出来,首先写入WAL,再写入对应Region列簇的MemStore。
  • MemStore Flush阶段:当Region中MemStore容量超过一定阈值,系统会异步执行f lush操作,将内存中的数据写入文件,形成HFile。

4.1.1 客户端处理阶段

  1. 用户提交put请求后,HBase客户端会将写入的数据添加到本地缓冲区中,符合一定条件就会通过AsyncProcess异步批量提交。HBase默认设置autoflush=true,表示put请求直接会提交给服务器进行处理;用户可以设置autoflush=false,这样,put请求会首先放到本地缓冲区,等到本地缓冲区大小超过一定阈值(默认为2M,可以通过配置文件配置)之后才会提交。很显然,后者使用批量提交请求,可以极大地提升写入吞吐量,但是因为没有保护机制,如果客户端崩溃,会导致部分已经提交的数据丢失。

  2. 在提交之前,HBase会在元数据表hbase:meta中根据rowkey找到它们归属的RegionServer,这个定位的过程是通过HConnection的locateRegion方法完成的。如果是批量请求,还会把这些rowkey按照HRegionLocation 分组,不同分组的请求意味着发送到不同的RegionServer,因此每个分组对应一次RPC请求。

在这里插入图片描述

写入流程各组件交互图
  • 客户端根据写入的表以及rowkey在**元数据缓存(Meta Cache)**中查找,如果能够查找出该rowkey所在的RegionServer以及Region,就可以直接发送写入请求(携带Region信息)到目标RegionServer。

  • 如果客户端缓存中没有查到对应的rowkey信息,需要首先到ZooKeeper上/hbase/meta-region-server节点查找HBase元数据表所在的RegionServer。向hbase:meta所在的RegionServer发送查询请求,在元数据表中查找rowkey所在的RegionServer以及Region信息。客户端接收到返回结果之后会将结果缓存到本地,以备下次使用。

  • 客户端根据rowkey相关元数据信息将写入请求发送给目标RegionServer,Region Server接收到请求之后会解析出具体的Region信息,查到对应的Region对象,并将数据写入目标Region的MemStore中。

  1. HBase会为每个HRegionLocation构造一个远程RPC请求MultiServerCallable,并通过rpcCallerFactory. newCaller()执行调用。将请求经过Protobuf序列化后发送给对应的RegionServer。

4.1.2 Region写入阶段

在这里插入图片描述

Region写入流程

源码org.apache.hadoop.hbase.regionserver.HRegion Region的 8个写入流程:

  • Acquire locks :HBase中使用行锁保证对同一行数据的更新都是互斥操作,用以保证更新的原子性,要么更新成功,要么更新失败

    // STEP 1. Try to acquire as many locks as we can and build mini-batch of operations with
    // locked rows
    
  • Update LATEST_TIMESTAMP timestamps :更新所有待写入(更新)KeyValue的时间戳为当前系统时间.

    // STEP 2. Update mini batch of all operations in progress with  LATEST_TIMESTAMP timestamp
    // We should record the timestamp only after we have acquired the rowLock,
    // otherwise, newer puts/deletes are not guaranteed to have a newer timestamp
    
  • Build WAL edit :HBase使用WAL机制保证数据可靠性,即首先写日志再写缓存,即使发生宕机,也可以通过恢复HLog还原出原始数据。该步骤就是在内存中构建WALEdit对象,为了保证Region级别事务的写入原子性,一次写入操作中所有KeyValue会构建成一条WALEdit记录。

    // STEP 3. Build WAL edit
    
  • Append WALEdit To WAL :将步骤3中构造在内存中的WALEdit记录顺序写入HLog中,此时不需要执行sync操作。当前版本的HBase使用了disruptor实现了高效的生产者消费者队列,来实现WAL的追加写入操作。

    // STEP 4. Append the WALEdits to WAL and sync.
    
  • Write back to MemStore:写入WAL之后再将数据写入MemStore

    // STEP 5. Write back to memStore
    // NOTE: writeEntry can be null here
    
  • Release row locks:释放行锁。

          releaseRowLocks(acquiredRowLocks);
    
  • Sync wal :HLog真正sync到HDFS,在释放行锁之后执行sync操作是为了尽量减少持锁时间,提升写性能。如果sync失败,执行回滚操作将MemStore中已经写入的数据移除。

  • 结束写事务:此时该线程的更新操作才会对其他读请求可见,更新才实际生效。

4.1.3 MemStore Flush

A MemStore flush can be triggered under any of the conditions listed below. The minimum flush unit is per region, not at individual MemStore level.

  1. When a MemStore reaches the size specified by hbase.hregion.memstore.flush.size, all MemStores that belong to its region will be flushed out to disk.

  2. When the overall MemStore usage reaches the value specified by hbase.regionserver.global.memstore.upperLimit, MemStores from various regions will be flushed out to disk to reduce overall MemStore usage in a RegionServer。

The flush order is based on the descending order of a region’s MemStore usage.

Regions will have their MemStores flushed until the overall MemStore usage drops to or slightly below hbase.regionserver.global.memstore.lowerLimit.

  1. When the number of WAL log entries in a given region server’s WAL reaches the value specified in hbase.regionserver.max.logs, MemStores from various regions will be flushed out to disk to reduce the number of logs in the WAL.

The flush order is based on time.

Regions with the oldest MemStores are flushed first until WAL count drops below hbase.regionserver.max.logs.

MemStore Flush 的最小执行单元是 Region,而非 MemStore 级别,

Flush 触发时机

  • MemStore级别限制:当Region中任意一个MemStore的大小达到了上限(hbase.hregion.memstore.f lush.size,默认128MB),会触发整个Region 的MemStore刷新

  • Region级别限制:当Region中所有MemStore的大小总和达到了上限(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size),会触发MemStore刷新。

  • RegionServer级别限制:当RegionServer中MemStore的大小总和超过

    hbase.regionserver.global.memstore.size.lower.limit*hbase.regionserver.global.memstore.size,RegionServer开始强制执行flush,先flush MemStore最大的Region,再flush次大的,依次执行。如果此时写入吞吐量依然很高,导致总MemStore大小超过高水位阈值hbase.regionserver.global.memstore.size,RegionServer会阻塞更新并强制执行flush,直至总MemStore大小下降到低水位阈值。

  • 当一个RegionServer中HLog数量达到上限(可通过参数hbase.regionserver.maxlogs配置)时,系统会选***取最早的HLog对应的一个或多个Region进行f lush***。

  • HBase定期刷新MemStore :默认周期为1小时,确保MemStore不会长时间没有持久化。为避免所有的MemStore在同一时间都进行f lush而导致的问题,定期的f lush操作有一定时间的随机延时。

  • 手动执行f lush :用户可以通过shell命令flush 'tablename'或者flush 'regionname'分别对一个表或者一个Region进行f lush。

Flush执行流程:为了减少f lush过程对读写的影响,HBase采用了类似于两阶段提交的方式,将整个f lush过程分为三个阶段。

  • prepare阶段 :遍历当前Region中的所有MemStore,将MemStore中当前数据集CellSkipListSet(内部实现采用ConcurrentSkipListMap)做一个快照snapshot,然后再新建一个CellSkipListSet接收新的数据写入。prepare阶段需要添加updateLock对写请求阻塞,结束之后会释放该锁。因为此阶段没有任何费时操作,因此持锁时间很短。
  • flush阶段:遍历所有MemStore,将prepare阶段生成的snapshot持久化为临时文件,临时文件会统一放到目录.tmp下。这个过程因为涉及磁盘IO操作,因此相对比较耗时。
  • commit阶段:遍历所有的MemStore,将f lush阶段生成的临时文件移到指定的ColumnFamily目录下,针对HFile生成对应的storef ile和Reader,把storef ile添加到Store的storef iles列表中,最后再清空prepare阶段生成的snapshot。

生成HFile

  • 构建"Scanned Block"部分
  • 构建Bloom Block
  • 构建Data Block
  • 构建Leaf Index Block
  • 构建Bloom Block Index

HFile生成基本流程总结:f lush阶段生成HFile和Compaction阶段生成HFile的流程完全相同,不同的是,f lush读取的是MemStore中的KeyValue写成HFile,而Compaction读取的是多个HFile中的KeyValue写成一个大的HFile,**KeyValue来源不同。**KeyValue数据生成HFile,首先会构建Bloom Block以及Data Block,一旦写满一个Data Block就会将其落盘同时构造一个Leaf IndexEntry,写入Leaf Index Block,直至Leaf Index Block写满落盘。实际上,每写入一个KeyValue就会动态地去构建"Scanned Block"部分,等所有的KeyValue都写入完成之后再静态地构建"Non-scanned Block"部分、"Load on open"部分以及"Trailer"部分。

MemStore Flush对业务的影响

  • 在实践过程中,flush操作的不同触发方式对用户请求影响的程度不尽相同。正常情况下,大部分MemStore Flush操作都不会对业务读写产生太大影响。比如系统定期刷新MemStore、手动执行flush操作、触发MemStore级别限制、触发HLog数量限制以及触发Region级别限制等,这几种场景只会阻塞对应Region上的写请求,且阻塞时间较短。

  • 然而,一旦触发RegionServer级别限制导致flush,就会对用户请求产生较大的影响。在这种情况下,系统会阻塞所有落在该RegionServer上的写入操作,直至MemStore中数据量降低到配置阈值内。

4.1.4 HBase 写数据主要流程

  1. Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。
  2. 访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey,查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 region 信息以及 meta 表的位置信息缓存在客户端的 MetaCache,方便下次访问。
  3. 与目标 Region Server 进行通讯;
  4. 将数据顺序写入(追加)到 WAL;
  5. 将数据写入对应的 MemStore,数据会在 MemStore 进行排序;
  6. 向客户端发送 ack;
  7. 等达到 MemStore 的刷写时机后,将数据刷写到 HFile。

4.2 BulkLoad 功能

4.3 读取流程

在这里插入图片描述

HBase 读取流程

HBase之读取数据流程

HBase 读取数据主要流程

  1. Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 RegionServer。
  2. 访问对应的 RegionServer,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey,查询出目标数据位于哪个 RegionServer中的哪个 Region 中。并将该 table 的 region 信息以及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。
  3. 与目标 Region Server 进行通讯;
  4. 分别在 Block Cache(读缓存),MemStore 和 Store File(HFile)中查询目标数据,并将查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不同的类型(Put/Delete)。
  5. 将从文件中查询到的数据块(Block,HFile 数据存储单元,默认大小为 64KB)缓存到Block Cache。
  6. 将合并后的最终结果返回给客户端。

4.4 Coprocessor

5. Compaction

为了提高读取效率,LSM树体系架构设计了一个非常重要的模块——Compaction。Compaction核心功能是将小文件合并成大文件,提升读取效率。

5.1 Compaction 基本原理

Compaction是从一个Region的一个Store中选择部分HFile文件进行合并。合并原理是,先从这些待合并的数据文件中依次读出KeyValue,再由小到大排序后写入一个新的文件。之后,这个新生成的文件就会取代之前已合并的所有文件对外提供服务。

img
Store File Compaction

HBase根据合并规模将Compaction分为两类:Minor CompactionMajor Compaction

  • Minor Compaction是指选取部分小的、相邻的HFile,将它们合并成一个更大的HFile。
  • Major Compaction是指将一个Store中所有的HFile合并成一个HFile,这个过程还会完全清理三类无意义数据被删除的数据TTL过期数据版本号超过设定版本号的数据

Compaction有以下核心作用:

  • 合并小文件,减少文件数,稳定随机读延迟。
  • 提高数据的本地化率。地化率越高,在HDFS上访问数据时延迟就越小;相反,本地化率越低,访问数据就可能大概率需要通过网络访问,延迟必然会比较大
  • 清除无效数据,减少数据存储量。

Compaction合并小文件的同时会将落在远程DataNode上的数据读取出来重新写入大文件,合并后的大文件在当前DataNode节点上有一个副本,因此可以提高数据的本地化率。极端情况下,Major Compaction可以将当前Region的本地化率提高到100%。这也是最常用的一种提高数据本地化率的方法。

Compaction在执行过程中有个比较明显的副作用:Compaction 操作重写文件会带来很大的带宽压力以及短时间IO压力。这点比较容易理解,要将小文件的数据读出来需要IO,很多小文件数据跨网络传输需要带宽,读出来之后又要写成一个大文件,因为是三副本写入,必然需要网络开销,当然写入IO开销也避免不了。

Compaction操作是所有LSM树结构数据库所特有的一种操作,它的核心操作批量将大量小文件合并成大文件用以提高读取性能。另外,Compaction是有副作用的,它在一定程度上消耗系统资源,进而影响上层业务的读取响应

在这里插入图片描述

Compaction 执行流程

5.1.1 Compaction触发时机

HBase中触发Compaction的时机有很多,最常见的时机有如下三种:MemStore Flush后台线程周期性检查手动触发

  • MemStore Flush

应该说Compaction操作的源头来自f lush操作,MemStore Flush会产生HFile文件,文件越来越多就需要compact执行合并。因此在每次执行完f lush操作之后,都会对当前Store中的文件数进行判断,一旦Store中总文件数大于hbase.hstore.compactionThreshold,就会触发Compaction。

Compaction都是以Store为单位进行的,而在f lush触发条件下,整个Region的所有Store都会执行compact检查,所以一个Region有可能会在短时间内执行多次Compaction。

  • 后台线程周期性检查

RegionServer会在后台启动一个线程CompactionChecker,定期触发检查对应Store是否需要执行Compaction,检查周期为 ${hbase.server.thread.wakefrequency} * ${hbase.server.compactchecker.interval.multiplier}

默认在7天左右就会执行一次MajorCompaction。用户如果想禁用Major Compaction,需要将参数hbase.hregion.majorcompaction设为0。

  • 手动触发

手动触发Compaction大多是为了执行Major Compaction

使用手动触发Major Compaction的原因通常有三个:

  1. 为很多业务担心自动MajorCompaction影响读写性能,因此会选择低峰期手动触发;

  2. 用户在执行完alter操作之后希望立刻生效,手动触发Major Compaction;

  3. HBase管理员发现硬盘容量不够时手动触发Major Compaction,删除大量过期数据

5.1.2 待合并HFile集合选择策略

  • RatioBasedCompactionPolicy:

从老到新逐一扫描所有候选文件,满足其中条件之一便停止扫描:

1)当前文件大小<比当前文件新的所有文件大小总和* ratio。其中ratio是一个可变的比例,在高峰期ratio为1.2,非高峰期ratio为5,也就是非高峰期允许compact更大的文件。HBase允许用户配置参数hbase.offpeak.start.hourhbase.offpeak.end.hour设置高峰期时间段。

2)当前所剩候选文件数<=hbase.store.compaction.min(默认为3)。

停止扫描后,待合并文件就选择出来了,即当前扫描文件以及比它更新的所有文件。

  • ExploringCompactionPolicy

待合并文件数最多或者待合并文件数相同的情况下文件较小,这样有利于减少Compaction带来的IO消耗

5.2 Compaction 高级策略

6. 负载均衡

6.1 Region 迁移

6.2 Region 合并

[hbase优化之region合并和压缩](https://www.cnblogs.com/feng-bigdata/p/8488289.html)

HBASE操作:(一般先合并region然后再压缩)

一 、Region合并: merge_region 'regionname1','regionname2' ,'true'–true代表强制合并,一般要加上

一般要是将小文件根据配置的最大上限进行合并,合并后最好清理一下hdfs

merge_region 之前

在这里插入图片描述
merge 一次

```merge_region ‘8e7db63a6bdc48f66a2914ee631e1228’, ‘f0de56b943cf83b253384d9b23ebc4cb’``

在这里插入图片描述

merge 两次

merge_region 'ea3edde9b9a43a10d29f14886ccb8d5f', '418ab0c241ca53b614b07597c5d81814'

在这里插入图片描述

6.3 Region 分裂

  • before split

在这里插入图片描述

在这里插入图片描述

  • split-step-1

在这里插入图片描述

split 过一段时间之后,原来的HFile文件才会被删除,通过命令hfile -p -f hfile可以看到不同region下的数据已经根据splitKey 进行了切分

6.4 HBase负载均衡的应用

7. HBase 高级

7.1 Flush 流程

7.2 Compact 流程

7.3 Split 流程

7.4 高可用

HBase可用性分析与高可用实践

HBase 高可用 :zookeeper + conf/backup-masters

7.5 预分区

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> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
hbase> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit', REGION_REPLICATION => 2, CONFIGURATION => {'hbase.hregion.scan.loadColumnFamiliesOnDemand' => 'true'}}

7.6 RowKey 设计

8. 默认配置说明

configDescriptionDefaultDescription-cn
hbase.hregion.max.filesizeMaximum HFile size. If the sum of the sizes of a region’s HFiles has grown to exceed this value, the region is split in two.10737418240(10G)当1个region中的某个Store下所有StoreFile的总大小超过hbase.hregion.max.filesize,该 Region 就会进行拆分
hbase.hregion.memstore.flush.sizeMemstore will be flushed to disk if size of the memstore exceeds this number of bytes. Value is checked by a thread that runs every hbase.server.thread.wakefrequency.134217728Memstore 被 flush 到磁盘HFile 的内存大小
hbase.hregion.memstore.block.multiplierBlock updates if memstore has hbase.hregion.memstore.block.multiplier times hbase.hregion.memstore.flush.size bytes. Useful preventing runaway memstore during spikes in update traffic. 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.4

8. 面试

聊聊HBase

读流程

写流程

HLog写入失败了怎么办 : 如果WAL写失败, 则整个更新操作失败。

如果Region挂了怎么办,那怎么恢复呢?

MemStore刷不到HFile里怎么办?

能在仔细介绍一下HBase的整体架构吗

Master干什么的,读取、写入操作具体指什么?

9. 其他

9.1 数据真正的删除时间

1.flush: 删除未被刷写的被覆盖或有删除标记的数据。删除标记不会删,因为不知道hdfs中是否有被此删除标记作用的数据。

flush : 如果有DeleteColumn标记,不管该 column family 有多大的VERSION,flush 之后只保留 DeleteColumn;如果没有DeleteColumn 标记,flush 之后 ,HFile 中会保留 VERSION 数量的 数据,

2.majorCompact: 多个文件加载到内存,将一个 Store 下的所有的 HFile 合并成一个大 HFile,并且会清理掉过期和有删除标记的数据。数据删除完毕后再删除删除标记。

URL

HBase官网

HBase官方文档

一条数据的HBase之旅,简明HBase入门教程-Write全流程

扎心了,老铁-HBase

扎心了,老铁

有态度的HBase/Spark/BigData

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值