時序列數據庫武鬥大會之 OpenTSDB 篇

【編者按】 劉斌OneAPM後端研發工程師,擁有10多年編程經驗,參與過大型金融、通訊以及Android手機操做系的開發,熟悉Linux及後臺開發技術。曾參與翻譯過《第一本Docker書》、《GitHub入門與實踐》、《Web應用安全權威指南》、《WEB+DB PRESS》、《Software Design》等書籍,也是Docker入門與實踐課程主講人。本文所闡述的「時間序列數據庫」,系筆者所負責產品 Cloud Insight性能指標進行聚合、分組、過濾過程當中的梳理和總結。html

什麼是 OpenTSDB

OpenTSDB ,能夠認爲是一個時系列數據(庫),它基於HBase存儲數據,充分發揮了HBase的分佈式列存儲特性,支持數百萬每秒的讀寫,它的特色就是容易擴展,靈活的tag機制。java

架構簡介

這裏咱們簡單看一下它的架構,以下圖所示:mysql

時序列數據庫武鬥大會之 OpenTSDB 篇

其最主要的部件就是TSD了,這是接收數據並存儲到HBase處理的核心所在。而帶有C(collector)標誌的Server,則是數據採集源,將數據發給 TSD服務。git

安裝 OpenTSDB

爲了安裝 OpenTSDB ,都須要如下條件和軟件:github

  • Linux操做系統web

  • JRE 1.6 or latersql

  • HBase 0.92 or laterdocker

  • 安裝GnuPlotshell

若是你還想使用自帶的界面,則須要安裝GnuPlot 4.2及之後版本,以及gd和gd-devel等。這裏咱們選擇了GnuPlot 5.0.1的版本。數據庫

根據狀況執行(沒有就裝),安裝所需軟件

$ sudo yum install -y gd gd-devel libpng libpng-devel

以後安裝GnuPlot:

$ tar zxvf gnuplot-5.0.1.tar.gz$ cd gnuplot-5.0.1$ ./configure$ make$ sudo make install

安裝HBase

首先,確保設置了JAVA_HOME:

$ echo $JAVA_HOME/usr

這個很少說了,很是簡單,只須要按照 https://hbase.apache.org/book.html#quickstart 這裏所說,下載、解壓、修改配置文件、啓動便可。

這時候,再設置HBASE_HOME:

$ echo $HBASE_HOME/opt/hbase-1.0.1.1

以後即可啓動hbase:

$ /opt/hbase-1.0.1.1/bin/start-hbase.sh
starting master, logging to /opt/hbase-1.0.1.1/logs/hbase-vagrant-master-localhost.localdomain.out

安裝 OpenTSDB

這個也很簡單,若是build失敗,那確定是缺乏Make或者Autotools等東西,用包管理器安裝便可。

$ git clone git://github.com/OpenTSDB/opentsdb.git$ cd opentsdb$ ./build.sh

建立表OpenTSDB所須要的表結構:

