前面博主写了一篇文章去介绍opentsdb的http接口的使用方法,但是某一些接口的使用还是比较复杂,这篇文章会通过example来详细讲述opentsdb的一些特性。

本文的举的例子有这些:

  1. 基本的写入和查询
  2. 数据的注释和说明
  3. 子查询
  4. 查询中的filters使用
  5. 查询数据的rate(增长率)
  6. 直方图中百分位数(percentiles)的查询
  7. Downsampling(下采样)
  8. query/exp 的使用(查询中使用表达式)
  9. trees详解

一、基本的写入和查询

这个功能是最基本,也是最常用的。
写数据:写入数据post接口为 /api/put?details,details表示会将写入的详细结果返回回来:

#请求体
[{"metric": "sys.cpu.nice","timestamp": 1346846402,"value": 18,"tags": {"host": "web01","dc": "lga"}}
]
#写入成功返回的内容
{"success": 1,"failed": 0,"errors": []
}

查数据:写入成功之后,当然可以去查询。查询post接口为 /api/query:

#请求体
{"start": 1346846402,"end": 1346846403,#返回数据对应的tsUID"showTSUIDs":"true",  "queries": [{"aggregator": "avg","metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"}}]
}
#返回数据
[{"metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"},"aggregateTags": [],"tsuids": ["000001000001000001000002000002"  #数据对应的tsUID],"dps": {"1346846402": 18}}
]

这里需要对tsUID进行说明一下,opentsdb是由metric+tags来区分数据的,当metric和tags相同时,其tsUID就会相同,代表着同一系列的数据。那么,假如我们想对这一系列数据进行标注和说明呢?见下一个example。

二、数据的注释和说明

数据的注释和说明是用到了 /api/annotation 接口,post方式是写入annotation数据,get是查询annotation数据。

#post接口的请求body
{"startTime":"1346846402",#和返回前面一个example返回tsUID相同,这样时间序列数据就和annotation数据关联了起来,可作为时间序列数据的注释和说明"tsuid":"000001000001000001000002000002","description": "Testing Annotations","notes": "These would be details about the event, the description is just a summary","custom": {"owner": "jdoe","dept": "ops"}
}

当写入成功时间,再次运行查询example1中的 /api/query 请求,即可得到:

[{"metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"},"aggregateTags": [],"tsuids": ["000001000001000001000002000002"],"annotations": [{"tsuid": "000001000001000001000002000002","description": "Testing Annotations","notes": "These would be details about the event, the description is just a summary","custom": {"owner": "jdoe","dept": "ops"},"startTime": 1346846402,"endTime": 0}],"dps": {"1346846402": 18}}
]

可见,此次在返回数据的清楚上,把相关联的注释(annotation数据)也一起返回回来,注释一般可以用来解释和说明数据。

三、子查询

/api/query 接口中,body中有一个参数是queries,它表示可以含有多个子查询,所谓子查询就是只要数据满足其中的一个子查询,数据就会返回回来。注意每次查询至少需要一个子查询。

在example1中写入一条数据的前提下,这里再向tsdb中写入一条数据:

[{"metric": "sys.cpu.nice","timestamp": 1346846402,"value": 9,"tags": {"host": "web02","dc": "lga"}}
]
# 通过 /api/query 接口我们可以查得该条数据的tsUID为000001000001000003000002000002

下面查询body就表示有两个子查询:

