摘要:為幫助用戶了解TDengine Database的指標,此次測試,從數據庫的讀、寫、查詢、壓縮比等方面對TDengine和OpenTSDB進行了對比測試。從測試結果上看,TDengine的性能遠超OpenTSDB,寫入性能約為25倍,讀取性能約為32倍,聚合函數性能約為1000倍,按標簽分組查詢性能約為1000倍,按時間分組查詢性能約為40倍,壓縮比約為5倍。
測試環境
對比測試的測試程序和數據庫服務在同一臺4核8GB的Dell臺式機上部署,臺式機型號為OptiPlex-3050,詳細配置如下
OS: Ubuntu 16.04 x64
CPU: Intel(R) Core(TM) i3-7100 CPU @ 3.90GHz
Memory: 8GB
Disk: 1TB HDD
測試數據集及其生成方法
本次測試調研了兩類比較熱門的測試數據集:
- 1.紐約出租車運行數據,因該數據中抹去了單臺車輛的信息,無法對其進行建模
- 2.faker生成工具,因其只能生成字符串,并不適合物聯網場景下處理的數據。
所以,為了使得測試可輕易重復,自己寫了一個生成模擬數據的程序來進行本次測試。
測試數據生成程序模擬若干溫濕度計生成的數據,其中溫度為整數、濕度為浮點數,同時每個溫度計包含設備ID、設備分組、設備名稱三個標簽。為了盡可能真實地模擬溫濕度計的生成數據,沒有使用完全隨機數,而是針對每個溫度計確保生成的數據值呈正態分布。
測試數據的頻率為1秒鐘,數據集包含10000臺設備,每臺設備10000條記錄。每條數據采集記錄包含3個標簽字段,2個數據字段,1個時間戳字段。
2.測試數據生成程序源碼
采用java程序生成測試數據集,測試程序源代碼行數較多,因此您可以到 下載,執行如下語句
cd tests/comparisonTest/dataGenerator
javac com/taosdata/generator/DataGenerator.java
3.測試數據生成程序用法
相關參數如下
- dataDir 生成的數據文件路徑
- numOfFiles 生成的數據文件數目
- numOfDevices 測試數據集中的設備數目
- rowsPerDevice 測試數據集中每臺設備包含的記錄條數
4.生成測試數據
執行如下命令,會在~/testdata目錄下生成100個數據文件,每個文件包含100臺設備的測試數據;合計10000臺設備,每臺設備10000條記錄
mkdir ~/testdata
java com/taosdata/generator/DataGenerator -dataDir ~/testdata -numOfDevices 10000 -numOfFiles 100 -rowsPerDevice 10000
TDengine環境準備
TDengine是一個開源的專為物聯網、車聯網、工業互聯網、IT運維等設計和優化的大數據平臺。除核心的快10倍以上的時序數據庫(Time-Series Database)功能外,還提供緩存、數據訂閱、流式計算等功能,最大程度減少研發和運維的工作量。
1.安裝部署
- 下載tdengine-1.6.1.0.tar.gz,地址//www.yakult-sh.com.cn/
- 安裝TDengine,解壓后運行install.sh進行安裝
- 啟動TDengine,運行sudo systemctl start taosd
- 測試是否安裝成功,運行TDengine的shell命令行程序taos,可以看到如下類似信息
Welcome to the TDengine shell, server version:1.6.1.0 client version:1.6.1.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos>
2.數據建模
TDengine Database為相同結構的設備創建一張超級表(STable),而每個具體的設備則單獨創建一張數據表。因此,超級表的數據字段為采集時間、溫度、濕度等與時間序列相關的采集數據;標簽字段為設備編號、設備分組編號、設備名稱等設備本身固定的描述信息。
創建超級表的SQL語句為
create table devices(ts timestamp, temperature int, humidity float) tags(devid int, devname binary(16), devgroup int);
以設備ID作為表名(例如device id為1,則表名為dev1),使用自動建表語句,寫入一條記錄的語句為
insert into dev1 using devices tags(1,'d1',0) values(1545038786000,1,3.560000);
3.測試程序源碼
本文采用TDengine的原生C語言接口,編寫數據寫入及查詢程序,后續的其他文章會提供基于JDBCDriver的測試程序。
測試程序源代碼行數較多,因此您可以到 下載,執行如下語句
cd tdengine
make
會在當前目錄下生成可執行文件./tdengineTest
4.測試程序用法
TDengine的測試程序用法與OpenTSDB的用法相同,寫入相關參數
- writeClients 并發寫入的客戶端鏈接數目,默認為1
- rowsPerRequest 一次請求中的記錄條數,默認為100,范圍1-1000
- dataDir 讀取的數據文件路徑,來自于測試數據生成程序
- numOfFiles 從數據文件路徑中讀取的文件個數
例如
./tdengineTest -dataDir ./data -numOfFiles 10 -writeClients 2 -rowsPerRequest 100
查詢相關參數
- sql 將要執行的SQL語句列表所在的文件路徑,以逗號區分每個SQL語句
例如
./tdengineTest -sql ./sqlCmd.txt
OpenTSDB環境準備
OpenTSDB是基于HBase的分布式的,可擴展的時間序列數據庫。
1.安裝部署
- 下載安裝并啟動HBase
從下載 hbase-1.4.10-bin.tar.gz
tar xzvf hbase-1.4.10-bin.tar.gz
cd hbase-1.4.10/bin
./start_hbase.sh
- 下載并安裝OpenTSDB
git clone git://github.com/OpenTSDB/opentsdb.git
cd opentsdb
./build.sh
- 在HBase里建表
如果是第一次運行OpenTSDB,還需要先創建一些必要的HBase表。
env COMPRESSION=NONE HBASE_HOME=${HBASE_HOME}/hbase-version ${OpenTSDB_download_path}/src/create_table.sh
- 啟動OpenTSDB服務
sudo service opentsdb start
OpenTSDB可以通過//hostIp:4242打開交互式網頁

