时间序列数据库武斗大会之 KairosDB 篇

【编者按】
刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融、通讯以及Android手机操做系的开发,熟悉Linux及后台开发技术。曾参与翻译过《第一本Docker书》、《GitHub入门与实践》、《Web应用安全权威指南》、《WEB+DB PRESS》、《Software Design》等书籍,也是Docker入门与实践课程主讲人。本文所阐述的「时间序列数据库」,系笔者所负责产品 Cloud Insight 对性能指标进行聚合、分组、过滤过程当中的梳理和总结。html

今天咱们来介绍一下 KairosDB.git

按照官方的说明,KairosDB 是一个 “Fast Time Series Database on Cassandra”,即基于 Cassandra 的高速时序列数据库。github

特色

数据采集

数据能够经过多种协议写入 KairosDB,好比 Telnet 的按行写入,HTTP API,Graphite 以及批处理导入。此外,还可使用或者本身编写插件。数据库

存储

KairosDB 采用了 Cassandra 做为数据存储方式,Cassandra 也是一个比较流行的NoSQL数据库,不少开源软件基于此数据库。编程

Rest API

KairosDB 提供了 REST API,已完成对 metric 名称,tag 等的查询,固然,也少不了存储和查询数据点(data points)。json

自定义数据类型(Custom Data)

KairosDB 支持存储和聚合自定义数据类型。默认状况下 KairosDB 支持 long、double 和字符串的 value,这比 OpenTSDB 要丰富一些。后端

分组和聚合

做为数据分析系统,分组和聚合则是必不可少的功能。 KairosDB的聚合(也就是down samples)功能,支持的标准函数有 min、max、sum、count、mean、histogram、gaps 等,并且都很是实用。api

好比 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 官方博客

相关文章
相关标签/搜索