時序列資料庫武鬥大會之 OpenTSDB 篇
【編者按】 劉斌,OneAPM後端研發工程師,擁有10多年程式設計經驗,參與過大型金融、通訊以及Android手機操作系的開發,熟悉Linux及後臺開發技術。曾參與翻譯過《第一本Docker書》、《GitHub入門與實踐》、《Web應用安全權威指南》、《WEB+DB PRESS》、《Software Design》等書籍,也是Docker入門與實踐課程主講人。本文所闡述的「時間序列資料庫」,系筆者所負責產品 Cloud Insight 對效能指標進行聚合、分組、過濾過程中的梳理和總結。
什麼是 OpenTSDB
OpenTSDB ,可以認為是一個時系列資料(庫),它基於HBase儲存資料,充分發揮了HBase的分散式列儲存特性,支援數百萬每秒的讀寫,它的特點就是容易擴充套件,靈活的tag機制。
架構簡介
這裡我們簡單看一下它的架構,如下圖所示:
其最主要的部件就是TSD了,這是接收資料並儲存到HBase處理的核心所在。而帶有C(collector)標誌的Server,則是資料採集源,將資料發給 TSD服務。
安裝 OpenTSDB
為了安裝 OpenTSDB ,都需要以下條件和軟體:
Linux作業系統
JRE 1.6 or later
HBase 0.92 or later
安裝GnuPlot
如果你還想使用自帶的介面,則需要安裝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 的重要概念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)兩條記錄。
我們一共看到了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,每秒鐘的資料都會存為一列,大大提高查詢的速度。
反過來,從uid到name也一樣,比如找uid為\x00\x00\x02的tagk,我們從上面結果可以看到,該row key(\x00\x00\x02)有4列,而column=name:tagk的value就是user,非常簡單直觀。
重要:我們看到,上面的metric也好,tagk或者tagv也好,uid只有3個位元組,這是 OpenTSDB 的預設配置,三個位元組,應該能表示1600多萬的不同資料,這對metric名或者tagk來說足夠長了,對tagv來說就不一定了,比如tagv是ip地址的話,或者電話號碼,那麼這個欄位就不夠長了,這時可以通過修改原始碼來重新編譯 OpenTSDB 就可以了,同時要注意的是,重編以後,老資料就不能直接使用了,需要匯出後重新匯入。
tsdb-meta:後設資料表
我們再看下第三個表tsdb-meta,這是用來儲存時間序列索引和後設資料的表。這也是一個可選特性,預設是不開啟的,可以通過配置檔案來啟用該特性,這裡不做特殊介紹了。
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 官方部落格
相關文章
- 時間序列資料庫武鬥大會之 KairosDB 篇資料庫AIROS
- 資料庫大會資料庫
- OpenTSDB 資料儲存詳解
- 時間序列化資料庫選型?時序資料庫的選擇?資料庫
- PHP 批鬥大會之缺失的異常PHP
- 大資料圖資料庫之TAO資料庫大資料資料庫
- 從零寫一個時間序列資料庫資料庫
- 大資料技術之資料採集篇大資料
- 京東城市時空資料引擎JUST亮相中國資料庫技術大會資料庫
- OpenTSDB 安裝 啟動 資料儲存
- 首次!中西方資料庫大咖“時空對話”,為中國分散式資料庫開發者大會打call資料庫分散式
- 1 小時學會 MySQL 資料庫MySql資料庫
- 同時使用資料庫鏈和序列時應注意的幾點資料庫
- 資料庫大會參會記(2)---奶爸們的聚首大會~~資料庫
- 3.15 資料庫吐槽大會資料庫
- 資料庫定時備份linux篇資料庫Linux
- python序列資料型別之序列資料的基本操作Python資料型別
- 達夢資料庫必知必會-DCA篇資料庫
- 2011資料庫技術大會資料資料庫
- 同時使用資料庫鏈和序列時應注意的幾點(轉)資料庫
- Oracle資料庫開發——序列Oracle資料庫
- 開源資料庫大會技術分享資料庫
- 大資料分析筆記 (7) - 時間序列分析(Time Series Analysis)大資料筆記
- 將VAE用於時間序列:生成時間序列的合成資料
- 北京雲棲大會workshop:《資料處理:資料建模與加工》篇
- 時間序列資料的處理
- 實時資料庫與時序資料庫資料庫
- 第一篇之認識大資料大資料
- 武林大會之國產資料庫風雲榜-2021年11月資料庫
- 2013年中國資料庫大會PPT資料庫
- 4篇論文入選資料庫頂會,騰訊雲突破資料庫效能瓶頸資料庫
- 大資料開發之Mapper Reduce序列化案例實操大資料APP
- 大資料應用場景之戰-行業篇大資料行業
- 效能優化之資料庫篇5-分庫分表與資料遷移優化資料庫
- 資料庫中會話休眠一段時間資料庫會話
- OpenTsDb安裝
- 2015中國資料庫技術大會資料庫
- 2011年資料庫大會紀行資料庫