時序數據庫 Apache-IoTDB 源碼解析之前言(一)

IoTDB 是一款時序數據庫,相關競品有 KairosdbInfluxDBTimescaleDB等,主要使用場景是在物聯網相關行業,如:車聯網、風力發電、地鐵、飛機監控等等,具體應用案例及公司詳情可以查看:IoTDB在實際公司中的使用信息收集

IoTDB 模塊主要分爲ClientJDBCServerTsFileGrafanaDistribution 以及各種生態的連接器。整個系列的文章會從行業背景開始講起,瞭解一個行業具體的使用場景,然後介紹 TsFile 是以什麼樣的格式來保存數據的,再介紹 Server 裏怎樣完成一次查詢,最後在介紹一條完 整的 SQL是怎樣從 Client 使用 JDBC 到 Server 直至返回具體結果。如果有能力的話再介紹一下集羣的一些內容和工作方式。

打一波廣告本人專注車聯網領域多年,現任四維智聯架構師。目前正在參與 IoTDB 社區,有志同道合的同伴歡迎加微信:liutaohua001

歡迎大家訪問 IoTDB 倉庫,求一波 Star 。

這一章主要想聊一聊:

  1. 爲什麼重複造輪子,從物聯網行業的數據特點到 IoTDB 的發展過程

  2. 這個輪子造的怎麼樣,IoTDB 和競品測試對比

時序數據

我個人理解時序數據是基於時間維度的同一個物體或概念的值構成的一個序列數據。在傳統關係型數據庫中,例如 MySQL,我們通常會放置一個自增的 Id 列作爲主鍵標識,如下:

Id 人名 體溫 測量時間
1 張三 36.5 2020-02-06 9:00:00
2 李四 36.9 2020-02-06 9:00:00
3 王五 36.7 2020-02-06 9:00:00
4 張三 36.3 2020-02-06 9:30:00
5 張三 36.9 2020-02-06 11:00:00

上面的表結構就是一個時序數據,將表結構做個變形更容易理解:

時間戳 人名 體溫
1580950800 張三 36.5
1580950800 李四 36.9
1580950800 王五 36.7
1580952600 張三 36.3
1580958000 張三 36.9

如果把時間作爲一個唯一鍵對齊展示,能夠更像時序數據一些,這也是 IoTDB 中查詢結果的展示方式:

時間戳 張三 李四 王五
1580950800 36.5 36.9 36.7
1580952600 36.3 NULL NULL
1580958000 36.9 NULL NULL

這裏可能會存在疑問就是假如人數是逐漸增加的,那麼是動態創建列呢?還是提前創建足夠多的列?這個問題等後面文章有機會繼續介紹

物聯網

物聯網的特點是都會存在一個或多個設備,他們以各種各樣的形式組織到一起,用來觀測或記錄同一時間裏相同環境所產生的數據。下面的介紹中,使用由簡單到複雜的數據逐步介紹在物聯網行業中,通用的一些問題和方向。

1.基本存儲

假如我是一個公司,對外播報北京、天津、上海三地的溫度數據,從而實現盈利。

時間戳 北京 天津 上海
1580950800 20.5 22.9 21.7
1580952600 20.5 NULL 22.9
1580958000 20.5 21.7 22.9

2.保證數據質量

數據保證的質量是多方面的,一步一步介紹。

2.1 更多設備

首先可以看到上面數據是存在 NULL 值的,這個 NULL 值有可能是因爲當時設備所在的區域停電了,所以並沒有辦法上報當時的情況,這樣客戶如果想獲取1580952600 這個時間戳對應的天津的數據的時候,肯定是拿不到了,所以傳統思維上,我們應該增加一個容災設備,保證一個設備在壞掉、停電、人爲損壞等等的情況的時候,依然能夠有數據上報回來。

基於這樣的思想,以上的表結構就會變成:

時間戳 北京 1 北京 2 天津1 天津2 上海1 上海2
1580950800 20.5 20.9 21.7 20.9 20.7 21.7
1580952600 21.5 21.0 NULL 21.7 21.7 21.7
1580958000 22.5 22.7 22.9 22.7 NULL NULL

2.2 更高採樣頻率

這時候依然存在問題, 1580958000 這一刻兩個設備都沒有數據,有可能是放置設備的區域同時出現了斷網或者斷電,這種情況下,我們可以採用提高採集數據的頻率或者補傳數據來解決(補傳暫不討論)。

我們將每天數據分爲3組,每組採樣3次,間隔爲1個小時,假如時間分佈爲:上午(7、8、9)、中午(12、13、14)、下午(18、19、20)。當增加了採樣頻率之後,即便某一刻出現了 NULL 數據,我們也可以採用臨近時間做爲補充。爲了方便對應,下表數據中增加時間點列輔助查看。

時間點 時間戳 北京 1 北京 2 天津1 天津2 上海1 上海2
7點 1580943600 20.5 20.9 21.7 20.9 20.7 21.7
8點 1580947200 21.5 21.0 NULL 21.7 21.7 21.7
9點 1580950800 22.5 22.7 22.9 22.7 NULL NULL
12點 1580961600 20.5 20.9 21.7 20.9 20.7 21.7
13點 1580965200 21.5 21.0 NULL 21.7 21.7 21.7
14點 1580968800 22.5 22.7 22.9 22.7 NULL NULL
18點 1580983200 20.5 20.9 21.7 20.9 20.7 21.7
19點 1580986800 21.5 21.0 NULL 21.7 21.7 21.7
20點 1580990400 22.5 22.7 22.9 22.7 NULL NULL

