首批通过分布式安全可靠测评,为关键业务系统打造
HBaseAPI 存储模型
更新时间:2023-08-09 15:55:22
本文介绍如何在 OceanBase 中添加适合 HBase 的存储模型。
前提条件
已连接 OceanBase 数据库。 您可使用 OBClient 或 MySQL 客户端登录 OceanBase,具体方法可参考 通过 OBClient 连接 OceanBase 租户 和 通过 MySQL 客户端连接 OceanBase 数据库。
存储模型
建表语法
HBase table 中的每一个 column family,在 HBase 类型的数据库下(当前的实现并没有约定数据库),对应下列形式的一个关系表。假设我们要建立一个 HBase 数据表,SQL 示例如下:
CREATE TABLE htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576) NOT NULL,
PRIMARY KEY(K, Q, T));
参数说明:
htable1 为建立的 HBase 表名,可自行命名。
family1 为 column family,可自行命名。
说明
表名与列簇名之间用美元符号($)连接。
K 列存储 HBase 表的 rowkey。
Q 列存储 column qualifier。
T 列存储时间戳版本 timestamp,一般为自 1970-01-01 UTC 至今的毫秒。
V 列存储值 value,使用了 varbinary 类型,最长 1 MB,如果长度不够,可以用 longblob 类型。
K、Q、T 组成联合主键,这样可以标识主键的唯一性。
通过上述 SQL 建表,一个 HBase 表中行的若干列数据,在关系表中存储为相邻的若干行,每一行存储 Hbase 的一个 cell :<row, column family, column qualifier, timestamp, value>
注意
由于 HBaseAPI 依赖于 TableAPI 的底层实现,且 TableAPI 不支持跨分区事务,因而 HBaseAPI 不支持全局索引。
模板表
表模式是固定的,可以建一个模板表,其他表可以通过 SQL CREATE TABLE LIKE 建表,例如:
CREATE TABLE htable2$family2 LIKE htable1$family1;
分区方式
上述建表过程中没有包含分区方式,建立的表是一个非分区表,仅适用于数据量很小的场景。一般情况下 HBase 业务表数据量都比较大,所以我们需要建立 分区表。目前,OceanBase 数据库的 HBase 模型不能像 Apache HBase 一样自动进行分区(region)分裂,所以需要在建表的时候选择一种分区方式。您可以参考如下流程决定使用哪一种分区方法。
Key 分区
如果您的业务中没有用 Scan 进行范围扫描,或者说您只需要 Get 接口,那么使用 Key 分区。分区数需要是奇数,最好是素数,建议值为 97、193、389 等。Key 分区的显著优点是数据分布均匀,一般不会出现数据倾斜和热点。示例如下:
CREATE TABLE htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576) NOT NULL,
PRIMARY KEY(K, Q, T))
PARTITION BY KEY(K) PARTITIONS 97;
虚拟列结合 Key 分区
如果您在业务中必须使用 Scan,但是扫描范围总是 rowkey 的一个定长前缀(前缀扫描),可以在 K 上定义一个虚拟列,然后对这个虚拟列进行 Key 分区。通过这样的方式,可以保证每次扫描只涉及一个分区。除非前缀数据有倾斜,这种分区方式也有利于避免热点。示例如下:
CREATE TABLE htable1$family1 (
K varbinary(1024),,
Q varbinary(256),
T bigint,
V varbinary(1048576),
K_PREFIX varbinary(1024) GENERATED ALWAYS AS (substring(K, 1, 4)),
PRIMARY KEY(K, Q, T))
PARTITION BY KEY(K_PREFIX) PARTITIONS 97;
参数说明:
函数 substring(K, 1, 4) 表示取 K(即 HBase 表的 rowkey)的前 4 个字节为子串,这里的 “4” 需要根据业务 rowkey 特点,替换为前缀长度。
Range 分区
如果您不仅需要前缀扫描和 Get,那么必须建立 range 分区。建议您需要预先对 rowkey 的分布进行估计或采样,选定 range 分区的分割点。如果预估不合理,这种分区方式很容易造成数据倾斜和热点,因尽量避免采用这种方式。示例如下:
CREATE TABLE htable1$family1 (
K varbinary(1024),
Q varbinary(256),
T bigint,
V varbinary(1048576),
PRIMARY KEY(K, Q, T)
)
PARTITION BY RANGE columns (K)
(
PARTITION p0 VALUES LESS THAN ('a'),
PARTITION p1 VALUES LESS THAN ('w'),
PARTITION p2 VALUES LESS THAN MAXVALUE);
参数说明:
通过 'a' 和 'w' 把整个 rowkey 值域空间分为3段。
多 column family 支持
与原生 HBase 在一个表中支持多列簇的不同,OceanBase 不支持多列簇。但可以通过建立上面章节描述的多个表(例如 htable1$family1,htable1$family2 )在客户端实现多 column family。对于上述使用方式,建议您把这些表放入同一个 OceanBase 数据库的 Table Group 中,详细操作,请参考 如何创建 Table Group,这样可以保证跨 column family 的操作没有跨机分布式事务。