作者:芬飞满天2011 | 来源:互联网 | 2023-09-16 19:48
HBase 体系结构来源于谷歌的 BigTable 论文,是典型的 Master-Slave 模型。系统中有一个管理集群的 Master 节点以及大量实际服务用户读写的 RegionServer 节点。除此之外,HBase 中所有数据最终都存储在 HDFS 系统中,这与 BigTable 实际数据存储在 GFS 中相对应;系统中还有一个 ZooKeeper 节点,协助 Master 对集群进行管理。
HBase 体系结构如下图所示:
1. HBase 客户端
HBase 客户端(Client)提供了 Shell 命令行接口、原生 Java API 编程接口、Thrift/REST API 编程接口以及 MapReduce 编程接口。HBase 客户端支持所有常见的 DML 操作以及 DDL 操作,即数据的增删改查和表的日常维护等。其中 Thrift/REST API 主要用于支持非 Java 的上层业务需求,MapReduce 接口主要用于批量数据导入以及批量数据读取。
HBase 客户端访问数据行之前,首先需要通过元数据表定位目标数据所在 RegionServer,之后才会发送请求到该 RegionServer。同时这些元数据会被缓存在客户端本地,以方便之后的请求访问。如果集群 RegionServer 发生宕机或者执行了负载均衡等,从而导致数据分片发生迁移,客户端需要重新请求最新的元数据并缓存在本地。
2. Zookeeper
在 HBase 系统中,ZooKeeper 扮演着非常重要的角色。
实现 Master 高可用:通常情况下系统中只有一个 Master 工作,一旦 Active Master 由于异常宕机,ZooKeeper 会检测到该宕机事件,并通过一定机制选举出新的 Master,保证系统正常运行。
管理系统核心元数据:比如,管理当前系统中正常工作的 RegionServer 集合,保存系统元数据表 hbase:meta 所在的 RegionServer 地址等。
参与 RegionServer 宕机恢复:ZooKeeper 通过心跳可以感知到 RegionServer 是否宕机,并在宕机后通知 Master 进行宕机处理。
实现分布式表锁:HBase 中对一张表进行各种管理操作(比如 alter 操作)需要先加表锁,防止其他用户对同一张表进行管理操作,造成表状态不一致。与其他的 RDBMS 表不同,HBase 中的表通常是分布式存储,ZooKeeper 可以通过特定机制实现分布式表锁。
3. Master
Master 主要负责 HBase 系统的各种管理工作:
处理用户的各种管理请求,包括建表、修改表、权限操作、切分表、合并数据分片以及 Compaction 等。
管理集群中所有 RegionServer,包括 RegionServer 中的 Region 的负载均衡、RegionServer 的宕机恢复以及 Region 的迁移等。
清理过期日志以及文件,Master 会每隔一段时间检查 HDFS 中 HLog 是否过期、HFile 是否已经被删除,并在过期之后将其删除。
4. RegionServer
RegionServer 主要用来响应用户的 IO 请求,是 HBase 中最核心的模块,由 WAL(HLog)、BlockCache 以及多个 Region 构成。
WAL(HLog):HLog 在 HBase 中有两个核心作用:
BlockCache:HBase 系统中的读缓存。客户端从磁盘读取数据之后通常会将数据缓存到系统内存中,后续访问同一行数据可以直接从内存中获取而不需要访问磁盘。对于带有大量热点读的业务请求来说,缓存机制会带来极大的性能提升。BlockCache 缓存对象是一系列 Block 块,一个 Block 默认是为 64k,由物理上相邻的多个 KV 数据组成。BlockCache 同时利用了空间局部性和时间局部性原理,前者表示最近将读取的 KV 数据很可能与当前读取到的 KV 数据在地址上是邻近的,缓存单位是 Block(块)而不是单个 KV 就可以实现空间局部性;后者表示一个 KV 数据正在被访问,那么近期她还可能再次被访问。当前 BlockCache 主要有两种实现 LRUBlockCache 和 BucketCache,前者实现相对简单,而后者在 GC 优化方面有明显的提升。
Region : 数据表的一个分片,当数据表大小超过一定阈值就会”水平切分“,分裂为两个 Region。Region 是集群负载均衡的基本单位。通常一张表的 Region 会分布在整个集群的多台 RegionServer 上,一个 RegionServer 上会管理多个 Region,当然,这些 Region 一般来自不同的数据表。一个 Region 由一个或者多个 Store 组成,Store 的个数取决于表中列族(column family)的个数,多少个列族就有多少个 Store。HBase 中,每个列族的数据都集中存放在一起形成一个存储单元 Store,因此建议将具有相同 IO 特性的数据设置在同一个列族中。每个 Store 由一个 MemStore 和一个或者多个 HFile 组成。MemStore 称为写缓存,用户写入数据时首先会写到 MemStore,当 MemStore 写满之后(缓存数据超过阈值,默认128M)系统会异步地将数据 flush 成一个 HFile 文件。显然,随着数据不断写入,HFile 文件会越来越多,当 HFile 文件数超过一定阈值之后系统将会执行 Compact 操作,将这些小文件通过一定策略合并成一个或多个大文件。
5. HDFS
HBase 底层依赖 HDFS 组件存储实际数据,包括用户数据文件、HLog 日志文件等最终都会写入 HDFS 落盘。HDFS 是 Hadoop 生态圈内最成熟的组件之一,数据默认三副本存储策略可以有效保证数据的高可靠性。HBase 内部封装了一个名为 DFSClient 的 HDFS 客户端组件,负责对 HDFS 的实际数据进行读写访问。
6. HBase 的优点
与其他数据库相比,HBase 在系统设计以及实际实践中有很多独特的优点。
容量大:HBase 的单表可以支持千亿行、百万列的数据规模,数据容量可以达到 TB 甚至 PB 级别。传统的关系型数据库,如 Oracle 和 MySQL 等,如果单表记录条数超过亿行,读写性能都会急剧下降,在 HBase 中并不会出现这样的问题。
良好的可扩展性:HBase 集群可以非常方便地实现集群容量扩展,主要包括数据存储节点扩展以及读写服务节点扩展。HBase 底层数据存储依赖于 HDFS 系统,HDFS 可以通过简单地增加 DataNode 实现扩展,HBase 读写服务节点也一样,可以通过简单的增加 RegionServer 节点实现计算层的扩展。
稀疏性:HBase 支持大量稀疏存储,即允许大量列值为空,并不占用任何存储空间。这与传统数据库不同,传统数据库对于空值的处理要占用一定的存储空间,这会造成一定程度上的存储空间浪费。因此可以使用 HBase 存储上百万列的数据,即使表中存在大量的空值,也不需要任何的额外空间。
高性能:HBase 目前主要擅长于 OLTP 场景,数据写操作性能强劲,对于随机单点以及小范围的扫描读,其性能也能够得到保证。对于大范围的扫描读可以使用 MapReduce 提供的 API,以便实现更高效的并行扫描。
多版本:HBase 支持多版本特性,即一个 KV 可以同时保留多个版本,用户可以根据需要选择最新版本或者某个历史版本。
支持过期:HBase 支持 TTL 过期特性,用户只需要设置过期时间,超过 TTL 的数据就会被自动清理,不需要用户写程序手动删除。
Hadoop 原生支持:HBase 是 Hadoop 生态中的核心成员之一,很多生态组件都可以与其直接对接。
7. HBase 的缺点
HBase 本身不支持很复杂的聚合运算(如 Join、GroupBy等)。如果业务中需要使用聚合运算,可以在 HBase 之上架设 Phoenix 组件或者 Spark 组件,前者主要应用于小规模聚合的 OLTP 场景,后者应用于大规模聚合的 OLAP 场景。
HBase 本身并没有实现二级索引功能,所以不支持二级索引查找。比如 Phoenix 提供的二级索引功能。
HBase 原生不支持全局跨行事务,直直垂单行事务模型。同样,可以使用 Phoenix 提供的全局事务模型组件来弥补 HBase 这个缺陷。