opentsdb探索之路——部分设计与实现

2022-02-14 00:00:00 查询 数据 时序 写入 相关

基于opentsdb-2.4.0版本,本篇开启opentsdb探索之路(主要涉及读写特性以及一些其他细节),下一篇将开启opentsdb优化之路——性能优化思路与建议(总结当前痛点问题、优化思路和解决方案,同时也欢迎朋友提出更好的思路与方案)。
注意:阅读本篇文章应该要对HBase有基本的认识,比如rowkeyregionstore ColumnFamilyColumnQualifier等概念以及HBase逻辑结构、物理存储结构有大致的认知。

opentsdb 概览(overview)#

上图取自官方http://opentsdb.net/overview.html。其中的TSD(对应实际进程名是TSDMain)就是opentsdb组件。每个实例TSD都是独立的。没有master,没有共享状态(shared state),因此实际生产部署可能会通过nginx+Consul运行多个TSD实例以实现负载均衡

Each TSD uses the open source database HBase or hosted Google Bigtable service to store and retrieve time-series data

我们大多应该还是用HBase作为数据存储。
安装部署一文中提到过在HBase中创建表结构,这里先简单介绍一下这4张表(table),随着探究的深入会对tsdbtsdb-uid这两张表有更深刻的认识,至于tsdb-metatsdb-tree两张表不是这里讨论的重点,简单了解一下即可。相关文档:http://opentsdb.net/docs/build/html/user_guide/backends/index.html

  • tsdb: opentsdb全部的时序数据都存在这张表中,该表只有一个名为"t"的列族(ColumnFamily)。所以这张表的数据非常大,大多情况下读写性能瓶颈也就与这张表密切相关,进而优化也可能与它相关。
    rowkey的设计为an optional salt, the metric UID, a base timestamp and the UID for tagk/v pairs,即[可选的salt位+metric的UID+小时级别的时间戳+依次有序的tagk、tagv组成的UID键值对],如下:
[salt]<metric_uid><timestamp><tagk1><tagv1>[...<tagkN><tagvN>]

暂不考虑salt位,关于加salt下面有章节单独拿出来看它的设计与实现。来看一个不加salt且含有两个tag的时序数据的rowkey组成:

00000150E22700000001000001000002000004
'----''------''----''----''----''----'
metric  time   tagk  tagv  tagk  tagv

至于rowkey为什么要这样设计以及具体实现,后面详细介绍,这里先有个基本认知。

  • tsdb-uid: 为了减少rowkey的长度,opentsdb会将metrictagktagv都映射成UID,映射是双向的,比如说既可以根据tagk找到对应的UID,也可以根据UID直接找到相应的tagk。而这些映射关系就记录在tsdb-uid表中。该表有两个ColumnFamily,分别是nameid,另外这两个ColumnFamily下都有三列,分别是metrictagktagv。如下图所示:
RowKeyid:metricid:tagkid:tagvname:metricname:tagkname:tagv
metric010x01
metric020x02
tagk010x01
tagv010x01
tagv020x02
0x01metric01
0x01tagk01
0x01tagv01
0x02metric02
0x02tagv02
从上面可以看出,metrictagktagv三种类型的UID映射互不干扰,这也就使得0x01这个UID在不同类型中有着不同的含义。后面会从源码角度讲一下uid大致的分配。

相关文章