TANKENQI.cn

May 27, 2024

Apache Hbase —— 简介

BigData3.4 min to read

1 简介

img

HBase 是以 Google 的 Bigtable 为模型的开源非关系型分布式数据库,提供了一种存储大量稀疏数据的容错方式,适用于需要低延迟随机访问和高达 PB 级的海量存储的用例。

HBase采用共享存储架构,将计算层与存储层分开,存储层通常位于HDFS(Hadoop分布式文件系统)上。这种架构选择实现了吸引人的功能,如平滑扩展和成本优化等。以下是一些用例,在这些用例中,HBase 可能是一个不错的候选者。

一些具体用例包括:

下面列出了 HBase 的一些功能:

2 Hbase如何组织数据

HBase 中的表是半结构化的,这意味着必须在使用前定义列族。数据单元格由特定行键、特定列系列、确切的列限定符和时间戳(对于多版本单元格中的特定版本)唯一标识。数据稀疏地存储在 HBase 中,缺失的列根本不占用存储空间。

Hbase 支持多版本数据,这意味着“一个单元格”实际上由多个单元格组成,每个版本一个单元格,按时间戳降序排序。为了便于理解,可以粗略地将数据组织视为下面的 JSON 数组。

// table name format:"${namespace}:${table}"// e.g. "default:test_table"[  "rowKey1": { // rowkey locates a row    "cf1": { // column family must be pre-defined in table schema      "cq_a": { // column qualifier can be arbitrary value        "timestamp3": "value3",         // a cell is located by (row=rowKey1, column="cf1:cf_a", timestamp=timestamp2)        "timestamp2": "value2",        "timestamp1": "value1"      },      "cq_b": {        "timestamp2": "value2",        "timestamp1": "value1"      }    },    "cf3": {      "cq_m": {        "timestamp1": "value1"      },      "cq_n": {        "timestamp1": "value1"      }    },  },  "rowKey3": {    "cf2": { // sparse storage. missing column families take no storage space      "cq_x": {        "timestamp3": "value3",        "timestamp2": "value2",        "timestamp1": "value1"      },      "cq_y": {        "timestamp1": "value1"      }    },  }]

img

img

3 HBase客户端如何执行读/写请求

HBase 客户端配置了与目标 HBase 集群对应的 Zookeeper 信息

  1. 客户端请求 Zookeeper 查找Region Server A 提供元数据表 'hbase:meta'
  2. 然后,客户端请求区域服务器 A 在“hbase:meta”表中查找为目标行键提供服务的Region Server B
  3. 最后,客户端请求Region Server B 操作目标行键的数据
  4. 然后,位置信息将缓存在客户端中,以避免查找成本

img

4 当我们向 HBase 读取/写入数据时会发生什么?

HBase 实现了一种称为日志结构化合并树的数据结构。

当收到写入请求时,更改记录首先记录在预写日志中,该日志是持久存储在磁盘上的仅追加日志。然后将数据写入 MemTable,这是一种内存中的数据结构,可使行保持顺序,并支持二进制搜索和行的正向和反向迭代,通常由 ConcurrentSkipListMap 实现。

一旦 MemTable 的大小达到配置的阈值,就会触发刷新,将 MemTable 数据写入存储在 HDFS 上的 StoreFiles 中。顺便说一下,每个列系列都有自己的 MemTable 和 StoreFiles。

既然一个列族的数据可以存储在 MemTable 中,也可以存储在一个区域服务器内的多个 StoreFile 中,那么我们如何读取一行呢?构造一个合并的迭代器,将所有 StoreFile 和 MemTable 组合在一起,形成一个全局有序的视图。首先,为每个 StoreFile/MemTable 创建一个迭代器,该迭代器可以在 StoreFile/MemTable 中按顺序迭代行。其次,在这些迭代器上构造一个最小堆,使用比较器作为迭代器的当前行。因此,可以确保最小堆顶部的迭代器中的当前行是全局顺序的下一行。

img

img