- 修改設置
打開OpenTSDB配置文件
cd /etc/opentsdb
vim opentsdb.conf
修改某些參數的默認值
tsd.core.auto_create_metrics = true
tsd.http.request.enable_chunked = true
tsd.http.request.max_chunk = 30000
因為本次測試采用http 接口,如果出現“java.net.NoRouteToHostException: Cannot assign requested address (Address not available)” 這種錯誤,還可執行如下命令
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
2.OpenTSDB數據建模
創建一個名為devices的measurement,所有設備都屬于該measurement,不同設備通過標簽進行區分。每臺設備包含三個標簽,分別為設備編號、設備分組編號、設備名稱。每條記錄只能包含一個metric,因此需要對溫度(整型)和 濕度(浮點)分別寫入一條記錄。每條記錄包含設備的三個標簽,一個metric的名字和值,以及時間戳。
3.OpenTSDB測試程序源碼
本文采用OpenTSDB的原生語言java,編寫數據寫入及查詢程序。因為OpenTSDB并未提供官方java 接口,本次測試選擇調用他們的http接口。測試程序源代碼行數較多,因此您可以到 下載。
4.OpenTSDB測試程序用法
寫入相關參數
- writeClients 并發寫入的客戶端鏈接數目,默認為1
- rowsPerRequest 一次請求中的記錄條數,默認為100,范圍1-1000
- dataDir 讀取的數據文件路徑,來自于測試數據生成程序
- numOfFiles 從數據文件路徑中讀取的文件個數
例如
cd opentsdb/opentsdbtest/src/target
java -jar opentsdbtest-1.0-SNAPSHOT-jar-with-dependencies.jar -dataDir ~/testdata -numOfFiles 100 -writeClients 2 -rowsPerRequest 30
查詢相關參數
- sql 將要執行的SQL語句選項
java -jar opentsdbtest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql sqlchoice
寫入性能對比
數據庫的一個寫入請求可以包含一條或多條記錄,一次請求里包含的記錄條數越多,寫入性能就會相應提升。在以下測試中,使用R/R表示Records/Request ,即一次請求中的記錄條數。同時,一個數據庫可以支持多個客戶端鏈接,鏈接數增加,系統總的寫入通吐量也會相應增加。因此測試中,對于每一個數據庫,都會測試一個客戶端和多個客戶端連接的情況。
1.TDengine的寫入性能
TDengine按照每次請求包含1,100,500,1000,2000條記錄各進行測試,同時也測試了不同客戶端連接數的情況。測試步驟如下所示,您可以修改示例中的參數,完成多次不同的測試。
1.清空上次測試數據
運行TDengine的shell命令行程序taos,執行刪除測試數據庫語句
Welcome to the TDengine shell, server version:1.6.1.0 client version:1.6.1.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos>drop database db;
2.測試執行
開啟5個客戶端讀取~/testdata目錄中的100個數據文件,每個請求寫入1000條數據,可以參考如下命令
./tdengineTest -dataDir ~/testdata -numOfFiles 100 -writeClients 5 -rowsPerRequest 1000
寫入吞吐量如下,單位為記錄數/秒
| R/R | 1 client | 2 clients | 3 clients | 4 clients | 5 clients | 6 clients | 7 clients |
|---|---|---|---|---|---|---|---|
| 1 | 26824 | 43699 | 55137 | 62869 | 64529 | 68647 | 72277 |
| 100 | 415800 | 734484 | 895522 | 976085 | 1087902 | 1171074 | 1192199 |
| 500 | 479846 | 882612 | 1083032 | 1195100 | 1269196 | 1364256 | 1417004 |
| 1000 | 500751 | 914494 | 1121914 | 1239157 | 1367989 | 1418104 | 1476560 |
| 2000 | 512820 | 1055520 | 1174164 | 1306904 | 1426635 | 1458434 | 1477208 |

