OpenTSDB 简介
OpenTSDB
是一个基于HBase的可扩展时间序列数据库,支持数百万每秒的读写,与OpenTSDB的交互主要是通过运行一个或多个TSD来实现的。每个TSD是独立的,没有主设备,没有共享状态,因此您可以根据需要运行任意数量的 TSD,以处理向其施加的任何负载。
Cloudera Express
管理并运行了生产环境的 HDFS/HBase/ZooKeeper。
项目背景
OpenTSDB存储了SDN设备间的流量数据,粒度包括:源IP、目的IP、上下行流量、服务类型、协议等。
流量统计接口按时间区间直接查询了OpenTSDB的原始数据,未经Rollup处理。
查询瓶颈
客户BJ联通反馈某台SDN
设备11月初的流量统计接口返回超时。测试发现其他设备流量统计正常,联通设备查询时候有如下错误日志:
1 | 16:14:13.466 ERROR [RegionClient.exceptionCaught] - Unexpected exception from downstream on [id: 0xbbc6970f, /172.31.250.10:50790 => /172.31.120.131:16020] |
Github上有人2016年就遇到该错误,CallbackOverflowError with many tag values,issue至今未关闭
翻阅了OpenTSDB报错代码段
1 | // com.stumbleupon:async:1.4.1 |
MAX_CALLBACK_CHAIN_LENGTH
限制了Deferred
链的长度,而进入到上面addCallbacks
方法的为聚合分类后的每条数据,估计联通的问题就是处理数据超过了该限制。
测试也发现缩短联通设备的查询时间区间是能正常返回的,并且2019-11-06 8:00:00 - 2019-11-06 9:00:00的数据就近1.5W条返回,也就是说联通设备目的IP近1.5W个,大多数IP流量不多。
Deferred类是Java库提供一些有用的构建模块去 构建高性能,多线程,异步的java应用。它的实现灵感来自Twisted的异步库(twisted.internet.defer)。
Deferred允许你轻松地构建异步的处理链,这个处理链必须触发,当一个异步的事件(I/O,RPC 以及其它)完成。它能被广泛用于构建异步API,在一个多线程服务器或者是客户端中。
着手解决
OpenTSDB并不提供返回结果限制参数,至少2.4版本没有。
华为云CloudTable集成的OpenTSDB服务支持了结果限制,也就是query api提供了一个limit参数。
流量统计接口是统计该设备的TOP10
流量,因此设置更大的MAX_CALLBACK_CHAIN_LENGTH没有意义:返回结果多,查询慢。
解决办法就是过滤进入到addCallback的数据大小:
1、OpenTSDB的查询最后准备返回结果的时候才通过三行代码过滤掉不在该时间区间的数据,
1 | //net/opentsdb/tsd/HttpJsonSerializer.java:835 |
因此一个优化就是在进入addCallback就过滤掉这一部分数据。
2、提供一个limit参数,限制返回结果集大小。这里分两步:一是进入addCallback前通过TreeSet
自动排序,限制最多limit条数据会进入处理,二是OutputStream写入时候,排序后截取前limit条数据返回。
关键是提前过滤不在时间区间的数据点及TreeSet自动排序过滤掉大部分小流量的IP数据
1 | class HttpJsonSerializer extends HttpSerializer { |
如query api传入参数包含limit,则先将数据写入到ByteArrayOutputStream
(这样子源代码改动小),再从ByteArrayOutputStream
中反序列化获得原响应数据,倒序并截取前limit条数据写入到OutputStream
1 | //net.opentsdb.tsd.HttpJsonSerializer#sortDps |
编译测试
参考OpenTSDB General Development Compiles OpenTSDB and generates a Debian package
,卸载官方版本后安装。
修改 laudukang/opentsdb-okhttp-client 让其支持limit
查询参数。
测试显示查询耗时明显缩短,而且响应大小也减少了,不再返回几MB的json数据。
查询例子POST /api/query?summary
1 | { |
response
1 | [ |
提供一个编译好的安装包:
Debian package: opentsdb-2.4.0_all.deb
Debian package: opentsdb-2.4.0_all.deb Backup Url
1 | >md5sum opentsdb-2.4.0_all.deb |
推荐一个类库
推荐一个OpenTSDB
Java类库OpenTSDB Java Async Client,封装了一下几个方法,开箱即用:
1 | default String buildUrl(String serviceUrl, String postApiEndPoint, ExpectResponse expectResponse) |
Spring boot init OpenTSDBService
example:
1 |
|
Thanks to JetBrains‘ support
