【hbase】基于HBase的存储设计

编程

HBase Table 中的数据按照 RowKey 的字典序排列,在行的方向上数据可以分布到多个 HRegion中,而 HRegion 可以分布在不同的节点上,因此只要能够使数据均匀地分布在 HRegion 中,就可以实现存储的负载均衡。

图4 HRegion的分布

容易看出,RowKey 的设计是负载均衡的关键。如果 RowKey 设计不好,就容易形成热点HRegion,导致其所在节点负载过重,进而集群的整体性能下降。

接下来重点介绍 TSDB 中最关键的两张表的设计:数据表和维度索引表。前者支撑了所有时序数据的存储和查询,后者是多维度聚合查询的基础。

1数据表 前文介绍过,监控时间序列构成如下:

时间序列 = 监控对象 + 标签列表 + 监控项 + 数据点

为方便讲解,换一种形式表述:

ts = (object + tags) + metric + [(timestamp, value), (timestamp, value), ...]

可见,由object + tags + metric + timestamp 可以唯一定位一个数据点的取值。为了充分利用HBase 的特性,我们借鉴了 OpenTSDB 的做法,将 RowKey 设计如下:

RowKey = entity_id + metric_id + timebase

entity_id 是由 object 和 tags 的经过 hash 得到的一个固定长度的值,hash 后原始字符串的自然顺序被打乱,使得 RowKey 能够相对均匀地分布在不同 HRegion 中。

metric_id 为 metric 的字符串 hash 值,同样是固定长度。

timebase 为 Unix 时间戳按照 1 小时(3600 秒)取整得到的数值,固定 4 个字节的长度

这样的设计有如下好处:

entity_id 和 metric_id 的散列使得数据相对均匀分布

timebase 置于 RowKey 的字节低位,使得同一个时间序列数据的 RowKey 连续分布,可以高效地按时间进行范围扫描

固定长度的 RowKey 减少了空间浪费,同时前缀式的设计可以充分利用 HBase 的前缀压缩机制,进一步节省 RowKey 所占空间

RowKey 代表的行包含 1 小时的数据,行中数据点按照当前时间在 1 小时内的偏移量进行存储,最终的表结构示意如表 1:

表1 数据表 RowKey 设计

2 维度索引表

在数据表的设计中,tags 被编码进固定长度的 entity_id 中,同时 HBase 并没有对索引的原生支持,这导致无法通过 tag 找到对应的 entity_id,也就无法满足数据的多维度检索聚合需求。为此我们引入了一张索引表,建立从 tag 到 entity_id 的映射,以支持通过 tag 筛选数据。

如图 5 所示,通过指定一个 tag: k1=v1,可以查到所有包含这个 tag 的 entity_id1、entity_id2 和entity_id3。

图5 维度索引

RowKey 的构造比较简单:

RowKey = key + value

以上是 【hbase】基于HBase的存储设计 的全部内容, 来源链接: utcz.com/z/516817.html

回到顶部