2.OpenTSDB的寫入性能
OpenTSDB按照每次請求包含1,10,30,50,80條記錄各進行測試,同時也測試了不同客戶端連接數的情況。測試步驟如下所示,您可以修改示例中的參數,完成多次不同的測試。
1.清空上次測試數據
運行HBase的shell命令行程序./hbase shell,可以看到如下類似信息
HBase Shell
Use "help" to get list of supported commands.
Use "exit" to quit this interactive shell.
Version 1.4.10, r76ab087819fe82ccf6f531096e18ad1bed079651, Wed Jun 5 16:48:11 PDT 2019
hbase(main):001:0> disable 'tsdb'; disable 'tsdb-meta'; disable 'tsdb-tree'; disable 'tsdb-uid';
hbase(main):002:0> drop 'tsdb'; drop 'tsdb-meta'; drop 'tsdb-tree'; drop 'tsdb-uid';
hbase(main):003:0> quit
然后再為OpenTSDB建表
env COMPRESSION=NONE HBASE_HOME=${HBASE_HOME}/hbase-version ${OpenTSDB_download_path}/src/create_table.sh
2.測試執行
開啟5個客戶端讀取~/testdata目錄中的100個數據文件,每個請求寫入30條數據,可以參考如下命令
java -jar opentsdbtest-1.0-SNAPSHOT-jar-with-dependencies.jar -dataDir ~/testdata -numOfFiles 100 -writeClients 5 -rowsPerRequest 30
寫入吞吐量如下,單位為記錄數/秒
| R/R | 1 client | 2 clients | 3 clients | 4 clients | 5 clients | 6 clients | 7 clients |
|---|---|---|---|---|---|---|---|
| 1 | 2370 | 2474 | 2572 | 2710 | 2497 | 2436 | 2371 |
| 10 | 18393 | 22828 | 22656 | 22924 | 22507 | 23200 | 23099 |
| 30 | 37463 | 45649 | 45735 | 46342 | 46795 | 46675 | 44908 |
| 50 | 45255 | 53222 | 50503 | 54475 | 54543 | 54283 | 54970 |
| 80 | 48794 | 56386 | 54564 | 56999 | 57198 | 57318 | 57272 |

3.TDengin和OpenTSDB的最佳性能對比
基于以上的測試數據,將TDengine和OpenTSDB測試出的最佳寫入速度進行對比,結果如下
| R/R | 1 client | 2 clients | 3 clients | 4 clients | 5 clients | 6 clients | 7 clients |
|---|---|---|---|---|---|---|---|
| TDengine | 512820 | 1055520 | 1174164 | 1306904 | 1426635 | 1458434 | 1477208 |
| OpenTSDB | 48794 | 56386 | 54564 | 56999 | 57198 | 57318 | 57272 |

