IoTDB 是一款時序數據庫,相關競品有 Kairosdb,InfluxDB,TimescaleDB等,主要使用場景是在物聯網相關行業,如:車聯網、風力發電、地鐵、飛機監控等等,具體應用案例及公司詳情可以查看:IoTDB在實際公司中的使用信息收集
IoTDB 模塊主要分為Client,JDBC,Server,TsFile,Grafana,Distribution 以及各種生態的連接器。整個系列的文章會從行業背景開始講起,了解一個行業具體的使用場景,然后介紹 TsFile 是以什么樣的格式來保存數據的,再介紹 Server 里怎樣完成一次查詢,最后在介紹一條完 整的 SQL是怎樣從 Client 使用 JDBC 到 Server 直至返回具體結果。如果有能力的話再介紹一下集群的一些內容和工作方式。
打一波廣告本人專注車聯網領域多年,現任四維智聯架構師。目前正在參與 IoTDB 社區,有志同道合的同伴歡迎加微信:liutaohua001
歡迎大家訪問 IoTDB 倉庫,求一波 Star 。
這一章主要想聊一聊:
- 為什么重復造輪子,從物聯網行業的數據特點到
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 |
這里可能會存在疑問就是假如人數是逐漸增加的,那么是動態創建列呢?還是提前創建足夠多的列?這個問題等后面文章有機會繼續介紹
物聯網
物聯網的特點是都會存在一個或多個設備,他們以各種各樣的形式組織到一起,用來觀測或記錄同一時間里相同環境所產生的數據。下面的介紹中,使用由簡單到復雜的數據逐步介紹在物聯網行業中,通用的一些問題和方向。
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 是怎樣完成如此高的壓縮比、如此恐怖的寫入速度、如此高效的查詢呢?歡迎繼續關注。。。