可以看到經過各種各樣的需求之後,上傳的數據是成倍增長的,不難想象如果這個溫度數據希望精準的獲取到每個縣城的溫度,那麼中國有 2854 個縣城 * 2 個溫度設備 * 9 條數據 = 1 天產生的數據總量 = 51372 條,那麼一個月就是 1541160 條。

數據實時性及總量

假如上面的數據我們繼續提高頻率到每1分鐘每個設備上報一次,那麼數據量就會成爲 2854 * 2 * 60 * 24 = 246585600 條/天。

在這樣的數據量下,實時插入實時做一些聚合計算,應該傳統數據庫就有些處理不過來了。

IoTDB 的前身

某公司在實際業務中,20 萬設備保存了 3 年的數據,TB級別的數據使得 Oracle 被拖的根本喫不消。關鍵的問題點還不僅僅是存量數據大,新增數據依然以非常快的速度在增長。後來公司聯繫到了 IoTDB 的第一批開發者,但是當時的方案還是基於 Cassandra 來做設計,當時規劃了 5 臺機器的集羣,性能剛滿足,但隨着時間推移設備總量在增加,業務系統的查詢請求量在增加。Cassandra 在經過大量的努力之後,最後發現如果再改可能就需要大面積的重構 Cassandra 數據的代碼了,最終決定重新設計一個存儲方式,來解決物聯網場景下的時序數據高效寫入、低延遲讀取、高壓縮比持久化。

PS: 以上都是黃向東 (IoTDB PPMC) ,在 meetup 中講到的,我只是在腦中存留了一部分,具體的細節大家可以到 IoTDB 社區交流。

性能對比

測試工具使用的是由清華大學大數據實驗室開發的iotdb-benchmark

1.寫入性能對比

數據集2 客戶端 存儲組 設備 變量 batchsize LOOP 數據量 寫入速度(point/s) 硬盤數據大小
IoTDB 10 10 10 10 1000 1000000 1E+11 24750321.93 38306092
InfluxDB 10 10 10 10 1000 1000000 1E+11
304682932
TimescaleDB 10 10 10 10 1000 1000000 1E+11 737689.22 1610219064
數據集1 客戶端 存儲組 設備 變量 batchsize LOOP 數據量 寫入速度(point/s) 硬盤數據大小
IoTDB 10 10 10 10 1000 100000 10000000000 20706345.15 3599732
InfluxDB 10 10 10 10 1000 100000 10000000000 1729907.81 30546560
TimescaleDB 10 10 10 10 1000 100000 10000000000 715857 161026468
KairosDB 10 10 10 10 10000 10000 10000000000 24924.97 76263380

上面一組數據可以看出寫入性能高於同款數據庫10倍有餘,單機寫入速度高達到每秒2千萬。且硬盤佔用是最小的,這在數據比較大的線上業務中,可能每個月會差出來 1 到 2 塊硬盤。

2. 查詢性能對比

原始數據查詢


客戶端 存儲組 設備 序列-數據量 變量 查詢點數 LOOP 速度(point/s) AVG MIN
IoTDB 10 10 10 1.00E+09 1 1000000 100 12942984.85 740.27 457.04
InfluxDB 10 10 10 1.00E+09 1 1000000 100 1779606.4 5591 4666.39
TimescaleDB 10 10 10 1.00E+09 1 1000000 100 3781467.52 2345.69 1193.78

聚合數據查詢


客戶端 存儲組 設備 序列-數據量 變量 LOOP 範圍 速度(point/s) AVG MIN
IoTDB-1 10 10 10 1.00E+09 1 100 0.0001 49.75 27.87 18.03
IoTDB-2 10 10 10 1.00E+09 1 100 0.001 49.75 49.14 19.87
IoTDB-3 10 10 10 1.00E+09 1 100 0.01 49.76 48.69 22.32
IoTDB-4 10 10 10 1.00E+09 1 100 0.1 48.68 99.14 25.56
IoTDB-5 10 10 10 1.00E+09 1 100 1 14 595.61 45.54
InfluxDB-1 10 10 10 1.00E+09 1 100 0.0001 234.32 40.28 21.63
InfluxDB-2 10 10 10 1.00E+09 1 100 0.001 28.88 341.9 238.1
InfluxDB-3 10 10 10 1.00E+09 1 100 0.01 3.07 3226.87 2664.86
TimescaleDB-1 10 10 10 1.00E+09 1 100 0.0001 42.39 220.57 120.5
TimescaleDB-2 10 10 10 1.00E+09 1 100 0.001 5.8 1502.9 754.15
TimescaleDB-3 10 10 10 1.00E+09 1 100 0.01 1.02 9711.55 7148.69

3. 對比圖

整體來看 IoTDB 無論在寫入、原始數據查詢還是聚合查詢,都幾乎是10倍的性能於競品數據庫,而且硬盤佔用又小於同款數據庫10倍,那麼 IoTDB 是怎樣完成如此高的壓縮比、如此恐怖的寫入速度、如此高效的查詢呢?歡迎繼續關注。。。


本文分享自微信公衆號 - 數據庫技術研究(atoildw)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章