從圖3可以看出,TDengine的寫入速度約為百萬條記錄/秒的量級,而OpenTSDB的寫入速度約為六萬條記錄/秒的量級。因此可以得出結論,在同等數據集和硬件環境下,TDengine的寫入速度遠高于OpenTSDB,約為25倍。
讀取性能對比
本測試做了簡單的遍歷查詢,就是將寫入的數據全部讀出。每次查詢僅取出100萬條記錄,在測試數據準備時,已經按照devgroup字段將數據拆分成100個分組,本次測試隨機選取其中10個分組進行查詢。
1. TDengine的測試方法
測試SQL語句存儲在tdengine/q1.txt中,測試SQL語句參考
select * from db.devices where devgroup=0;
執行方法如下
./tdengineTest -sql ./q1.txt
2.OpenTSDB的測試方法
OpenTSDB的查詢語句為json語句,已寫在代碼里,測試時只需選擇執行哪項查詢即可。
測試SQL的選項(sqlchoice)為q1
執行方法如下
java -jar opentsdbtest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql q1
讀取速度如下,單位為秒
| Latency | G-0 | G-10 | G-20 | G-30 | G-40 | G-50 | G-60 | G-70 | G-80 | G-90 |
|---|---|---|---|---|---|---|---|---|---|---|
| TDengine | 0.235 | 0.212 | 0.208 | 0.218 | 0.209 | 0.210 | 0.209 | 0.209 | 0.216 | 0.208 |
| OpenTSDB | 6.69 | 5.92 | 6.58 | 6.65 | 7.29 | 7.51 | 5.98 | 6.20 | 7.03 | 6.57 |

從圖表中可以看出,TDengine的100萬條的讀取速度穩定在0.21秒,吞吐量約為500萬條記錄/秒,OpenTSDB的100萬條的讀取速度穩定在6.7秒,吞吐量約為15萬條記錄/秒。所以從測試結果來看,TDengine的查詢吞吐量遠高于OpenTSDB, 約為OpenTSDB的16倍。
聚合函數性能對比
本單元的測試包含COUNT,AVERAGE,SUM,MAX,MIN,SPREAD這六個TDEngine和OpenTSDB共有的聚合函數。所有測試函數都會搭配篩選條件(WHERE)來選取設備的十分之一、十分之二、十分之三、直到全部設備。
1.TDengine的聚合函數性能
測試SQL語句存儲在tdengine/q2.txt中,測試SQL語句參考
select count(*) from db.devices where devgroup<10;
執行方法如下
./tdengineTest -sql ./q2.txt
查詢速度如下表,單位為秒
| Latency | 10% | 20% | 30% | 40% | 50% | 60% | 70% | 80% | 90% | 100% |
|---|---|---|---|---|---|---|---|---|---|---|
| count | 0.018 | 0.026 | 0.016 | 0.018 | 0.017 | 0.024 | 0.024 | 0.027 | 0.030 | 0.033 |
| avg | 0.007 | 0.014 | 0.015 | 0.020 | 0.024 | 0.038 | 0.044 | 0.050 | 0.057 | 0.060 |
| sum | 0.006 | 0.010 | 0.019 | 0.018 | 0.031 | 0.036 | 0.034 | 0.037 | 0.043 | 0.046 |
| max | 0.007 | 0.013 | 0.015 | 0.020 | 0.025 | 0.030 | 0.035 | 0.039 | 0.045 | 0.049 |
| min | 0.006 | 0.010 | 0.016 | 0.024 | 0.032 | 0.039 | 0.045 | 0.041 | 0.043 | 0.049 |

