IoTDB
是一款時序數據庫,相關競品有 Kairosdb
,InfluxDB
,TimescaleDB
等,主要使用場景是在物聯網相關行業,如:車聯網、風力發電、地鐵、飛機監控等等,具體應用案例及公司詳情能夠查看:IoTDB在實際公司中的使用信息收集git
IoTDB
模塊主要分爲Client
,JDBC
,Server
,TsFile
,Grafana
,Distribution
以及各類生態的鏈接器。整個系列的文章會從行業背景開始講起,瞭解一個行業具體的使用場景,而後介紹 TsFile
是以什麼樣的格式來保存數據的,再介紹 Server
裏怎樣完成一次查詢,最後在介紹一條完 整的 SQL
是怎樣從 Client
使用 JDBC
到 Server
直至返回具體結果。若是有能力的話再介紹一下集羣的一些內容和工做方式。github
打一波廣告本人專一車聯網領域多年,現任四維智聯架構師。目前正在參與 IoTDB 社區,有志同道合的同伴歡迎加微信:liutaohua001數據庫
歡迎你們訪問 IoTDB 倉庫,求一波 Star 。apache
這一章主要想聊一聊:微信
IoTDB
的發展過程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 |
這裏可能會存在疑問就是假如人數是逐漸增長的,那麼是動態建立列呢?仍是提早建立足夠多的列?這個問題等後面文章有機會繼續介紹測試
物聯網的特色是都會存在一個或多個設備,他們以各類各樣的形式組織到一塊兒,用來觀測或記錄同一時間裏相同環境所產生的數據。下面的介紹中,使用由簡單到複雜的數據逐步介紹在物聯網行業中,通用的一些問題和方向。大數據
假如我是一個公司,對外播報北京、天津、上海三地的溫度數據,從而實現盈利。
時間戳 | 北京 | 天津 | 上海 |
---|---|---|---|
1580950800 | 20.5 | 22.9 | 21.7 |
1580952600 | 20.5 | NULL | 22.9 |
1580958000 | 20.5 | 21.7 | 22.9 |
數據保證的質量是多方面的,一步一步介紹。
首先能夠看到上面數據是存在 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 |
這時候依然存在問題, 1580958000
這一刻兩個設備都沒有數據,有多是放置設備的區域同時出現了斷網或者斷電,這種狀況下,咱們能夠採用提升採集數據的頻率或者補傳數據來解決(補傳暫不討論)。
咱們將天天數據分爲3組,每組採樣3次,間隔爲1個小時,假如時間分佈爲:上午(七、八、9)、中午(十二、1三、14)、下午(1八、1九、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 條/天。
在這樣的數據量下,實時插入實時作一些聚合計算,應該傳統數據庫就有些處理不過來了。
某公司在實際業務中,20 萬設備保存了 3 年的數據,TB級別的數據使得 Oracle 被拖的根本吃不消。關鍵的問題點還不只僅是存量數據大,新增數據依然以很是快的速度在增加。後來公司聯繫到了 IoTDB
的第一批開發者,可是當時的方案仍是基於 Cassandra 來作設計,當時規劃了 5 臺機器的集羣,性能剛知足,但隨着時間推移設備總量在增長,業務系統的查詢請求量在增長。Cassandra 在通過大量的努力以後,最後發現若是再改可能就須要大面積的重構 Cassandra 數據的代碼了,最終決定從新設計一個存儲方式,來解決物聯網場景下的時序數據高效寫入、低延遲讀取、高壓縮比持久化。
PS: 以上都是黃向東 (IoTDB PPMC) ,在 meetup 中講到的,我只是在腦中存留了一部分,具體的細節你們能夠到 IoTDB 社區交流。
測試工具使用的是由清華大學大數據實驗室開發的iotdb-benchmark
數據集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 塊硬盤。
原始數據查詢
客戶端 | 存儲組 | 設備 | 序列-數據量 | 變量 | 查詢點數 | 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 |
總體來看 IoTDB
不管在寫入、原始數據查詢仍是聚合查詢,都幾乎是10倍的性能於競品數據庫,並且硬盤佔用又小於同款數據庫10倍,那麼 IoTDB
是怎樣完成如此高的壓縮比、如此恐怖的寫入速度、如此高效的查詢呢?歡迎繼續關注。。。