$ env COMPRESSION=NONE ./src/create_table.sh2016-01-08 06:17:58,045 WARN [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform… using builtin-java classes where applicable
HBase Shell; enter ‘help‘ for list of supported commands.
Type 「exit」 to leave the HBase Shell
Version 1.0.1.1, re1dbf4df30d214fca14908df71d038081577ea46, Sun May 17 12:34:26 PDT 2015create ‘tsdb-uid’,
{NAME => ‘id’, COMPRESSION => ‘NONE’, BLOOMFILTER => ‘ROW’},
{NAME => ‘name’, COMPRESSION => ‘NONE’, BLOOMFILTER => ‘ROW’}0 row(s) in 1.3180 secondsHbase::Table – tsdb-uidcreate ‘tsdb’,
{NAME => ‘t’, VERSIONS => 1, COMPRESSION => ‘NONE’, BLOOMFILTER => ‘ROW’}0 row(s) in 0.2400 secondsHbase::Table – tsdbcreate ‘tsdb-tree’,
{NAME => ‘t’, VERSIONS => 1, COMPRESSION => ‘NONE’, BLOOMFILTER => ‘ROW’}0 row(s) in 0.2160 secondsHbase::Table – tsdb-treecreate ‘tsdb-meta’,
{NAME => ‘name’, COMPRESSION => ‘NONE’, BLOOMFILTER => ‘ROW’}0 row(s) in 0.4480 secondsHbase::Table – tsdb-meta

在habse shell裏,能夠看到表已經建立成功。

> listTABLE
tsdb
tsdb-metatsdb-treetsdb-uid4 row(s) in 0.0160 seconds

表建立以後,便可啓動tsd服務,只須要運行以下命令:

$ build/tsdb tsd

若是看到輸出:

2016-01-09 05:51:10,875 INFO [main] TSDMain: Ready to serve on /0.0.0.0:4242

便可認爲啓動成功。

保存數據到OpenTSDB.

在安裝並啓動全部服務以後,咱們就來嘗試發送1條數據吧。

最簡單的保存數據方式就是使用telnet。

$ telnet localhost 4242put sys.cpu.user 1436333416 23 host=web01 user=10001

這時,從 OpenTSDB 自帶界面均可以看到這些數據。 因爲sys.cpu.sys的數據只有一條,因此 OpenTSDB 只能看到一個點。

下圖爲 OpenTSDB 自帶的查詢界面,訪問http://localhost:4242便可。

時序列數據庫武鬥大會之 OpenTSDB 篇

OpenTSDB中的數據存儲結構

咱們來看看 OpenTSDB 的重要概念uid,先從HBase中存儲的數據開始吧,咱們來看一下它都有哪些表,以及這些表都是幹什麼的。

tsdb:存儲數據點

hbase(main):003:0> scan 'tsdb'
ROW                           COLUMN+CELL  

 \x00\x00\x01U\x9C\xAEP\x00\x column=t:q\x80,timestamp=1436350142588, value=\x17   
 
 00\x01\x00\x00\x01\x00\x00\x   
 
 02\x00\x00\x02  
 
1 row(s) in 0.2800 seconds

能夠看出,該表只有一條數據,咱們先無論rowid,只來看看列,只有一列,值爲0x17,即十進制23,即該metric的值。

左面的row key則是 OpenTSDB 的特色之一,其規則爲:

metric + timestamp + tagk1 + tagv1… + tagkN + tagvN

以上屬性值均爲對應名稱的uid。

咱們上面添加的metric爲:

sys.cpu.user 1436333416 23 host=web01 user=10001

一共涉及到5個uid,即名爲sys.cpu.user的metric,以及host和user兩個tagk及其值web01和10001。

上面數據的row key爲:

\x00\x00\x01U\x9C\xAEP\x00\x00\x01\x00\x00\x01\x00\x00\x02\x00\x00\x02

具體這個row key是怎麼算出來的,咱們來看看tsdb-uid表。

tsdb-uid:存儲name和uid的映射關係

下面tsdb-uid表的數據,各行之間人爲加了空行,爲方便顯示。

tsdb-uid用來保存名字和UID(metric,tagk,tagv)之間互相映射的關係,都是成組出現的,即給定一個name和uid,會保存(name,uid)和(uid,name)兩條記錄。

時序列數據庫武鬥大會之 OpenTSDB 篇

咱們一共看到了8行數據。

前面咱們在tsdb表中已經看到,metric數據的row key爲\x00\x00\x01U\x9C\xAEP\x00\x00\x01\x00\x00\x01\x00\x00\x02\x00\x00\x02 ,咱們將其分解下,用+號連起來(從name到uid的映射爲最後5行):

\x00\x00\x01 + U + \x9C\xAE + P + \x00\x00\x01 + \x00\x00\x01 + \x00\x00\x02  + \x00\x00\x02
sys.cpu.user       1436333416           host    =      web01          user     =    10001

能夠看出,這和咱們前面說到的row key的構成方式是吻合的。

須要着重說明的是時間戳的存儲方式。
雖然咱們指定的時間是以秒爲單位的,可是,row key中用到的倒是以一小時爲單位的,即:1436333416 – 1436333416 % 3600 = 1436331600

1436331600轉換爲16進制,即0x55 0x9c 0xae 0x50,而0x55即大寫字母U,0x50爲大寫字母P,這就是4個字節的時間戳存儲方式。相信下面這張圖能幫助各位更好理解這個意思,即一小時只有一個row key,每秒鐘的數據都會存爲一列,大大提升查詢的速度。

時序列數據庫武鬥大會之 OpenTSDB 篇

反過來,從uid到name也同樣,好比找uid爲x00x00x02的tagk,咱們從上面結果能夠看到,該row key(x00x00x02)有4列,而column=name:tagk的value就是user,很是簡單直觀。

重要:咱們看到,上面的metric也好,tagk或者tagv也好,uid只有3個字節,這是 OpenTSDB 的默認配置,三個字節,應該能表示1600多萬的不一樣數據,這對metric名或者tagk來講足夠長了,對tagv來講就不必定了,好比tagv是ip地址的話,或者電話號碼,那麼這個字段就不夠長了,這時能夠經過修改源代碼來從新編譯 OpenTSDB 就能夠了,同時要注意的是,重編之後,老數據就不能直接使用了,須要導出後從新導入。

tsdb-meta:元數據表

咱們再看下第三個表tsdb-meta,這是用來存儲時間序列索引和元數據的表。這也是一個可選特性,默認是不開啓的,能夠經過配置文件來啓用該特性,這裏不作特殊介紹了。

時序列數據庫武鬥大會之 OpenTSDB 篇

tsdb-tree:樹形表

第4個表是tsdb-tree,用來以樹狀層次關係來表示metric的結構,只有在配置文件開啓該特性後,纔會使用此表,這裏咱們不介紹了,能夠本身嘗試。

經過HTTP接口保存數據

保存數據除了咱們前面用到的telnet方式,也能夠選擇HTTP API或者批量導入工具

import( http://opentsdb.net/docs/build/html/user_guide/cli/import.html )

這裏咱們再對HTTP API進行簡單示例說明。

假設咱們有以下數據,保存爲文件mysql.json:

[
    {
        "metric": "mysql.innodb.row_lock_time",
        "timestamp": 1435716527,
        "value": 1234,
        "tags": {
           "host": "web01",
           "dc": "beijing"        }    },
    {
        "metric": "mysql.innodb.row_lock_time",
        "timestamp": 1435716529,
        "value": 2345,
        "tags": {
           "host": "web01",
           "dc": "beijing"        }    },
    {
        "metric": "mysql.innodb.row_lock_time",
        "timestamp": 1435716627,
        "value": 3456,
        "tags": {
           "host": "web02",
           "dc": "beijing"        }    },
    {
        "metric": "mysql.innodb.row_lock_time",
        "timestamp": 1435716727,
        "value": 6789,
        "tags": {
           "host": "web01",
           "dc": "tianjin"        }    }
]

以後執行以下命令:

$ curl -X POST -H 「Content-Type: application/json」 http://localhost:4242/api/put -d @mysql.json

便可將數據保存到 OpenTSDB 了。

查詢數據

看完了如何保存數據,咱們再來看看如何查詢數據。

查詢數據可使用query接口,它既可使用get的query string方式,也可使用post方式以JSON格式指定查詢條件,這裏咱們之後者爲例,對剛纔保存的數據進行說明。

首先,保存以下內容爲search.json:

{
    "start": 1435716527,
    "queries": [
        {
            "metric": "mysql.innodb.row_lock_time",
            "aggregator": "avg",
            "tags": {
                "host": "*",
                "dc": "beijing"            }        }
    ]}

執行以下命令進行查詢:

$ curl -s -X POST -H "Content-Type: application/json" http://localhost:4242/api/query -d @search.json | jq .
[
  {    "metric": "mysql.innodb.row_lock_time",    "tags": {      "host": "web01",      "dc": "beijing"
    },    "aggregateTags": [],    "dps": {      "1435716527": 1234,      "1435716529": 2345
    }
  },
  {    "metric": "mysql.innodb.row_lock_time",    "tags": {      "host": "web02",      "dc": "beijing"
    },    "aggregateTags": [],    "dps": {      "1435716627": 3456
    }
  }
]

能夠看出,咱們保存了dc=tianjin的數據,可是並無在此查詢中返回,這是由於,咱們指定了dc=beijing這一條件。

值得注意的是,tags參數在新版本2.2中,將不被推薦,取而代之的是filters參數。

總結

能夠看出來, OpenTSDB 仍是很是容易上手的,尤爲是單機版,安裝也很簡單。有HBase做爲後盾,查詢起來也很是快,不少大公司,相似雅虎等,也都在用此軟件。

可是,大規模用起來,多個TDB以及多存儲節點等,應該都須要專業、細心的運維工做了。

相關閱讀

這是本系列文章的其餘部分:

Cloud Insight 集監控、管理、計算、協做、可視化於一身,幫助全部 IT 公司,減小在系統監控上的人力和時間成本投入,讓運維工做更加高效、簡單。

本文轉自 OneAPM 官方博客

相關文章
相關標籤/搜索