//请求体
{"start": 1346846401,"end": 1346846403,"showTSUIDs":"true","queries": [{   //第一个子查询,查询的是example1中写入的数据"aggregator": "avg","metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"}},{   //第二个子查询,查询的是刚刚写入的数据"aggregator": "avg","tsuids":["000001000001000003000002000002"]}]
}//返回结果
[{    //第一个子查询对应的数据"metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"},"aggregateTags": [],"tsuids": ["000001000001000001000002000002"],"annotations": [{"tsuid": "000001000001000001000002000002","description": "Testing Annotations","notes": "These would be details about the event, the description is just a summary","custom": {"owner": "jdoe","dept": "ops"},"startTime": 1346846402,"endTime": 0}],"dps": {"1346846402": 18}},{     //第二个子查询对应的数据"metric": "sys.cpu.nice","tags": {"host": "web02","dc": "lga"},"aggregateTags": [],"tsuids": ["000001000001000003000002000002"],"dps": {"1346846402": 9}}
]

在平常使用过程中我们可以使用单个或者多个子查询,还有需要注意对于每个子查询而言,主要有两种类型:

  1. metric查询方式:子查询指定metric和tags(optional)进行查询,本次查询中的第一个子查询就是采用这种方式。
  2. TSUID查询方式:需要给出一个或者多个tsuid,对应本次查询中的第二个子查询。

四、查询中的filters使用

从opentsdb2.2版本便支持filter,它其实是用于过滤tags的,可以作为tags查询的替代者,并且比tags更加灵活。请求body如下:

{"start": 1346846401,"end": 1346846403,"showTSUIDs":"true","queries": [  {"aggregator": "avg","metric": "sys.cpu.nice","filters": [{  "type":"literal_or",  "tagk":"host","filter":"web01|web02","groupBy":true}]}]
}
参数 意义
type 过滤器的类型,可以访问 /api/config/filters 接口查看支持的所有类型,这里 literal_or 表示value是一个枚举
tagk 指定过滤的key
filter 和相type对应,这里表示对web01和web02都进行匹配
groupBy 是否对匹配到的数据进行分组

这里使用literal_or,filter里面的多个tagV以竖线相隔,这个过滤器的意思是对tagK为host进行匹配,并且value为web01和web02都数据都会匹配成功。
返回结果:

[{"metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"},"aggregateTags": [],"tsuids": ["000001000001000001000002000002"],"annotations": [{"tsuid": "000001000001000001000002000002","description": "Testing Annotations","notes": "These would be details about the event, the description is just a summary","custom": {"owner": "jdoe","dept": "ops"},"startTime": 1346846402,"endTime": 0}],"dps": {"1346846402": 18}},{"metric": "sys.cpu.nice","tags": {"host": "web02","dc": "lga"},"aggregateTags": [],"tsuids": ["000001000001000003000002000002"],"dps": {"1346846402": 9}}
]

可见本次filter查询用一个子查询的结果和example3中用了两个子查询的效果是一样的。

五、查询数据的rate(增长率)

在某些情况下,我们查询的可能并不是数据的本身,而是它的增长率。恰巧opentsdb有帮我们提供这个功能:子查询中的rate参数。
首先我们先写入3条数据,时间分别间隔两秒,数据分别为0、64000和1000。

[{"metric": "sys.cpu.nice","timestamp": 1346846410,"value": 0,"tags": {"host": "web03","dc": "lga"}},{"metric": "sys.cpu.nice","timestamp": 1346846412,"value": 64000,"tags": {"host": "web03","dc": "lga"}},{"metric": "sys.cpu.nice","timestamp": 1346846414,"value": 1000,"tags": {"host": "web03","dc": "lga"}}
]

查询增长率的请求body如下:

{"start": 1346846409,"end": 1346846414,"showTSUIDs":"true","queries": [  {"aggregator": "avg","metric": "sys.cpu.nice","rate":true,  # 查询增长率"rateOptions":{"counter":false  },"tags": {"host": "web03","dc": "lga"}}]
}# 响应结果
[{"metric": "sys.cpu.nice","tags": {"host": "web03","dc": "lga"},"aggregateTags": [],"tsuids": ["000001000001000007000002000002"],"dps": {"1346846412": 32000,"1346846414": -31500}}
]

3200=(6400-0)/2,-31500=(1000-6400)/2,可见增长率是以秒为单位。

六、直方图中百分位数(percentiles)的查询

opentsdb在2.4版本对直方图(histogram进行了支持),本个example中首先写入直方图数据,然后根据数据对百分位数(percentile)进行查询。
写入数据的body如下:buckets是直方图数据,意思为0到1.75区间的数值为12,1.75到3.5区间的数值为16.

{"metric": "sys.cpu.nice","timestamp": 1356998400,"overflow": 1,"underflow": 0,"buckets": { "0,1.75": 12,"1.75,3.5": 16},"tags": {"host": "web01","dc": "lga"}
}

关于百分位的定义可以自行查资料进行详细认识,本次查询中percentiles列表里面就是需要查询的百分位,需要注意的是列表里面的数字的取值区间是[0,100],并且可以不按照顺序排列。查询body如下:

{"start": 1356998400,"end": 1356998401,"showTSUIDs":"true","queries": [  {"aggregator": "sum","percentiles":  [100,99,43,42,1],"metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"}}]
}

请求的结果如下:

[{"metric": "sys.cpu.nice_pct_1.0","tags": {"host": "web01","dc": "lga"},"aggregateTags": [],"tsuids": ["000001000001000001000002000002"],"dps": {"1356998400": 0.875}},{"metric": "sys.cpu.nice_pct_42.0",···"dps": {"1356998400": 0.875}},{"metric": "sys.cpu.nice_pct_43.0",···"dps": {"1356998400": 2.625}},{"metric": "sys.cpu.nice_pct_99.0",···"dps": {"1356998400": 2.625}},{"metric": "sys.cpu.nice_pct_100.0",···"dps": {"1356998400": 2.625}}
]

返回内容如上:其中相同部分已经省略,返回的metric由 原始metric_pct_number 组成,下面讲述它们的计算方式:
第一个区间的数值为12,第二个区间的数值为16,12/(12+16)=0.428。

  • 我们看到1和42的百分位的取值都是0.875,0.875=1.75/2,取的第一个区间的中点坐标,可以得到在0.428之前的百分位的数值都为0.875。
  • 43、99、100百分位对应的数值都为2.625,2.625=1.75+(3.5-1.75)/2,2.625的物理意义就是第二个区间中点的横坐标,因此43到100之间的百分位取值都为2.525。

七、Downsampling(下采样)

下采样即让浓密数据变稀疏的过程,首先写入10条数据,数值分别为0到9,相邻数据的时间间隔为1s:

[{"timestamp": 1562068000,"value": 0,"metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"}},······{"metric": "sys.cpu.nice","timestamp": 1562068009,"value": 9,"tags": {"host": "web01","dc": "lga"}}
]

下采样查询如下,downsample字段是一个字符串,该字段由 interval-aggregate-fill policy 组成,分别表示时间间隔、聚合方法、缺少的值补齐的方法。本次查询下采样间隔为2s,聚合方法是取聚合区间的最小值,并且缺少的值用0补齐:

{"start": 1562068000,"end": 1562068009,"queries": [  {"aggregator": "avg","metric": "sys.cpu.nice","downsample":"2s-min-zero","tags": {"host": "web01","dc": "lga"}}]
}

返回结果如下,可见原本每秒一个数据在结果中是每两秒返回一个数据,并且在每个间隔中,都是取的最小值。

[{"metric": "sys.cpu.nice","tags": {"host": "web01","dc": "lga"},"aggregateTags": [],"dps": {"1562068000": 0,"1562068002": 2,"1562068004": 4,"1562068006": 6,"1562068008": 8}}
]

八、query/exp 的使用(查询中使用表达式)

这个接口允许使用表达式进行查询,可以对查询的多个结果进行操作。
在example7写入数据的基础上,再写入如下数据,相比example7的数据而言仅仅是metric发生了变化:

[{"timestamp": 1562068000,"value": 0,"metric": "sys.cpu.nice1","tags": {"host": "web01","dc": "lga"}},······{"metric": "sys.cpu.nice1","timestamp": 1562068009,"value": 9,"tags": {"host": "web01","dc": "lga"}}
]

紧接着使用表达式进行查询,查询body如下,

  • time 定义了查询的时间区间和聚合方式
  • filters 定义了一个过滤器f1
  • metric 中指定了对sys.cpu.nice和sys.cpu.nice1两个metric进行查询,并且两个metric都使用同一个filter:f1
  • expressions 中是语法表达式,e就等于结果a加上结果b,e2就等于e乘以2
  • outputs 指定需要输出的表达式计算结果
{"time": {"start": "1562068000","end":"1562068009","aggregator":"sum"},"filters": [{ "tags": [{"type": "wildcard","tagk": "host","filter": "web*","groupBy": true}],"id": "f1"}],"metrics": [{"id": "a","metric": "sys.cpu.nice","filter": "f1","fillPolicy":{"policy":"nan"}},{"id": "b", "metric": "sys.cpu.nice1","filter": "f1","fillPolicy":{"policy":"nan"}}],"expressions": [{"id": "e","expr": "a + b"},{"id":"e2","expr": "e * 2"}],"outputs":[{"id":"e", "alias":"e"},{"id":"e2", "alias":"e2"}]}

查询结果如下,query是里面是关于查询请求body的信息,为了节约空间这里省略。可以得知表达式计算是对同一个时间点进行计算的。

  • outputs中的e,时间点1562068001000对应的值为2,sys.cpu.nice和sys.cpu.nice1在1562068001000对应的数值都为1,便可和表达式中 e=a+b 对应起来。
  • e2中时间点1562068001000对应的值为4,便可和表达式中 e2=ex2 对应起来。
{"outputs": [{"id": "e","alias": "e","dps": [ [1562068000000,0],[1562068001000,2],[1562068002000,4],[ 1562068003000, 6],[1562068004000,8],[1562068005000,10],[1562068006000,12],[1562068007000,14],[1562068008000,16],[1562068009000,18] ],"dpsMeta": { "firstTimestamp": 1562068000000,"lastTimestamp": 1562068009000, "setCount": 10,"series": 1},"meta": [{"index":0,"metrics":["timestamp"]},{"index":1,"metrics":["sys.cpu.nice","sys.cpu.nice1"],"commonTags":{"host":"web01","dc":"lga"},"aggregatedTags":[]}]},{"id": "e2","alias": "e2","dps": [[1562068000000,0],[1562068001000,4],[1562068002000,8],[1562068003000,12],[1562068004000,16],[1562068005000,20],[1562068006000,24],[1562068007000,28],[1562068008000,32],[1562068009000,36]],"dpsMeta": { "firstTimestamp": 1562068000000,"lastTimestamp": 1562068009000,"setCount": 10,"series": 1},"meta": [{"index":0,"metrics":["timestamp"]},{"index":1,"metrics":["sys.cpu.nice","sys.cpu.nice1"],"commonTags":{"host":"web01","dc":"lga"},"aggregatedTags":[]}]}],"query": {······}
}

九、trees详解

opentsdb2.0版本引入了tree的概念,tree可以将一些时间序列组织起来使其具有层次结构,和文件系统一样,tree中的叶子类比于文件系统的文件,tree中的branch类比于文件系统的文件夹,还可以继续在里面创建新的文件夹。其相关定义可参考官网。

在tsdb中创建一棵树步骤如下:

  1. 首先创建一棵树,此时数的enable属性为false。
  2. 为这棵树定义一些规则,数的形状和数据是由这些规则确定。
  3. 可以通过/api/tree/test接口对这棵树进行测试,看其接口是否满足要求。
  4. 将树的enable设为true。
  5. 运行./tsdb uid treesync扫描TSMeta中的全部对象,将符合条件的时间序列加入到树中。注意:若需要每创建一个TSMeta对象时,都试图将对象加入到enable tree中,那么在启动tsdb时需要加上 tsd.core.tree.enable_processing=true 配置。

现在按照上面的流程进行操作实际一遍,首先对时间序列、数的规则进行说明。

现在我们有如下的时间序列数据:

图1

这些时间序列需要满足如下规则(rules),level表示数的第几层,order表示同一level的不同rule有不同的优先级。level 0 有两个rule,当满足order为0的rule时,会跳过order为1的rule;反之order为1的rule就会生效。

图2

基于上面的时间序列和tree的规则,可以得到下面的tree:

图3

下面按照步步骤对这棵树进行生成:

  1. 写入图一中的输入,请求body此处略。
  2. 创建一棵树,post接口为 /api/tree,请求body如下:
{"name":"Network","description":"","notes":"","rules":null,"created":1368964815,"strictMatch":false,"storeFailures":false,"enabled":false}

创建成功后 可以用 get方式请求 /api/tree 接口查询tree的相关信息,并可以获得新创建tree的id,treeId下面也会用到。

  1. 利用接口 /api/tree/rule接口,依次创建图2中的4个rule,请求body分别如下:

{"type":"tagk","field":"dc","description":"a tagk named data center","level":0,"order":0,"treeId":1}{"type":"tagk","field":"host","description":"a tagk named host","regex":".*\\.(.*)\\.mysite\\.com","level":0,"order":1,"treeId":1}{"type":"tagk","field":"host","description":"a tagk named host","separator":"\\.","level":1,"order":0,"treeId":1}{"type":"metric","description":"metric","separator":"\\.","level":2,"order":0,"treeId":1}
  1. 利用/api/tree/test 接口测试我们新创建的tree,get请求有两个参数:
参数名 意义
treeId 用于指定测试的tree
tsuids 指定时间序列,试图将这些时间序列放入这颗树中进行测试,多个tsuid以 ","相隔

这里的tsuids当然是指图1中时间序列对应的tsuid,可以用 /api/query接口进行查询。
/api/tree/test会返回这些时间序列基于这棵树的层次关系,若这个层次结构不满足需求则需要对rule进行修改,若满则需求则可进行下一步。

  1. 在tsdb的build文件夹运行 ./tsdb uid treesync 命令,它会扫描全部的 tsdb-uid,将符合条件的序列加入到tree的结构中。

至此这棵树的定义就已经完成,可以用 /api/tree/branch 接口对tree的分支进行查询,查询的参数有两个:

参数名 意义
treeid tree的id
branch branch的id

两个参数只需要一个,当传递treeid时,就会返回root branch的信息。当只传递branch时,就会返回对应branch的信息。当两个参数都传递时,参数treeid就会被忽略。

OpenTSDB 开发指南之 查询数据相关推荐

  1. OpenTSDB 开发指南之 Api操作数据

    /api/put 请求方式:post 请求参数: 参数 说明 example summary 返回主要摘要 /api/put?summary details 返回详细信息 /api/put?detai ...

  2. OpenTSDB 开发指南之 Grafana 展示OpenTSDB监控数据

    目录 准备数据 在Grafana创建OpenTSDB连接 创建一个仪表盘 统计 准备数据 将数据插入OpenTSDB {"metric":"jast.data" ...

  3. MySQL 09 DQL → select 初识查询数据和别名的使用

    4.1 DQL → select 查询数据和别名的使用 DQL:Data Query LANGUAGE(数据查询语言) 所有的查询操作都用它 select 简单的查询,无论多么复杂的查询它 都可以做到 ...

  4. 开发指南专题七:JEECG微云快速开发平台查询HQL过滤器

    开发指南专题七:JEECG微云快速开发平台 HQL过滤器 1. 查询HQL过滤器 1.1. 数据过滤现状分析 项目开发的查询页面都会有很多查询条件,开发追加查询条件的工作繁琐又很浪费时间. 这块工作量 ...

  5. 【SQL Server】数据库开发指南(五)T-SQL 高级查询综合应用与实战

    本系列博文还在更新中,收录在专栏:#MS-SQL Server 专栏中. 本系列文章列表如下: [SQL Server] Linux 运维下对 SQL Server 进行安装.升级.回滚.卸载操作 [ ...

  6. AgileEAS.NET平台开发指南-数据层开发

    对象关系映射 AgileEAS.NETORM并没有采用如NHibernate中映射文件的文件的模式,而是采用了直接硬编码的模式实现,ORM体系设计采用了属性/列>数据对象>数据集合(表)的 ...

  7. Knockout应用开发指南 第六章:加载或保存JSON数据

    原文:Knockout应用开发指南 第六章:加载或保存JSON数据 加载或保存JSON数据 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地 ...

  8. 【区块链 | 数据上链】星火链网、蚂蚁联盟链等区块链业务系统开发指南

    ​​​​ 星火链网.蚂蚁联盟链等区块链业务系统开发指南 一.区块链 1.简介 区块链,就是一个又一个区块组成的链条.每一个区块中保存了一定的信息,它们按照各自产生的时间顺序连接成链条.这个链条被保存在 ...

  9. OpenTSDB 查询数据

    文章目录 Querying or Reading Data Query Components Times Filters Aggregation Downsampling Rate Order of ...

最新文章

  1. ReadyFor4GB破解win7支持4G内存恢复到原系统
  2. vue Watcher分类 computed watch
  3. elasticsearch入门hello world (macos)【一】下载运行
  4. Angular form学习笔记
  5. python地图 两点距离_没学过还真不会!怎样才能画出准确的地图?
  6. SQL Server 2008将数据导出到SQL脚本文件
  7. Code-NFine:NFine介绍
  8. MSMS探针卡市场现状及未来发展趋势
  9. 如何卸载 3DMAX ?怎么把3DMAX彻底卸载删除干净重新安装的方法
  10. 增长模型—评分卡模型
  11. 手机号码测试用例java_“邮箱”“验证码”“手机号码”输入框测试用例
  12. PythonTutor本地化运行
  13. FPGA开发板学习(1)
  14. linux sem_wait sleep,[Linux]多线程同步之sem_wait()学习笔记
  15. C语言编程b a化简,C语言编程,已知三角形的三边长a,b,c,计算求三角... 如果三角形三边长 a,b,c,满足( )那么这个三角形......
  16. js控制excel打印完美解决方案
  17. 数绵羊(矩阵快速幂)
  18. StbM 和 Time Synchronization Over CAN and Ethernet(二) 以EthTSyn和StbM为例
  19. 15、【易混淆概念集】-第九章 职责分配矩阵(RAM) 活动资源估算、资源分解结构 获取资源 资源/项目/自然日历区别 虚拟团队、集中办公、认可与奖励 塔克曼阶梯理论 冲突管理 权力类型
  20. 手把手实战 Redis 教学

热门文章

  1. hfss螺旋平面_利用HFSS设计平面等角螺旋天线
  2. JAVAWEB入门之Servlet相关配置
  3. idea卡顿的解决方法_lt;绝地求生/PUBG/解决卡顿方法(停机9小时)维护gt;9月16日(星期三) 08点30分amp;崩溃...
  4. mfc color 亮度_双十一4K投影仪怎么选?小心别掉“亮度坑” - 电视
  5. Java学习之数据库中的范式和反范式
  6. oracle 11g segment,11g视图dba_segments中增加了一个有用的segment_subtype字段!
  7. leetcode 2 --- 两数相加
  8. domino缺省注册服务器或无法访问,Domino服务器挂起时的现象
  9. z370支持pcie信号拆分吗_定了!AMD B550主板确认将支持PCIE4.0,多项能力接近X570
  10. mysql定时导入_MySQL导入、导出、数据库定时备份