近日,咱們曾發佈測試報告 DolphinDB與InfluxDB對比測試報告,此報告測試於2019年。當時的結果顯示,DolphinDB的查詢性能領先InfluxDB一到三個數據量級,數據導入性能領先一個數量級,數據導出性能相差不大。時隔一年,DolphinDB與InfluxDB都作了很多功能和性能上的優化,二者的性能究竟有何變化?咱們從新對DolphinDB Database 和InfluxDB進行對比測試,測試涵蓋數據導入導出、數據查詢和磁盤空間佔用三個方面。測試的數據集也涵蓋了日益流行的物聯網數據集,以及規模更大的金融大數據集。git
在本次的全部測試項目中,DolphinDB 表現更出色,主要測試結論以下:github
查詢功能方面,InfluxDB 不支持對比查詢,不支持錶鏈接,不支持對除 time 之外的 tag, field 進行排序,且函數的參數只能是某一個 field ,而不能是 field 的表達式,功能上有極大的限制,有多個測試樣例沒法在sql
InfluxDB 中實現;而 DolphinDB 對數據的處理則更加的靈活、方便。
數據庫
DolphinDB編程
DolphinDB 是以 C++ 編寫的一款分析型的高性能分佈式時序數據庫,使用高吞吐低延遲的列式內存引擎,集成了功能強大的編程語言和高容量高速度的流數據分析系統,可在數據庫中進行復雜的編程和運算,顯著減小數據遷移所耗費的時間。windows
DolphinDB 經過內存引擎、數據本地化、細粒度數據分區和並行計算實現高速的分佈式計算,內置流水線、 Map Reduce 和迭代計算等多種計算框架,使用內嵌的分佈式文件系統自動管理分區數據及其副本,爲分佈式計算提供負載均衡和容錯能力。緩存
DolphinDB 支持類標準 SQL 的語法,提供相似於 Python 的腳本語言對數據進行操做,也提供其它經常使用編程語言的 API,在金融領域中的歷史數據分析建模與實時流數據處理,以及物聯網領域中的海量傳感器數據處理與實時分析等場景中表現出色。性能優化
InfluxDBapp
InfluxDB 是目前最爲流行的高性能開源時間序列數據庫,由 Go 語言寫成。它的核心是一款定製的存儲引擎 TSM Tree,對時間序列數據作了優化,優先考慮插入和查詢數據的性能。負載均衡
InfluxDB 使用類 SQL 的查詢語言 InfluxQL,並提供開箱即用的時間序列數學和統計函數;同時對外提供基於 HTTP 的接口來支持數據的插入與查詢
InfluxDB 容許用戶定義數據保存策略 (Retention Policies) 來實現對存儲超過指定時間的數據進行刪除或者降採樣,被普遍應用於存儲系統的監控數據,IoT 行業的實時數據等場景。
因爲 InfluxDB 集羣版本閉源,在測試中 DolphinDB 與 InfluxDB 均使用單機模式。
主機:DELL OptiPlex 7060
CPU :Intel Core i7-8700(6 核 12 線程 3.20 GHz)
內存:32 GB (8GB × 4, 2666 MHz)
硬盤:2T HDD (222 MB/s 讀取;210 MB/s 寫入)
OS:Ubuntu 16.04 LTS
測試使用的 DolphinDB 版本爲 Linux v0.89 (2019.01.31),最大內存設置爲 28GB
。
測試使用的 InfluxDB 版本爲 1.7.5,根據 InfluxDB 官方配置文件中的說明,結合測試機器的實際硬件對配置作了優化,主要將 wal-fsync-delay
調節爲適合機械硬盤的 100ms
,將 cache-max-memory-size
設置爲 28GB
,以及將 series-id-set-cache-size
設置爲 400
。
具體修改的配置詳見附錄中 influxdb.conf
文件。
本報告測試了小數據量級(4.2GB)和大數據量級(270GB)下DolphinDB和InfluxDB的表現狀況,如下是兩個數據的表結構和分區方法:
4.2GB設備傳感器記錄小數據集(csv格式,3千萬條)
咱們使用物聯網設備的傳感器信息做爲小數據集來測試,數據集包含3000個設備在2016年11月15日到2016年11月19日10000個時間間隔上的傳感器時間,設備ID,電池,內存,CPU等時序統計信息。數據集共30,000,000條數據,包含包含一張設備信息表device_info和一張設備傳感器信息記錄表readings。
數據來源:https://docs.timescale.com/v1.1/tutorials/other-sample-datasets
下載地址:https://timescaledata.blob.core.windows.net/datasets/devices_big.tar.gz
如下是readings表在DolphinDB和InfluxDB中的結構:
2018年8月,咱們曾發佈測試報告 DolphinDB與InfluxDB對比測試報告。當時的結果顯示,DolphinDB的查詢性能領先InfluxDB一到三個數據量級,數據導入性能領先一個數量級,數據導出性能相差不大。時隔半年,DolphinDB與InfluxDB都作了很多功能和性能上的優化,二者的性能究竟有何變化?咱們從新對DolphinDB和InfluxDB進行對比測試,測試涵蓋數據導入導出、數據查詢和磁盤空間佔用三個方面。測試的數據集也涵蓋了日益流行的物聯網數據集,以及規模更大的金融大數據集。
在本次的全部測試項目中,DolphinDB 表現更出色,主要測試結論以下:
DolphinDB
DolphinDB 是以 C++ 編寫的一款分析型的高性能分佈式時序數據庫,使用高吞吐低延遲的列式內存引擎,集成了功能強大的編程語言和高容量高速度的流數據分析系統,可在數據庫中進行復雜的編程和運算,顯著減小數據遷移所耗費的時間。
DolphinDB 經過內存引擎、數據本地化、細粒度數據分區和並行計算實現高速的分佈式計算,內置流水線、 Map Reduce 和迭代計算等多種計算框架,使用內嵌的分佈式文件系統自動管理分區數據及其副本,爲分佈式計算提供負載均衡和容錯能力。
DolphinDB 支持類標準 SQL 的語法,提供相似於 Python 的腳本語言對數據進行操做,也提供其它經常使用編程語言的 API,在金融領域中的歷史數據分析建模與實時流數據處理,以及物聯網領域中的海量傳感器數據處理與實時分析等場景中表現出色。
InfluxDB
InfluxDB 是目前最爲流行的高性能開源時間序列數據庫,由 Go 語言寫成。它的核心是一款定製的存儲引擎 TSM Tree,對時間序列數據作了優化,優先考慮插入和查詢數據的性能。
InfluxDB 使用類 SQL 的查詢語言 InfluxQL,並提供開箱即用的時間序列數學和統計函數;同時對外提供基於 HTTP 的接口來支持數據的插入與查詢
InfluxDB 容許用戶定義數據保存策略 (Retention Policies) 來實現對存儲超過指定時間的數據進行刪除或者降採樣,被普遍應用於存儲系統的監控數據,IoT 行業的實時數據等場景。
因爲 InfluxDB 集羣版本閉源,在測試中 DolphinDB 與 InfluxDB 均使用單機模式。
主機:DELL OptiPlex 7060
CPU :Intel Core i7-8700(6 核 12 線程 3.20 GHz)
內存:32 GB (8GB × 4, 2666 MHz)
硬盤:2T HDD (222 MB/s 讀取;210 MB/s 寫入)
OS:Ubuntu 16.04 LTS
測試使用的 DolphinDB 版本爲 Linux v0.89 (2019.01.31),最大內存設置爲 28GB
。
測試使用的 InfluxDB 版本爲 1.7.5,根據 InfluxDB 官方配置文件中的說明,結合測試機器的實際硬件對配置作了優化,主要將 wal-fsync-delay
調節爲適合機械硬盤的 100ms
,將 cache-max-memory-size
設置爲 28GB
,以及將 series-id-set-cache-size
設置爲 400
。
具體修改的配置詳見附錄中 influxdb.conf
文件。
本報告測試了小數據量級(4.2GB)和大數據量級(270GB)下DolphinDB和InfluxDB的表現狀況,如下是兩個數據的表結構和分區方法:
4.2GB設備傳感器記錄小數據集(csv格式,3千萬條)
咱們使用物聯網設備的傳感器信息做爲小數據集來測試,數據集包含3000個設備在2016年11月15日到2016年11月19日10000個時間間隔上的傳感器時間,設備ID,電池,內存,CPU等時序統計信息。數據集共30,000,000條數據,包含包含一張設備信息表device_info和一張設備傳感器信息記錄表readings。
數據來源:https://docs.timescale.com/v1.1/tutorials/other-sample-datasets
下載地址:https://timescaledata.blob.core.windows.net/datasets/devices_big.tar.gz
如下是readings表在DolphinDB和InfluxDB中的結構:
咱們在 DolphinDB database 中的分區方案是將 time
做爲分區的第一個維度,按天分爲 4 個區,分區邊界爲 [2016.11.15 00:00:00, 2016.11.16 00:00:00, 2016.11.17 00:00:00, 2016.11.18 00:00:00, 2016.11.19 00:00:00]
;再將 device_id
做爲分區的第二個維度,天天一共分 10 個區,最後每一個分區所包含的原始數據大小約爲 100 MB
。
InfluxDB 中使用 Shard Group 來存儲不一樣時間段的數據,不一樣 Shard Group 對應的時間段不會重合。一個 Shard Group 中包含了大量的 Shard, Shard 纔是 InfluxDB 中真正存儲數據以及提供讀寫服務的結構。InfluxDB 採用了 Hash 分區的方法將落到同一個 Shard Group 中的數據再次進行了一次分區,即根據 hash(Series) 將時序數據映射到不一樣的 Shard,所以咱們使用如下語句手動指定每一個 Shard Group 的 Duration,在時間維度上按天分區。
create retention policy one_day on test duration inf replication 1 shard duration 1d default
270GB股票交易大數據集(csv格式,23個csv,65億條)
咱們將紐約證券交易所(NYSE)提供的 2007.08.01 - 2007.08.31 一個月的股市 Level 1 報價數據做爲大數據集進行測試,數據集包含 8000 多支股票在一個月內的交易時間
,股票代碼
,買入價
,賣出價
,買入量
,賣出量
等報價信息。
數據集中,共有 65 億(65,6169,3704)條報價記錄,一個 CSV 中保存一個交易日的記錄,該月共 23 個交易日,未壓縮的 CSV 文件共計 270 GB。
數據來源:NYSE Exchange Proprietary Market Data
如下是TAQ表在DolphinDB和InfluxDB中的結構:
在 DolphinDB database 中咱們按date(日期)
,symbol(股票代碼)
進行分區,天天再根據 symbol 分爲 100 個分區,每一個分區大概 120 MB 左右。
在InfluxDB中使用與小數據集相同的策略。
DolphinDB使用如下腳本導入:
timer { for (fp in fps) { loadTextEx(db, `taq, `date`symbol, fp, ,schema) print now() + ": 已導入 " + fp } }
4.2 GB 設備傳感器記錄小數據集共3 千萬條數據導入用時 20 秒
, 平均速率 150 萬條/秒
。
270 GB 股票交易大數據集共 65 億條數據(TAQ20070801 - TAQ20070831
23 個文件),導入用時 38 分鐘
。
InfluxDB 自己不支持直接導入 CSV,只能經過 HTTP API 或者influx -import
的方式導入,出於導入性能考慮,咱們選擇將 CSV 中的每一行先轉換爲 Line Protocol 格式,如:
readings,device_id=demo000000,battery_status=discharging,bssid=A0:B1:C5:D2:E0:F3,ssid=stealth-net battery_level=96,battery_temperature=91.7,cpu_avg_1min=5.26,cpu_avg_5min=6.172,cpu_avg_15min=6.51066666666667,mem_free=650609585,mem_used=349390415,rssi=-42 1479211200
並添加以下文件頭:
# DDL CREATE DATABASE test CREATE RETENTION POLICY one_day ON test DURATION INF REPLICATION 1 SHARD DURATION 1d DEFAULT # DML # CONTEXT-DATABASE:test # CONTEXT-RETENTION-POLICY:one_day
保存到磁盤中,再經過如下命令導入:
influx -import -path=/data/devices/readings.txt -precision=s -database=test
通過轉換後,4.2 GB 設備傳感器記錄小數據集共3 千萬
條數據導入用時25 分鐘 10 秒
, 平均速率2 萬條/秒
。
將 TAQ 數據插入到 InfluxDB 的過程當中,若是屢次插入時間相同 (1185923302),tag 相同的記錄 (這裏是 symbol, mode, ex),好比下面兩條,即便 value 不一樣 (bid, ofr, bidsiz, ofrsiz),後面的那一條記錄也會覆蓋前面的記錄,最終數據庫中只保留了最後一條記錄。
taq,symbol=A,mode=12,ex=T bid=37,ofr=54.84,bidsiz=1,ofrsiz=1 1185923302 taq,symbol=A,mode=12,ex=T bid=37,ofr=38.12,bidsiz=1,ofrsiz=1 1185923302
要解決這個問題文檔(InfluxDB frequently asked questions | InfluxData Documentation)裏給出了兩種方法,一種是新增一個 tag 來對相同時間的數據設置不一樣的 tag value 手動區分,另外一種是強行微調時間戳使其不一樣。
設置不一樣的 tag value 手動區分這種方法只適用於數據徹底按照時間順序插入的狀況。在使用其餘的編程語言插入數據的過程當中判斷該條記錄的時間戳是否與上一條記錄徹底相同,並在插入數據庫時手動指定不一樣的 tag value 做區分,效率低下且操做繁瑣;若數據並不是徹底按照時間順序插入,則沒法判斷當前的時間點是否已經有數據記錄的存在,是否會覆蓋先前的數據。
咱們在本次測試中使用強行微調時間戳的方法,因爲原有 TAQ 交易記錄的時間精度爲秒,所以咱們能夠在將 CSV 的數據轉換至 Line Protocol 格式的過程當中,在原來精確到秒的時間戳的基礎上,隨機加上一個毫秒值,產生一個新的精度爲毫秒的僞時間戳,以防止數據衝突。
通過轉換後,270 GB 股票交易大數據集所包含的65 億
條數據導入用時65 小時
,平均導入速率2.7 萬條/秒
。
導入性能對好比下表所示:
結果顯示,DolphinDB 的導入速率遠大於 InfluxDB 的導入速率。在導入過程當中還能夠觀察到,隨着時間的推移,InfluxDB 的導入速率不斷降低,而 DolphinDB 保持穩定。並且 InfluxDB 在導入數據時須要先編寫代碼將 CSV 格式文件轉換爲 InfluxDB 的 Line Protocol 格式,複雜繁瑣,還會產生多餘的中間文件佔用大量空間。
在 DolphinDB 中使用saveText((select * from readings), '/data/devices/readings_dump.csv')
進行數據導出,用時僅需 28 秒。
在 InfluxDB 中若使用influx -database 'test' -format csv -execute "select * from readings > /data/devices/export_15.csv
進行數據導出內存佔用會超過 30 GB,最終引起fatal error: runtime: out of memory
,最後採用分時間段導出 CSV 的方法。代碼以下所示:
for i in 1{5..8}; do time influx -database 'test' -format csv -execute "select * from readings where '2016-11-$i 00:00:00' <= time and time < '2016-11-$((i+1)) 00:00:00'" > /data/devices/export_$i.csv done
總耗時5 min 31 s。
除性能差距懸殊以外,InfluxDB 的 CSV 數據導出操做複雜,容易發生內存溢出問題,並且導出的 CSV 文件首行無字段名稱,用戶體驗遠不如 DolphinDB。
導出性能對好比下表所示:
導入數據後,DolphinDB和InfluxDB佔用空間以下表所示:
小數據集中 DolphinDB 的空間利用率與 InfluxDB 相近,兩款數據庫都對數據進行了壓縮存儲,壓縮率大體處於同一個數量級,在 20% - 30% 之間;大數據集中 InfluxDB 對數據的壓縮效果很差,佔用空間爲 DolphinDB 的兩倍。
咱們一共對比了如下八種類別的查詢:
查詢測試的時間包含磁盤 I/O 的時間,爲保證測試公平,每次啓動程序測試前均經過 Linux 系統命令sync; echo 1,2,3 | tee /proc/sys/vm/drop_caches
分別清除系統的頁面緩存、目錄項緩存和硬盤緩存,啓動程序後依次執行全部查詢語句執行一次。
4.2GB設備傳感器記錄小數據集查詢測試結果以下表所示:
查詢腳本見附錄。
結果顯示,DolphinDB的查詢性能遠超於InfluxDB。在功能上,InfluxDB不如DolphinDB強大,好比:
select * from taq order by <some-field>
,詳見[feature request] ORDER BY tag values · Issue #3954 · influxdata/influxdb。field1 + field2
等)所以只能用 subquery 先計算出表達式的值再套用函數,很是繁瑣,並且須要在子查詢和父查詢的 where 子句中重複指定時間範圍,不然會從最舊的數據記錄的時間開始一直掃描到當前時間。 InfluxDB 和 DolphinDB 第14個查詢語句的對好比下://14. 經典查詢:計算某時間段內高負載高電量設備的內存大小 //DolphinDB select max(date(time)) as date, max(mem_free + mem_used) as mem_all from readings where time <= 2016.11.18 21:00:00, battery_level >= 90, cpu_avg_1min > 90 group by hour(time), device_id //InfluxDB select max(mem_total) from ( select mem_free + mem_used as mem_total from readings where time <= '2016-11-18 21:00:00' and battery_level >= 90 and cpu_avg_1min > 90 ) where time <= '2016-11-18 21:00:00' group by time(1h), device_id
270GB股票交易大數據查詢測試結果以下表所示:
查詢腳本見附錄。
結果顯示,某些查詢,二者的性能差異不大,但某些查詢,DolphinDB比InfluxDB快將近100到200倍。
在測試中,咱們發現:
//2. 範圍查詢:查詢某時間段內的某些股票的全部記錄 select symbol, time, bid, ofr from taq where (symbol = 'IBM' or symbol = 'MSFT' or symbol = 'GOOG' or symbol = 'YHOO') and ('2007-08-03 01:30:00' <= time and time < '2007-08-03 01:30:59') //該語句返回的結果不爲空 select symbol, time, bid, ofr from taq where (symbol = 'IBM' or symbol = 'MSFT' or symbol = 'GOOG' or symbol = 'YHOO') and (('2007-08-03 01:30:00' <= time and time < '2007-08-03 01:30:59') or ('2007-08-04 01:30:00' <= time and time < '2007-08-04 01:30:59')) //擴展了時間範圍後,該語句返回的結果反而爲空
//8. 經典查詢:計算某天每一個股票每分鐘最大賣出與最小買入價之差 select symbol, max(ofr) - min(bid) as gap from taq where '2007-08-03' <= time and time < '2007-08-04' and bid > 0 and ofr > bid group by symbol, time(1m)
InfluxDB會拋出異常,ERR: mixing multiple selector functions with tags or fields is not supported
,即不能在select語句中同時使用max和min函數,而DolphinDB能夠正常執行。
2007-07-31T23:02:00Z 22.17 54.84 2007-07-31T23:03:00Z 2007-07-31T23:04:00Z 2007-07-31T23:05:00Z 2007-07-31T23:06:00Z 2007-07-31T23:07:00Z 2007-07-31T23:08:00Z 37 38.12 2007-07-31T23:09:00Z 2007-07-31T23:10:00Z 37.03 38.12
DolphinDB 除了在基準測試中體現出優越的性能以外,還具備以下優點:
數據預覽(取前20行)
DolphinDB
InfluxDB