時間序列資料庫(TSDB)初識與選擇(InfluxDB、OpenTSDB、Druid、Elasticsearch對比)
背景
這兩年網際網路行業掀著一股新風,總是聽著各種高大上的新名詞。大資料、人工智慧、物聯網、機器學習、商業智慧、智慧預警啊等等。
以前的系統,做資料視覺化,資訊管理,流程控制。現在業務已經不僅僅滿足於這種簡單的管理和控制了。資料視覺化分析,大資料資訊挖掘,統計預測,建模模擬,智慧控制成了各種業務的追求。
“所有一切如淚水般消失在時間之中,時間正在死去“,以前我們利用網際網路解決現實的問題。現在我們已經不滿足於現實,資料將連線成時間序列,可以往前可以觀其歷史,揭示其規律性,往後可以把握其趨勢性,預測其走勢。
於是,我們開始儲存大量時間相關的資料(如日誌,使用者行為等),並總結出這些資料的結構特點和常見使用場景,不斷改進和優化,創造了一種新型的資料庫分類——時間序列資料庫(Time Series Database).
時間序列模型
時間序列資料庫主要用於指處理帶時間標籤(按照時間的順序變化,即時間序列化)的資料,帶時間標籤的資料也稱為時間序列資料。
每個時序點結構如下:
-
timestamp: 資料點的時間,表示資料發生的時間。
-
metric: 指標名,當前資料的標識,有些系統中也稱為name。
-
value: 值,資料的數值,一般為double型別,如cpu使用率,訪問量等數值,有些系統一個數據點只能有一個value,多個value就是多條時間序列。有些系統可以有多個value值,用不同的key表示
-
tag: 附屬屬性。
實現
比如我想記錄一系列感測器的時間序列資料。資料結構如下:
* 識別符號:device_id,時間戳
* 元資料:location_id,dev_type,firmware_version,customer_id
* 裝置指標:cpu_1m_avg,free_mem,used_mem,net_rssi,net_loss,電池
* 感測器指標:溫度,溼度,壓力,CO,NO2,PM10
如果使用傳統RDBMS儲存,建一張如下結構的表即可:
如此便是一個最簡單的時間序列庫了。但這只是滿足了資料模型的需要。我們還需要在效能,高效儲存,高可用,分散式和易用性上做更多的事情。
大家可以思考思考,如果讓你自己來實現一個時間序列資料庫,你會怎麼設計,你會考慮哪些效能上的優化,又如何做到高可用,怎樣做到簡單易用。
Timescale
這個資料庫其實就是一個基於傳統關係型資料庫postgresql改造的時間序列資料庫。瞭解postgresql的同學都知道,postgresql是一個強大的,開源的,可擴充套件性特別強的一個數據庫系統。
於是timescale.inc開發了Timescale,一款相容sql的時序資料庫, 底層儲存架構在postgresql上。 作為一個postgresql的擴充套件提供服務。其特點如下:
基礎:
-
PostgreSQL原生支援的所有SQL,包含完整SQL介面(包括輔助索引,非時間聚合,子查詢,JOIN,視窗函式)
-
用PostgreSQL的客戶端或工具,可以直接應用到該資料庫,不需要更改。
-
時間為導向的特性,API功能和相應的優化。
-
可靠的資料儲存。
擴充套件:
-
透明時間/空間分割槽,用於放大(單個節點)和擴充套件
-
高資料寫入速率(包括批量提交,記憶體中索引,事務支援,資料備份支援)
-
單個節點上的大小合適的塊(二維資料分割槽),以確保即使在大資料量時即可快速讀取。
-
塊之間和伺服器之間的並行操作
劣勢:
-
因為TimescaleDB沒有使用列存技術,它對時序資料的壓縮效果不太好,壓縮比最高在4X左右
-
目前暫時不完全支援分散式的擴充套件(正在開發相關功能),所以會對伺服器單機效能要求較高
其實大家都可以去深入瞭解一下這個資料庫。對RDBMS我們都很熟悉,瞭解這個可以讓我們對RDBMS有更深入的瞭解,瞭解其實現機制,儲存機制。在對時間序列的特殊化處理之中,我們又可以學到時間序列資料的特點,並學習到如何針對時間序列模型去優化RDBMS。
之後我們也可以寫一篇文章來深入的瞭解一下這個資料庫的特點和實現。
Influxdb
Influxdb是業界比較流行的一個時間序列資料庫,特別是在IOT和監控領域十分常見。其使用go語言開發,突出特點是效能。
特性:
-
高效的時間序列資料寫入效能。自定義TSM引擎,快速資料寫入和高效資料壓縮。
-
無額外儲存依賴。
-
簡單,高效能的HTTP查詢和寫入API。
-
以外掛方式支援許多不同協議的資料攝入,如:graphite,collectd,和openTSDB
-
SQL-like查詢語言,簡化查詢和聚合操作。
-
索引Tags,支援快速有效的查詢時間序列。
-
保留策略有效去除過期資料。
-
連續查詢自動計算聚合資料,使頻繁查詢更有效。
Influxdb已經將分散式版本轉為閉源。所以在分散式叢集這塊是一個弱點,需要自己實現。
OpenTSDB
The Scalable Time Series Database. 開啟OpenTSDB官網,第一眼看到的就是這句話。其將Scalable作為其重要的特點。OpenTSDB執行在Hadoop和HBase上,其充分利用HBase的特性。通過獨立的Time Series Demon(TSD)提供服務,所以它可以通過增減服務節點來輕鬆擴縮容。
-
Opentsdb是一個基於Hbase的時間序列資料庫(新版也支援Cassandra)。
其基於Hbase的分散式列儲存特性實現了資料高可用,高效能寫的特性。受限於Hbase,儲存空間較大,壓縮不足。依賴整套HBase, ZooKeeper
-
採用無模式的tagset資料結構(sys.cpu.user 1436333416 23 host=web01 user=10001)
結構簡單,多value查詢不友好
-
HTTP-DSL查詢
OpenTSDB在HBase上針對TSDB的表設計和RowKey設計是值得我們深入學習的一個特點。有興趣的同學可以找一些詳細的資料學習學習。
Druid
Druid是一個實時線上分析系統(LOAP)。其架構融合了實時線上資料分析,全文檢索系統和時間序列系統的特點,使其可以滿足不同使用場景的資料儲存需求。
-
採用列式儲存:支援高效掃描和聚合,易於壓縮資料。
-
可伸縮的分散式系統:Druid自身實現可伸縮,可容錯的分散式叢集架構。部署簡單。
-
強大的並行能力:Druid各叢集節點可以並行地提供查詢服務。
-
實時和批量資料攝入:Druid可以實時攝入資料,如通過Kafka。也可以批量攝入資料,如通過Hadoop匯入資料。
-
自恢復,自平衡,易於運維:Druid自身架構即實現了容錯和高可用。不同的服務節點可以根據響應需求新增或減少節點。
-
容錯架構,保證資料不丟失:Druid資料可以保留多副本。另外可以採用HDFS作為深度儲存,來保證資料不丟失。
-
索引:Druid對String列實現反向編碼和Bitmap索引,所以支援高效的filter和groupby。
-
基於時間分割槽:Druid對原始資料基於時間做分割槽儲存,所以Druid對基於時間的範圍查詢將更高效。
-
自動預聚合:Druid支援在資料攝入期就對資料進行預聚合處理。
Druid架構蠻複雜的。其按功能將整個系統細分為多種服務,query、data、master不同職責的系統獨立部署,對外提供統一的儲存和查詢服務。其以分散式叢集服務的方式提供了一個底層資料儲存的服務。
Druid在架構上的設計很值得我們學習。如果你不僅僅對時間序列儲存感興趣,對分散式叢集架構也有興趣,不妨看看Druid的架構。另外Druid在segment(Druid的資料儲存結構)的設計也是一大亮點,既實現了列式儲存,又實現了反向索引。
Elasticsearch
Elasticsearch 是一個分散式的開源搜尋和分析引擎,適用於所有型別的資料,包括文字、數字、地理空間、結構化和非結構化資料。Elasticsearch 在 Apache Lucene 的基礎上開發而成,由 Elasticsearch N.V.(即現在的 Elastic)於 2010 年首次釋出。Elasticsearch 以其簡單的 REST 風格 API、分散式特性、速度和可擴充套件性而聞名。
Elasticsearch以ELK stack被人所熟知。許多公司基於ELK搭建日誌分析系統和實時搜尋系統。之前我們在ELK的基礎上開始開發metric監控系統。即想到了使用Elasticsearch來儲存時間序列資料庫。對Elasticserach的mapping做相應的優化,使其更適合儲存時間序列資料模型,收穫了不錯的效果,完全滿足了業務的需求。後期發現Elasticsearch新版本竟然也開始釋出Metrics元件和APM元件,並大量的推廣其全文檢索外,對時間序列的儲存能力。真是和我們當時的想法不謀而合。
Elasticsearch的時序優化可以參考一下這篇文章:《elasticsearch-as-a-time-series-data-store》
也可以去了解一下Elasticsearch的Metric元件:Elastic Metrics
Beringei
Beringei是Facebook在2017年最新開源的一個高效能記憶體時序資料儲存引擎。其具有快速讀寫和高壓縮比等特性。
2015年Facebook發表了一篇論文《Gorilla: A Fast, Scalable, In-Memory Time Series Database 》,Beringei正是基於此想法實現的一個時間序列資料庫。
Beringei使用Delta-of-Delta演算法儲存資料,使用XOR編碼壓縮數值。使其可以用很少的記憶體即可儲存下大量的資料。
如何選擇一個適合自己的時間序列資料庫
-
Data model
時間序列資料模型一般有兩種,一種無schema,具有多tag的模型,還有一種name、timestamp、value型。前者適合多值模式,對複雜業務模型更適合。後者更適合單維資料模型。
-
Query language
目前大部分TSDB都支援基於HTTP的SQL-like查詢。
-
Reliability
可用性主要體現在系統的穩定高可用上,以及資料的高可用儲存上。一個優秀的系統,應該有一個優雅而高可用的架構設計。簡約而穩定。
-
Performance
效能是我們必須考慮的因素。當我們開始考慮更細分領域的資料儲存時,除了資料模型的需求之外,很大的原因都是通用的資料庫系統在效能上無法滿足我們的需求。大部分時間序列庫傾向寫多讀少場景,使用者需要平衡自身的需求。下面會有一份各庫的效能對比,大家可以做一個參考。
-
Ecosystem
我一直認為生態是我們選擇一個開源元件必須認真考慮的問題。一個生態優秀的系統,使用的人多了,未被發現的坑也將少了。另外在使用中遇到問題,求助於社群,往往可以得到一些比較好的解決方案。另外好的生態,其周邊邊界系統將十分成熟,這讓我們在對接其他系統時會有更多成熟的方案。
-
Operational management
易於運維,易於操作。
-
Company and support
一個系統其背後的支援公司也是比較重要的。背後有一個強大的公司或組織,這在專案可用性保證和後期維護更新上都會有較大的體驗。
效能對比
Timescale | InfluxDB | OpenTSDB | Druid | Elasticsearch | Beringei | |
---|---|---|---|---|---|---|
write(single node) | 15K/sec | 470k/sec | 32k/sec | 25k/sec | 30k/sec | 10m/sec |
write(5 node) | 128k/sec | 100k/sec | 120k/sec |
總結
可以按照以下需求自行選擇合適的儲存:
-
小而精,效能高,資料量較小(億級): InfluxDB
-
簡單,資料量不大(千萬級),有聯合查詢、關係型資料庫基礎:timescales
-
資料量較大,大資料服務基礎,分散式叢集需求: opentsdb、KairosDB
-
分散式叢集需求,olap實時線上分析,資源較充足:druid
-
效能極致追求,資料冷熱差異大:Beringei
-
兼顧檢索載入,分散式聚合計算: elsaticsearch
-
如果你兼具索引和時間序列的需求。那麼Druid和Elasticsearch是最好的選擇。其效能都不差,同時滿足檢索和時間序列的特性,並且都是高可用容錯架構。
最後
之後我們可以來深入瞭解一兩個TSDB,比如Influxdb,OpenTSDB,Druid,Elasticsearch等。並可以基於此學習一下行儲存與列儲存的不同,LSM的實現原理,數值資料的壓縮,MMap提升讀寫效能的知識等。
連結:
十分鐘瞭解Apache Druid