2.OpenTSDB的聚合函數性能
OpenTSDB的查詢語句為json語句,已寫在代碼里,測試時只需選擇執行哪項查詢即可。
測試SQL的選項(sqlchoice)為q2
執行方法如下
java -jar opentsdbtest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql q2
查詢速度如下表,單位為秒
| Latency | 10% | 20% | 30% | 40% | 50% | 60% | 70% | 80% | 90% | 100% |
|---|---|---|---|---|---|---|---|---|---|---|
| count | 67.82 | 67.3 | 66.87 | 67.17 | 66.67 | 67.23 | 67.17 | 66.88 | 67.1 | 66.72 |
| mean | 66.62 | 67.3 | 67.21 | 67.1 | 67.07 | 66.76 | 67.31 | 67.00 | 66.52 | 66.99 |
| sum | 67.12 | 66.79 | 67.68 | 66.90 | 67.41 | 66.59 | 66.95 | 67.1 | 66.74 | 66.59 |
| max | 66.55 | 67.13 | 66.93 | 67.12 | 66.96 | 67.15 | 66.91 | 66.73 | 67.1 | 67.29 |
| min | 66.82 | 67.03 | 66.66 | 66.5 | 66.82 | 66.64 | 67.36 | 67.04 | 66.51 | 66.67 |

3.聚合函數性能對比
基于以上的測試數據,將TDengine和OpenTSDB在1億條記錄數據集的測試結果進行對比
| Latency | count | average | sum | max | min |
|---|---|---|---|---|---|
| TDengine | 0.033 | 0.06 | 0.046 | 0.049 | 0.049 |
| OpenTSDB | 66.72 | 66.99 | 66.59 | 67.29 | 66.67 | >

從圖7可以看出,TDengine的聚合函數查詢時間在100毫秒以內,而OpenTSDB的查詢時間在66秒左右。因此可以得出結論,在同等數據集和硬件環境下,TDengine的聚合速度遠遠高于OpenTSDB,超過1000倍。
按標簽分組查詢性能對比
本測試做了按標簽分組函數的性能測試,測試函數會搭配篩選條件(WHERE)來選取設備的十分之一、十分之二、十分之三、直到全部設備。
1. TDengine的測試方法
測試SQL語句存儲在tdengine/q3.txt中,例如
select count(temperature), sum(temperature), avg(temperature) from db.devices where devgroup<10 group by devgroup;
執行方法如下
./tdengineTest -sql ./q3.txt
2. OpenTSDB的測試方法
測試SQL的選項(sqlchoice)為q3
執行方法如下
java -jar opentsdbtest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql q3
讀取速度如下,單位為秒
| Latency | 10% | 20% | 30% | 40% | 50% | 60% | 70% | 80% | 90% | 100% |
|---|---|---|---|---|---|---|---|---|---|---|
| TDengine | 0.030 | 0.028 | 0.031 | 0.041 | 0.069 | 0.066 | 0.077 | 0.091 | 0.102 | 0.123 |
| OpenTSDB | 125.91 | 127.39 | 126.79 | 126.42 | 125.73 | 126.85 | 127.77 | 126.99 | 127.16 | 126.41 |

從測試結果來看,TDengine的分組聚合查詢速度遠高于OpenTSDB,約為1000倍。
按時間分組性能對比
本測試做了按時間分組函數的性能測試,測試函數會搭配篩選條件(WHERE)來選取設備的十分之一、十分之二、十分之三、直到全部設備。
1. TDengine的測試方法
測試SQL語句存儲在tdengine/q4.txt中,例如
select count(temperature), sum(temperature), avg(temperature) from db.devices where devgroup<10 interval(1m);
執行方法如下
./tdengineTest -sql ./q4.txt
2. OpenTSDB的測試方法
測試SQL的選項(sqlchoice)為q4
執行方法如下
java -jar opentsdbtest-1.0-SNAPSHOT-jar-with-dependencies.jar -sql q4
讀取速度如下,單位為秒
| Latency | 10% | 20% | 30% | 40% | 50% | 60% | 70% | 80% | 90% | 100% |
|---|---|---|---|---|---|---|---|---|---|---|
| TDengine | 0.237 | 0.472 | 0.653 | 0.902 | 1.134 | 1.422 | 1.753 | 1.784 | 2.085 | 2.549 |
| OpenTSDB | 82.53 | 83.04 | 83.93 | 82.74 | 82.96 | 82.75 | 82.14 | 82.37 | 83.29 | 82.46 |

從測試結果來看,TDengine的按時間分組聚合查詢速度遠高于OpenTSDB,約為40倍。
壓縮比對比
1.原始數據的磁盤占用
本次測試共生成100個測試數據文件,存儲在~/testdata目錄下,使用du命令查看~/testdata目錄的文件大小
cd ~/testdata
du -h .
如下圖所示

