opentsdb探索之路——部分设计与实现
基于opentsdb-2.4.0版本,本篇开启opentsdb探索之路(主要涉及读写特性
以及一些其他细节
),下一篇将开启opentsdb优化之路——性能优化思路与建议
(总结当前痛点问题、优化思路和解决方案,同时也欢迎朋友提出更好的思路与方案)。
注意:阅读本篇文章应该要对HBase
有基本的认识,比如rowkey
、region
、store
、 ColumnFamily
、ColumnQualifier
等概念以及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
),随着探究的深入会对tsdb
和tsdb-uid
这两张表有更深刻的认识,至于tsdb-meta
、tsdb-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
会将metric
、tagk
、tagv
都映射成UID
,映射是双向的,比如说既可以根据tagk
找到对应的UID
,也可以根据UID
直接找到相应的tagk
。而这些映射关系
就记录在tsdb-uid
表中。该表有两个ColumnFamily
,分别是name
和id
,另外这两个ColumnFamily
下都有三列,分别是metric
、tagk
、tagv
。如下图所示:
RowKey | id:metric | id:tagk | id:tagv | name:metric | name:tagk | name:tagv |
---|---|---|---|---|---|---|
metric01 | 0x01 | |||||
metric02 | 0x02 | |||||
tagk01 | 0x01 | |||||
tagv01 | 0x01 | |||||
tagv02 | 0x02 | |||||
0x01 | metric01 | |||||
0x01 | tagk01 | |||||
0x01 | tagv01 | |||||
0x02 | metric02 | |||||
0x02 | tagv02 | |||||
从上面可以看出,metric 、tagk 、tagv 三种类型的UID 映射互不干扰,这也就使得0x01 这个UID 在不同类型中有着不同的含义。后面会从源码角度讲一下uid大致的分配。 |
相关文章