時間序列數據庫武鬥大會之 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 官方博客

相關文章
相關標籤/搜索