測試工具
測試工具
概述
IoT-benchmark 是基于 Java 和大數據環境開發的時序數據庫基準測試工具,由清華大學軟件學院研發并開源。它使用方便,支持多種寫入以及查詢方式,支持存儲測試信息和結果以供進一步查詢或分析,支持與 Tableau 集成以可視化測試結果。
下圖1-1囊括了測試基準流程及其他擴展功能。這些流程可以由IoT-benchmark 統一來完成。IoT Benchmark 支持多種工作負載,包括純寫入、純查詢、寫入查詢混合等,支持軟硬件系統監控、測試指標度量等監控功能,還實現了初始化數據庫自動化、測試數據分析及系統參數優化等功能。

圖1-1
借鑒 YCSB 測試工具將工作負載生成、性能指標測量和數據庫接口三個組件分離的設計思想,IoT-benchmark 的模塊化設計如圖1-2所示。與基于 YCSB 的測試工具系統不同的是,IoT-benchmark 增加了系統監控模塊,支持測試數據和系統指標監控數據的持久化。此外也增加了一些特別針對時序數據場景的特殊負載測試功能,如支持物聯網場景的批量寫入和多種亂序數據寫入模式。

圖1-2
目前 IoT-benchmark 支持如下時間序列數據庫、版本和連接方式:
| 數據庫 | 版本 | 連接方式 |
|---|---|---|
| InfluxDB | v1.x v2.0 | SDK |
| TimescaleDB | -- | jdbc |
| OpenTSDB | -- | Http Request |
| QuestDB | v6.0.7 | jdbc |
| TDengine | v2.2.0.2 | jdbc |
| VictoriaMetrics | v1.64.0 | Http Request |
| KairosDB | -- | Http Request |
| IoTDB | v1.x v0.13 | jdbc、sessionByTablet、sessionByRecord、sessionByRecords |
表1-1大數據測試基準對比
軟件安裝與環境搭建
IoT Benchmark 運行的前置條件
- Java 8
- Maven 3.6+
- 對應的合適版本的數據庫,如 Apache IoTDB 1.0
IoT Benchmark 的獲取方式
- 獲取二進制包:進入https://github.com/thulab/iot-benchmark/releases 下載需要的安裝包。下載下來為一個壓縮文件,選擇文件夾解壓即可使用。
- 源代碼編譯(可用戶 Apache IoTDB 1.0 的測試):
- 第一步(編譯 IoTDB Session 最新包):進入官網 https://github.com/apache/iotdb/tree/rel/1.0 下載 IoTDB 源碼,在根目錄下運行命令 mvn clean package install -pl session -am -DskipTests 編譯 IoTDB Session 的最新包。
- 第二步(編譯 IoTDB Benchmark 測試包):進入官網 https://github.com/thulab/iot-benchmark 下載源碼,在根目錄下運行 mvn clean package install -pl iotdb-1.0 -am -DskipTests 編譯測試 Apache IoTDB 1.0版本的測試包,測試包位置與根目錄的相對路徑為 ./iotdb-1.0/target/iotdb-1.0-0.0.1/iotdb-1.0-0.0.1
IoT Benchmark 的測試包結構
測試包的目錄結構如下圖1-3所示。其中測試配置文件為conf/config.properties,測試啟動腳本為benchmark.sh (Linux & MacOS) 和 benchmark.bat (Windows),詳細文件用途見表1-2所示。

圖1-3文件和文件夾列表
| 名稱 | 子文件 | 用途 |
|---|---|---|
| benchmark.bat | - | Windows環境運行啟動腳本 |
| benchmark.sh | - | Linux/Mac環境運行啟動腳本 |
| conf | config.properties | 測試場景配置文件 |
| logback.xml | 日志輸出配置文件 | |
| lib | - | 依賴庫文件 |
| LICENSE | - | 許可文件 |
| bin | startup.sh | 初始化腳本文件夾 |
| ser-benchmark.sh | - | 監控模式啟動腳本 |
表1-2文件和文件夾列表用途
IoT Benchmark 執行測試
- 按照測試需求修改配置文件,主要參數介紹見 1.2 節,對應配置文件為conf/config.properties,比如測試Apache IoTDB 1.0,則需要修改 DB_SWITCH=IoTDB-100-SESSION_BY_TABLET
- 啟動被測時間序列數據庫
- 通過運行
- 啟動IoT-benchmark執行測試。執行中觀測被測時間序列數據庫和IoT-benchmark狀態,執行完畢后查看結果和分析測試過程。
IoT Benchmark 結果說明
測試的所有日志文件被存放于 logs 文件夾下,測試的結果在測試完成后被存放到 data/csvOutput 文件夾下,例如測試后我們得到了如下的結果矩陣:

