时间序列数据库武斗大会之 KairosDB 篇
【编者按】
刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融、通信以及Android手机操作系的开发,熟悉Linux及后台开发技术。曾参与翻译过《第一本Docker书》、《GitHub入门与实践》、《Web应用安全权威指南》、《WEB+DB PRESS》、《Software Design》等书籍,也是Docker入门与实践课程主讲人。本文所阐述的「时间序列数据库」,系笔者所负责产品 Cloud Insight 对性能指标进行聚合、分组、过滤过程中的梳理和总结。
今天我们来介绍一下 KairosDB.
按照官方的说明,KairosDB 是一个 “Fast Time Series Database on Cassandra”,即基于 Cassandra 的高速时序列数据库。
特点
数据采集
数据可以通过多种协议写入 KairosDB,比如 Telnet 的按行写入,HTTP API,Graphite 以及批处理导入。此外,还可以使用或者自己编写插件。
存储
KairosDB 采用了 Cassandra 作为数据存储方式,Cassandra 也是一个比较流行的NoSQL数据库,很多开源软件基于此数据库。
Rest API
KairosDB 提供了 REST API,已完成对 metric 名称,tag 等的查询,当然,也少不了存储和查询数据点(data points)。
自定义数据类型(Custom Data)
KairosDB 支持存储和聚合自定义数据类型。默认情况下 KairosDB 支持 long、double 和字符串的 value,这比 OpenTSDB 要丰富一些。
分组和聚合
作为数据分析系统,分组和聚合则是必不可少的功能。 KairosDB的聚合(也就是down samples)功能,支持的标准函数有 min、max、sum、count、mean、histogram、gaps 等,而且都非常实用。
比如 percentile,可以计算一个指标值大概的百分比位置,非常适合存储类似“你打败了xx%的人”这种需求场景。
支持工具
KairosDB 提供了进行数据导入导出的命令行工具。根据官方文档的说明,在一台分配了 2Gig 内存的 SSD Cassandra 上,1 秒钟能导入 13 万条数据。
插件机制
KairosDB 也提供多种基于 Guice 的插件机制来进行扩展(data point 监听器,数据存储,协议处理等。)
KairosDB 是从 OpenTSDB fork 过来的,因此最初它是支持 HBase 的,不过现在 HBase 已经不能完全支持 KairosDB 所需的特性,将来会取消对 HBase 的支持。
入门 KairosDB
安装 KairosDB
这里我们以当前最新的1.1.1版本为例进行说明。
首先,需要确保你的JAVA_HOME已经设置好了,且Java版本高于1.6。
$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home
然后需要到 GitHub 上去下载安装包。我用的是 OS X 系统,因此我选择了kairosdb-1.1.1-1.tar.gz (注意:点击这个链接即可下载)
解压后可以看看它的配置文件conf/kairosdb.properties,有一些东西适合 OpenTSDB 一样的,比如 4242 端口。
KairosDB 集成了 jetty,你可以通过 jetty 访问 WEB UI,而且还支持添加 SSL 支持,这样安全性上比 OpenTSDB 高了一个层级。
配置文件中还能对 Cassandra 进行设置,比如服务器地址、keyspace 等。不过默认的话 KairosDB 使用 H2 作为数据存储,这样在开发环境下我们就不必配置Cassandra 了。这里我们也以 H2 为例来初步认识一下 KairosDB,这也是 KairosDB 的默认配置。
所以在这个例子里,我们不必修改配置文件,直接启动 KairosDB 即可:
$ bin/kairosdb.sh run
# 或者
$ bin/kairosdb.sh start
其中run参数会以前台运行的方式启动 KairosDB,而start则以后台进程的方式启动 KairosDB。
停止 KairosDB 只需要运行bin/kairosdb.sh stop就可以了。
写入数据
和 OpenTSDB 一样,KairosDB 也支持基于 telnet 和 HTTP API 的方式写入数据。
Telnet
Telnet 的方式数据格式很简单:
put <metric_name> <time-stamp> <value> <tag> <tag>... \n
这里我们就不做演示了。
HTTP API
只需要发送 JSON 数据到 http://localhost:8080/api/v1/datapoints 就可以了。
这是我们写入测试数据的方法:
$ curl -v -H "Content-type: application/json" -X POST  http://localhost:8080/api/v1/datapoints -d '
[{
    "name": "cpu.load.1",
    "timestamp": 1453109876000,
    "type": "double",
    "value": 0.32,
    "tags":{"host":"test-1"}
},
{
    "name": "cpu.load.1",
    "timestamp": 1453109876000,
    "type": "double",
    "value": 0.21,
    "tags":{"host":"test-2"}
}]
'
* Connected to localhost (::1) port 8080 (#0)
> POST /api/v1/datapoints HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
> Content-type: application/json
> Content-Length: 262
>
* upload completely sent off: 262 out of 262 bytes
< HTTP/1.1 204 No Content
< Access-Control-Allow-Origin: *
< Pragma: no-cache
< Cache-Control: no-cache
< Expires: 0
< Content-Type: application/json; charset=UTF-8
< Server: Jetty(8.1.16.v20140903)
<
* Connection #0 to host localhost left intact
从服务器返回结果我们可以看到,HTTP 204 状态码,也是 KairosDB 成功写入数据的结果。
查询数据
同样 KairosDB 提供了查询用 API:
$ curl -H "Content-type: application/json" -X POST  http://localhost:8080/api/v1/datapoints/query -d '
{
  "metrics": [
    {
      "tags": {},
      "name": "cpu.load.1",
      "group_by": [
        {
          "name": JSON"tag",
          "tags": [
            "host"
          ]
        }
      ],
      "aggregators": [
        {
          "name": "sum",
          "align_sampling": true,
          "sampling": {
            "value": "1",
            "unit": "minutes"
          }
        }
      ]
    }
  ],
  "cache_time": 0,
  "start_absolute": 1453046400000,
  "end_absolute": 1453132800000,
  "time_zone": "Asia/Chongqing"
}' | jq .
注意上面命令最后的 jq,这是用来对 JSON 数据进行格式化的工具。
最终结果可能像下面一样:
{
  "queries": [
    {
      "sample_size": 2,
      "results": [
        {
          "name": "cpu.load.1",
          "group_by": [
            {
              "name": "tag",
              "tags": [
                "host"
              ],
              "group": {
                "host": "test-1"
              }
            },
            {
              "name": "type",
              "type": "number"
            }
          ],
          "tags": {
            "host": [
              "test-1"
            ]
          },
          "values": [
            [
              1453109876000,
              0.32
            ]
          ]
        },
        {
          "name": "cpu.load.1",
          "group_by": [
            {
              "name": "tag",
              "tags": [
                "host"
              ],
              "group": {
                "host": "test-2"
              }
            },
            {
              "name": "type",
              "type": "number"
            }
          ],
          "tags": {
            "host": [
              "test-2"
            ]
          },
          "values": [
            [
              1453109876000,
              0.21
            ]
          ]
        }
      ]
    }
  ]
}
WEB UI
KairosDB 自带了一个 Web 界面,你可以通过 http://localhost:8080 访问。不过这个 UI 主要是以开发为目的的,可以看到查询的 JSON 文本,方便调试,比较直观。默认的 UI 使用了 Flot 来画图,如果你愿意,也可以使用 Highcharts 替换。
Library
KairosDB 目前有一个单独的 Java Client,在官网还有一些其他语言的客户端,比如 Python、PHP 等。
由于是 Java 客户端,所以还是很容易上手的。比如写入数据:
MetricBuilder builder = MetricBuilder.getInstance();
builder.addMetric("metric1")
        .addTag("host", "server1")
        .addTag("customer", "Acme")
        .addDataPoint(System.currentTimeMillis(), 10)
        .addDataPoint(System.currentTimeMillis(), 30L);
HttpClient client = new HttpClient("http://localhost:8080");
Response response = client.pushMetrics(builder);
client.shutdown();
读取数据:
QueryBuilder builder = QueryBuilder.getInstance();
builder.setStart(2, TimeUnit.MONTHS)
       .setEnd(1, TimeUnit.MONTHS)
       .addMetric("metric1")
       .addAggregator(AggregatorFactory.createAverageAggregator(5, TimeUnit.MINUTES));
HttpClient client = new HttpClient("http://localhost:8080");
QueryResponse response = client.query(builder);
client.shutdown();
这应该会非常方便,开发起来比 OpenTSDB 要快不少了。
其他API
KairosDB 竟然支持 metric 删除功能,这个功能会有多少人需要呢?
列出 metric 名、tag 列表、列出 tag 值,说不定有人会喜欢,比如在输入框自动提示灯功能,可能需要这些元数据。
列出指标名
这里除了cpu.load.1是我们自己写入的 metric,其余的都是 KairosDB 自己的指标数据。
$ curl http://localhost:8080/api/v1/metricnames | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   501    0   501    0     0  45058      0 --:--:-- --:--:-- --:--:-- 50100
{
  "results": [
    "kairosdb.datastore.query_time",
    "kairosdb.protocol.telnet_request_count",
    "kairosdb.http.ingest_count",
    "kairosdb.datastore.query_row_count",
    "cpu.load.1",
    "kairosdb.protocol.http_request_count",
    "kairosdb.http.ingest_time",
    "kairosdb.jvm.thread_count",
    "kairosdb.jvm.total_memory",
    "kairosdb.jvm.max_memory",
    "kairosdb.metric_counters",
    "kairosdb.jvm.free_memory",
    "kairosdb.datastore.query_sample_size",
    "kairosdb.datastore.query_collisions",
    "kairosdb.http.query_time",
    "kairosdb.http.request_time"
  ]
}
列出 tag key
这个 API 能列出系统中所有的 tag key。不过遗憾的是它不支持只列出某一给定指标的所有 tag key。
$ curl http://localhost:8080/api/v1/tagnames | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    67    0    67    0     0   4188      0 --:--:-- --:--:-- --:--:--  4466
{
  "results": [
    "method",
    "metric_name",
    "query_index",
    "request",
    "host"
  ]
}
列出 tag value
这个 API 能列出系统中所有的 tag value。同样遗憾的是它也不支持只列出某一给定指标的所有 tag value。
所以这两个 API 几乎可以说是然并卵、无鸟用。
$ curl http://localhost:8080/api/v1/tagvalues | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   163    0   163    0     0   5011      0 --:--:-- --:--:-- --:--:--  5093
{
  "results": [
    "1",
    "lius-MacBook-Pro.local",
    "tagnames",
    "/datapoints/query",
    "test-1",
    "test-2",
    "metricnames",
    "query",
    "tags",
    "version",
    "datapoints",
    "putm",
    "cpu.load.1"
  ]
}
总结
KairosDB 毕竟是 OpenTSDB 的一个 fork,因此根本上的功能都差不多,而且随着 OpenTSDB 对 Cassandra 的支持,感觉 KairosDB 相比 OpenTSDB 也没有什么太大的优势。
相关阅读
这是本系列文章的其他部分:
Cloud Insight 集监控、管理、计算、协作、可视化于一身,帮助所有 IT 公司,减少在系统监控上的人力和时间成本投入,让运维工作更加高效、简单。
本文转自 OneAPM 官方博客
时间序列数据库武斗大会之 KairosDB 篇的更多相关文章
- 时序列数据库武斗大会之 OpenTSDB 篇
		
[编者按] 刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融.通信以及Android手机操作系的开发,熟悉Linux及后台开发技术.曾参与翻译过<第一本Docker书> ...
 - 时序列数据库武斗大会之TSDB名录 Part 2
		
[编者按] 刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融.通信以及Android手机操作系的开发,熟悉Linux及后台开发技术.曾参与翻译过<第一本Docker书> ...
 - [转]时序列数据库武斗大会之什么是TSDB
		
由于工作上的关系,最近看了一些关于时序列数据库的东西,当然,我所看的也都是以开源方案为主. 趁着这股热劲还没退,希望能整理一些资料出来.如果正好你也有这方面的需求,那么希望这一系列的介绍能够帮助到你. ...
 - 时序列数据库武斗大会之 TSDB 名录 Part 1
		
[编者按] 刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融.通信以及Android手机操作系的开发,熟悉Linux及后台开发技术.曾参与翻译过<第一本Docker书> ...
 - 时序列数据库武斗大会之什么是 TSDB ?
		
本文选自 OneAPM Cloud Insight 高级工程师刘斌博客 . 刘斌,一个才思敏捷的程序员,<第一本 Docker 书>.<GitHub 入门与实践>等书籍译者,D ...
 - [转帖]时间序列数据库 (TSDB)
		
时间序列数据库 (TSDB) https://www.jianshu.com/p/31afb8492eff 0.3392019.01.28 10:51:33字数 5598阅读 4030 背景 2017 ...
 - 时间序列数据库(TSDB)初识与选择(InfluxDB、OpenTSDB、Druid、Elasticsearch对比)
		
背景 这两年互联网行业掀着一股新风,总是听着各种高大上的新名词.大数据.人工智能.物联网.机器学习.商业智能.智能预警啊等等. 以前的系统,做数据可视化,信息管理,流程控制.现在业务已经不仅仅满足于这 ...
 - 2016 DTCC(中国数据库技术大会)
		
上周去参加了2016 DTCC(数据库技术大会),会议总共持续3天,议题非常多,我这里搜集了最新的公开的PPT内容,有兴趣的同学可以下载看看,PPT合集下载链接为:http://pan.baidu.c ...
 - 时间序列数据库选型——本质是列存储,B-tree索引,抑或是搜索引擎中的倒排索引
		
时间序列数据库最多,使用也最广泛.一般人们谈论时间序列数据库的时候指代的就是这一类存储.按照底层技术不同可以划分为三类. 直接基于文件的简单存储:RRD Tool,Graphite Whisper.这 ...
 
随机推荐
- 银联接口测试——详细(JAVA)
			
准备材料 1.注册账号 https://open.unionpay.com/ajweb/register?locale=zh_CN 2.▼登录账号 -->帮助中心--> 下载,选择网关支付 ...
 - float闭合(清除浮动)和CSS HACK
			
一.float 闭合(清除浮动) 将以下代码加入Global CSS 中,给需要闭合的div加上 class="clearfix" 即可,屡试不爽. <style>.c ...
 - 通信协议之HTTP,UDP,TCP协议
			
1.UDP,TCP,HTTP之间的关系 tcp/ip是个协议组,它可以分为4个层次,即网路接口层,网络层,传输层,以及应用层, 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协 ...
 - jquery弹出关闭遮罩层实例
			
jquery弹出关闭遮罩层实例. 代码如下: <!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" & ...
 - How to change comment
			
AX2009 // USR Changed on 2013-07-10 at 12:57:46 by 7519 - Begin // USR Changed on 2013-07-10 at 12:5 ...
 - JNI 学习笔记
			
JNI是Java Native Interface的缩写,JNI是一种机制,有了它就可以在java程序中调用其他native代码,或者使native代码调用java层的代码.也 就是说,有了JNI我们 ...
 - Python中Cookie的处理(一)Cookie库
			
Cookie用于服务器实现会话,用户登录及相关功能时进行状态管理.要在用户浏览器上安装cookie,HTTP服务器向HTTP响应添加类似以下内容的HTTP报头: Set-Cookie:session= ...
 - 12、在XAML中定义处理程序
			
<Grid> <Button x:Name="btnTest" Width="120" Height="36" Conte ...
 - 增强的PuTTY 以及 自定义主题
			
PuTTY很早之前就没有更新了(0.62),因为都是开源的所以有人branch出来做了增强,如这个PuTTY tray,增加了超链等功能: https://puttytray.goeswhere.co ...
 - 博主教你制作类似9patch效果的iOS图片拉伸
			
下面张图片,本来是设计来做按钮背景的: button.png,尺寸为:24x60 现在我们把它用作为按钮背景,按钮尺寸是150x50: // 得到view的尺寸 CGSize viewSize = ...