2.查看TDengine的磁盤占用
TDengine的磁盤文件默認位置在目錄/var/lib/taos/data下,在查看磁盤文件大小時,首先將TDengine的服務停止
sudo systemctl stop taosd
然后,調用du命令,查看/var/lib/taos/data目錄下文件的大小
cd /var/lib/taos/data
du -h .
如下圖所示

3.查看OpenTSDB的磁盤占用
OpenTSDB的磁盤文件默認位置在目錄/var/lib/hbase/data/下,在查看磁盤文件大小時,首先將OpenTSDB的服務停止
sudo service opentsdb stop
調用du命令,查看該目錄下文件的大小。
cd /var/lib/hbase/data/
du -sh
如下圖所示

4.磁盤占用情況對比
生成的測試數據文件占用的磁盤大小為3941MB,OpenTSDB磁盤占用2.3GB,TDengine磁盤占用459MB。在相對比較隨機數據集的情況下,TDengine的壓縮比約為OpenTSDB壓縮比的5倍。
在物聯網場景下,大多數采集數據的變化范圍都比較小。由于TDengine采用列式存儲,因此可以預期,TDengine在真實場景的壓縮比表現會更好。
功能對比
TDengine與OpenTSDB都是用與處理時序數據的存儲引擎,其功能比較接近,各有特色。
| 功能支持 | TDengine | OpenTSDB |
|---|---|---|
| SQL語法支持 | 支持 | 不支持 |
| 私有化部署支持 | 支持 | 支持 |
| 水平擴展能力 | 支持 | 支持 |
| 系統連接管理 | 支持 | 支持 |
| 查詢任務管理 | 支持 | 支持 |
| 數據導入工具 | 支持 | 支持 |
| 數據導出工具 | 支持 | 支持 |
| Web管理工具 | 支持 | 支持 |
| 多介質分級存儲 | 支持 | 支持 |
| Telegraf數據采集 | 支持 | 支持 |
| Grafana數據可視化 | 支持 | 支持 |
| RESTFul | 支持 | 支持 |
| C/C++ | 支持 | 不支持 |
| JDBC/ODBC | 支持 | 不支持 |
| GO | 支持 | 不支持 |
| Python | 支持 | 不支持 |
| 數據庫參數配置 | 支持 | 支持 |
| 配置副本數 | 支持 | 支持 |
| 數據時效 | 支持 | 支持 |
| 數據分區 | 支持 | 支持 |
| 流式計算 | 支持 | 不支持 |
| 微秒級精度 | 支持 | 支持 |
| 聚合函數支持 | 支持 | 支持 |
| 數據降采樣 | 支持 | 支持 |
| 數據分頁 | 支持 | 支持 |
| 數據插值 | 支持 | 支持 |
| 歷史數據修改 | 不支持 | 支持 |
| 歷史數據的標簽修改 | 支持 | 支持 |
| 時間線刪除 | 支持 | 支持 |
| 數據清空 | 支持 | 支持 |
總結
此次測試,從數據庫的讀、寫、查詢、壓縮比等方面對TDengine和OpenTSDB進行了對比測試。測試用數據集、測試程序源碼、執行的SQL語句都可以從 下載,測試具備可重復性。
從測試結果上看,TDengine的性能遠超OpenTSDB,寫入性能約為25倍,讀取性能約為32倍,聚合函數性能約為1000倍,按標簽分組查詢性能約為1000倍,按時間分組查詢性能約為40倍,壓縮比約為5倍,具體見下表。
| TDengine | OpenTSDB | |
|---|---|---|
| 寫入吞吐量 | 1477208 記錄數/秒 | 57272 記錄數/秒 |
| 100萬條記錄讀取時間 | 0.21秒 | 6.57秒 |
| 1億條記錄取平均值時間 | 0.06秒 | 66.99秒 |
| 1億條記錄按標簽分組取均值時間 | 0.123 | 126.41秒 |
| 1億條記錄按時間分組取均值時間 | 2.549秒 | 82.46秒 |



