- Result Matrix
- OkOperation:成功的對應操作次數
- OkPoint:對于寫入操作,是成功寫入的點數;對于查詢操作,是成功查詢到的點數。
- FailOperation:失敗的對應操作次數
- FailPoint:對于寫入操作是寫入失敗的點數
- Latency(mx) Matrix
- AVG:操作平均耗時
- MIN:操作最小耗時
- Pn:操作整體分布的對應分位值,比如P25是下四分位數
主要參數介紹
本節重點解釋說明了主要參數的用途和配置方法。
工作模式和操作比例
工作模式參數“BENCHMARK_WORK_MODE”可選項為“默認模式”和“服務器監控”;其中“服務器監控”模式可直接通過執行ser-benchmark.sh腳本啟動,腳本會自動修改該參數。“默認模式”為常用測試模式,結合配置OPERATION_PROPORTION參數達到“純寫入”、“純查詢”和“讀寫混合”的測試操作比例定義
當運行ServerMode來執行被測時序數據庫運行環境監控時IoT-benchmark依賴sysstat軟件相關命令;如果需要持久化測試過程數據時選擇MySQL或IoTDB,則需要安裝該類數據庫;ServerMode和CSV的記錄模式只能在Linux系統中使用,記錄測試過程中的相關系統信息。因此我們建議使用MacOs或Linux系統,本文以Linux(Centos7)系統為例,如果使用Windows系統,可以使用conf文件夾下的benchmark.bat腳本啟動IoT-benchmark。
表1-3測試模式
| 模式名稱 | BENCHMARK_WORK_MODE | 模式內容 |
|---|---|---|
| 常規測試模式 | testWithDefaultPath | 支持多種讀和寫操作的混合負載 |
| 服務器資源使用監控模式 | serverMODE | 服務器資源使用監控模式(該模式下運行通過ser-benchmark.sh腳本啟動,無需手動配置該參數 |
服務器連接信息
工作模式指定后,被測時序數據庫的信息要如何告知IoT-benchmark呢?當前通過“DB_SWITCH”告知被測時序數據庫類型;通過“HOST”告知被測時序數據庫網絡地址;通過“PORT”告知被測時序數據庫網絡端口;通過“USERNAME”告知被測時序數據庫登錄用戶名;通過“PASSWORD”告知被測時序數據庫登錄用戶的密碼;通過“DB_NAME”告知被測時序數據庫名稱;通過“TOKEN”告知被測時序數據庫連接認證Token(InfluxDB 2.0使用);
寫入場景構建參數
表1-4寫入場景構建參數
| 參數名稱 | 類型 | 示例 | 系統描述 |
|---|---|---|---|
| CLIENT_NUMBER | 整數 | 100 | 客戶端總數 |
| GROUP_NUMBER | 整數 | 20 | 數據庫的數量;僅針對IoTDB。 |
| DEVICE_NUMBER | 整數 | 100 | 設備總數 |
| SENSOR_NUMBER | 整數 | 300 | 每個設備的傳感器總數 |
| INSERT_DATATYPE_PROPORTION | 字符串 | 1:1:1:1:1:1 | 設備的數據類型比例,BOOLEAN:INT32:INT64:FLOAT:DOUBLE:TEXT |
| POINT_STEP | 整數 | 1000 | 數據間時間戳間隔,即生成的數據兩個時間戳之間的固定長度。 |
| OP_MIN_INTERVAL | 整數 | 0 | 操作最小執行間隔:若操作耗時大于該值則立即執行下一個,否則等待 (OP_MIN_INTERVAL-實際執行時間) ms;如果為0,則參數不生效;如果為-1,則其值和POINT_STEP一致 |
| IS_OUT_OF_ORDER | 布爾 | false | 是否亂序寫入 |
| OUT_OF_ORDER_RATIO | 浮點數 | 0.3 | 亂序寫入的數據比例 |
| BATCH_SIZE_PER_WRITE | 整數 | 1 | 批寫入數據行數(一次寫入多少行數據) |
| START_TIME | 時間 | 2022-10-30T00:00:00+08:00 | 寫入數據的開始時間戳;以該時間戳為起點開始模擬創建數據時間戳。 |
| LOOP | 整數 | 86400 | 總操作次數:具體每種類型操作會按OPERATION_PROPORTION定義的比例劃分 |
| OPERATION_PROPORTION | 字符 | 1:0:0:0:0:0:0:0:0:0:0 | # 各操作的比例,按照順序為 寫入:Q1:Q2:Q3:Q4:Q5:Q6:Q7:Q8:Q9:Q10, 請注意使用英文冒號。比例中的每一項是整數。 |
按照表1-4配置參數啟動可描述測試場景為:向被測時序數據庫壓力寫入30000個(100個設備,每個設備300個傳感器)時間序列2022年10月30日一天的順序數據,總計25.92億個數據點。其中每個設備的300個傳感器數據類型分別為50個布爾、50個整數、50個長整數、50個浮點、50個雙精度、50個字符。如果我們將表格中IS_OUT_OF_ORDER的值改為true,那么他表示的場景為:向被測時序數據庫壓力寫入30000個時間序列2022年10月30日一天的數據,其中存在30%的亂序數據(到達時序數據庫時間晚于其他生成時間晚于自身的數據點)。
查詢場景構建參數
表1-5查詢場景構建參數
| 參數名稱 | 類型 | 示例 | 系統描述 |
|---|---|---|---|
| QUERY_DEVICE_NUM | 整數 | 2 | 每條查詢語句中查詢涉及到的設備數量 |
| QUERY_SENSOR_NUM | 整數 | 2 | 每條查詢語句中查詢涉及到的傳感器數量 |
| QUERY_AGGREGATE_FUN | 字符 | count | 在聚集查詢中使用的聚集函數,比如count、avg、sum、max_time等 |
| STEP_SIZE | 整數 | 1 | 時間過濾條件的時間起點變化步長,若設為0則每個查詢的時間過濾條件是一樣的,單位:POINT_STEP |
| QUERY_INTERVAL | 整數 | 250000 | 起止時間的查詢中開始時間與結束時間之間的時間間隔,和Group By中的時間間隔 |
| QUERY_LOWER_VALUE | 整數 | -5 | 條件查詢子句時的參數,where xxx > QUERY_LOWER_VALUE |
| GROUP_BY_TIME_UNIT | 整數 | 20000 | Group by語句中的組的大小 |
| LOOP | 整數 | 10 | 總操作次數:具體每種類型操作會按OPERATION_PROPORTION定義的比例劃分 |
| OPERATION_PROPORTION | 字符 | 0:0:0:0:0:0:0:0:0:0:1 | 寫入:Q1:Q2:Q3:Q4:Q5:Q6:Q7:Q8:Q9:Q10 |
表1-6查詢類型及示例 SQL
| 編號 | 查詢類型 | IoTDB 示例 SQL |
|---|---|---|
| Q1 | 精確點查詢 | select v1 from root.db.d1 where time = ? |
| Q2 | 時間范圍查詢 | select v1 from root.db.d1 where time > ? and time < ? |
| Q3 | 帶值過濾的時間范圍查詢 | select v1 from root.db.d1 where time > ? and time < ? and v1 > ? |
| Q4 | 時間范圍聚合查詢 | select count(v1) from root.db.d1 where and time > ? and time < ? |
| Q5 | 帶值過濾的全時間范圍聚合查詢 | select count(v1) from root.db.d1 where v1 > ? |
| Q6 | 帶值過濾的時間范圍聚合查詢 | select count(v1) from root.db.d1 where v1 > ? and time > ? and time < ? |
| Q7 | 時間分組聚合查詢 | select count(v1) from root.db.d1 group by ([?, ?), ?, ?) |
| Q8 | 最新點查詢 | select last v1 from root.db.d1 |
| Q9 | 倒序范圍查詢 | select v1 from root.sg.d1 where time > ? and time < ? order by time desc |
| Q10 | 倒序帶值過濾的范圍查詢 | select v1 from root.sg.d1 where time > ? and time < ? and v1 > ? order by time desc |
按照表1-5配置參數啟動可描述測試場景為:從被測時序數據庫執行10次2個設備2個傳感器的倒序帶值過濾的范圍查詢,SQL語句為:select s_0,s_31from data where time >2022-10-30T00:00:00+08:00 and time < 2022-10-30T00:04:10+08:00 and s_0 > -5 and device in d_21,d_46 order by time desc。
測試過程和測試結果持久化
IoT-benchmark目前支持通過配置參數“TEST_DATA_PERSISTENCE”將測試過程和測試結果持久化到IoTDB、MySQL和CSV;其中寫入到MySQL和CSV可以定義分庫分表的行數上限,例如“RECORD_SPLIT=true、RECORD_SPLIT_MAX_LINE=10000000”表示每個數據庫表或CSV文件按照總行數為1千萬切分存放;如果記錄到MySQL或IoTDB需要提供數據庫鏈接信息,分別包括“TEST_DATA_STORE_IP”數據庫的IP地址、“TEST_DATA_STORE_PORT”數據庫的端口號、“TEST_DATA_STORE_DB”數據庫的名稱、“TEST_DATA_STORE_USER”數據庫用戶名、“TEST_DATA_STORE_PW”數據庫用戶密碼。
如果我們設置“TEST_DATA_PERSISTENCE=CSV”,測試執行時和執行完畢后我們可以在IoT-benchmark根目錄下看到新生成的data文件夾,其下包含csv文件夾記錄測試過程;csvOutput文件夾記錄測試結果。如果我們設置“TEST_DATA_PERSISTENCE=MySQL”,它會在測試開始前在指定的MySQL數據庫中創建命名如“testWithDefaultPath_被測數據庫名稱_備注_測試啟動時間”的數據表記錄測試過程;會在名為“CONFIG”的數據表(如果不存在則創建該表),寫入本次測試的配置信息;當測試完成時會在名為“FINAL_RESULT”的數據表(如果不存在則創建該表)中寫入本次測試結果。
實際案例
我們以中車青島四方車輛研究所有限公司應用為例,參考《ApacheIoTDB在智能運維平臺存儲中的應用》中描述的場景進行實際操作說明。
測試目標:模擬中車青島四方所場景因切換時間序列數據庫實際需求,對比預期使用的IoTDB和原有系統使用的KairosDB性能。
測試環境:為了保證在實驗過程中消除其他無關服務與進程對數據庫性能的影響,以及不同數據庫之間的相互影響,本實驗中的本地數據庫均部署并運行在資源配置相同的多個獨立的虛擬機上。因此,本實驗搭建了 4 臺 Linux( CentOS7 /x86) 虛擬機,并分別在上面部署了IoT-benchmark、 IoTDB數據庫、KairosDB數據庫、MySQL數據庫。每一臺虛擬機的具體資源配置如表2-1所示。每一臺虛擬機的具體用途如表2-2所示。
表2-1虛擬機配置信息
| 硬件配置信息 | 系統描述 |
|---|---|
| OS System | CentOS7 |
| CPU核數 | 16 |
| 內存 | 32G |
| 硬盤 | 200G |
| 網卡 | 千兆 |
表2-2虛擬機用途
| IP | 用途 |
|---|---|
| 172.21.4.2 | IoT-benchmark |
| 172.21.4.3 | Apache-iotdb |
| 172.21.4.4 | KaiosDB |
| 172.21.4.5 | MySQL |
寫入測試
場景描述:創建100個客戶端來模擬100列車、每列車3000個傳感器、數據類型為DOUBLE類型、數據時間間隔為500ms(2Hz)、順序發送。參考以上需求我們需要修改IoT-benchmark配置參數如表2-3中所列。
表2-3配置參數信息
| 參數名稱 | IoTDB值 | KairosDB值 |
|---|---|---|
| DB_SWITCH | IoTDB-013-SESSION_BY_TABLET | KairosDB |
| HOST | 172.21.4.3 | 172.21.4.4 |
| PORT | 6667 | 8080 |
| BENCHMARK_WORK_MODE | testWithDefaultPath | |
| OPERATION_PROPORTION | 1:0:0:0:0:0:0:0:0:0:0 | |
| CLIENT_NUMBER | 100 | |
| GROUP_NUMBER | 10 | |
| DEVICE_NUMBER | 100 | |
| SENSOR_NUMBER | 3000 | |
| INSERT_DATATYPE_PROPORTION | 0:0:0:0:1:0 | |
| POINT_STEP | 500 | |
| OP_MIN_INTERVAL | 0 | |
| IS_OUT_OF_ORDER | false | |
| BATCH_SIZE_PER_WRITE | 1 | |
| LOOP | 10000 | |
| TEST_DATA_PERSISTENCE | MySQL | |
| TEST_DATA_STORE_IP | 172.21.4.5 | |
| TEST_DATA_STORE_PORT | 3306 | |
| TEST_DATA_STORE_DB | demo | |
| TEST_DATA_STORE_USER | root | |
| TEST_DATA_STORE_PW | admin | |
| REMARK | demo |
首先在172.21.4.3和172.21.4.4上分別啟動被測時間序列數據庫Apache-IoTDB和KairosDB,之后在172.21.4.2、172.21.4.3和172.21.4.4上通過ser-benchamrk.sh腳本啟動服務器資源監控(圖2-1)。然后按照表2-3在172.21.4.2分別修改iotdb-0.13-0.0.1和kairosdb-0.0.1文件夾內的conf/config.properties文件滿足測試需求。先后使用benchmark.sh啟動對Apache-IoTDB和KairosDB的寫入測試。

圖2-1服務器監控任務
? 例如我們首先啟動對KairosDB的測試,IoT-benchmark會在MySQL數據庫中創建CONFIG數據表存放本次測試配置信息(圖2-2),測試執行中會有日志輸出當前測試進度(圖2-3)。測試完成時會輸出本次測試結果(圖2-3),同時將結果寫入FINAL_RESULT數據表中(圖2-4)。

圖2-2測試配置信息表




圖2-3測試進度和結果

圖2-4測試結果表
之后我們再啟動對Apache-IoTDB的測試,同樣的IoT-benchmark會在MySQL數據庫CONFIG數據表中寫入本次測試配置信息,測試執行中會有日志輸出當前測試進度。測試完成時會輸出本次測試結果,同時將結果寫入FINAL_RESULT數據表中。
依照測試結果信息我們知道同樣的配置寫入Apache-IoTDB和KairosDB寫入延時時間分別為:55.98ms和1324.45ms;寫入吞吐分別為:5,125,600.86點/秒和224,819.01點/秒;測試分別執行了585.30秒和11777.99秒。并且KairosDB有寫入失敗出現,排查后發現是數據磁盤使用率已達到100%,無磁盤空間繼續接收數據。而Apache-IoTDB無寫入失敗現象,全部數據寫入完畢后占用磁盤空間僅為4.7G(如圖2-5所示);從寫入吞吐和磁盤占用情況上看Apache-IoTDB均優于KairosDB。當然后續還有其他測試來從多方面觀察和對比,比如查詢性能、文件壓縮比、數據安全性等。

圖2-5磁盤使用情況
那么測試過程中各個服務器資源使用情況如何呢?每個寫操作具體的表現如何呢?這個時候我們就可以通過安裝和使用Tableau來可視化服務器監控表和測試過程記錄表內的數據了。Tableau的使用本文不展開介紹,通過它連接測試數據持久化的數據表后具體結果下如圖(以Apache-IoTDB為例):


圖2-6Tableau可視化測試過程
查詢測試
場景描述:在寫入測試場景下模擬10個客戶端對時序數據庫Apache-IoTDB內存放的數據進行全類型查詢任務。配置如下:
表2-4配置參數信息
| 參數名稱 | 示例 |
|---|---|
| CLIENT_NUMBER | 10 |
| QUERY_DEVICE_NUM | 2 |
| QUERY_SENSOR_NUM | 2 |
| QUERY_AGGREGATE_FUN | count |
| STEP_SIZE | 1 |
| QUERY_INTERVAL | 250000 |
| QUERY_LOWER_VALUE | -5 |
| GROUP_BY_TIME_UNIT | 20000 |
| LOOP | 30 |
| OPERATION_PROPORTION | 0:1:1:1:1:1:1:1:1:1:1 |
執行結果:

圖2-7查詢測試結果
其他參數說明
之前章節中針對Apache-IoTDB和KairosDB進行寫入性能對比,但是用戶如果要執行模擬真實寫入速率測試該如何配置?測試時間過長該如何控制呢?生成的模擬數據有哪些規律嗎?如果IoT-Benchmark服務器配置較低,可以使用多臺機器模擬壓力輸出嗎?
表2-5配置參數信息
| 場景 | 參數 | 值 | 說明 |
|---|---|---|---|
| 模擬真實寫入速率 | OP_INTERVAL | -1 | 也可輸入整數控制操作間隔 |
| 指定測試時長(1小時) | TEST_MAX_TIME | 3600000 | 單位 ms;需要LOOP執行時間大于該值 |
| 定義模擬數據規律:支持全部數據類型,數量平均分類;支持五種數據分布,數量平均分布;字符串長度為10;小數位數為2 | INSERT_DATATYPE_PROPORTION | 1:1:1:1:1:1 | 數據類型分布比率 |
| LINE_RATIO | 1 | 線性 | |
| SIN_RATIO | 1 | 傅里葉函數 | |
| SQUARE_RATIO | 1 | 方波 | |
| RANDOM_RATIO | 1 | 隨機數 | |
| CONSTANT_RATIO | 1 | 常數 | |
| STRING_LENGTH | 10 | 字符串長度 | |
| DOUBLE_LENGTH | 2 | 小數位數 | |
| 三臺機器模擬300臺設備數據寫入 | BENCHMARK_CLUSTER | true | 開啟多benchmark模式 |
| BENCHMARK_INDEX | 0、1、3 | 以寫入測試寫入參數為例:0號負責設備編號0-99數據寫入;1號負責設備編號100-199數據寫入;2號負責設備編號200-299數據寫入; |