私は日々 TiDB に関するテクニカルサポートの仕事をしています。お客様の問題を解決するため、お客様のアプリケーションの特徴を観察し、重要なクエリをピックアップして、ローカルでアプリケーションの問題を再現することがよくあります。今回は、私に書かれたこのより実環境に近い負荷をかけることができるツール「Database Workload」を紹介したいと思います。
概要
このツールは、単純なランダムデータだけでなく、データの分布(パレート分布など)やデータ型(数値、文字列、日付、配列)を細かく制御できる負荷生成ツールです。
Go言語で記述されており、設定ファイル(config.json)を編集するだけで、複雑なシナリオのテストデータを生成・投入することが可能です。
主な特徴
- Long connection (Connection pool) また、Short connection(PHP等の使い方) の模擬
- 多様なデータ生成: 数値、文字列、日付、配列などに対応
-
高度な分布制御:
- 一様分布 (Uniform): 均等にランダムな値を生成
- べき乗則分布 (Power Law): アクセス頻度に偏りがある(「80:20の法則」のような)状況をシミュレート
- パーティション付きべき乗則: シャーディングされた環境などを想定した分布
- 重み付きセット: 特定の値を指定した確率で出現させる
設定ファイルの例 (sysbench-config.json)
以下は、sysbench-config.json をベースにした設定例です。
この設定では、100並列でトランザクションを使用し、sbtest テーブルに対してクエリを発行します。
{
"concurrency": 100,
"db_conn_str": "root:@tcp(127.0.0.1:4000)/test?parseTime=true&interpolateParams=true&timeout=3s&readTimeout=3s&writeTimeout=3s",
"use_transaction": true,
"connection_type": "long",
"rate_per_thread": 50,
"templates": [
{
"sql": "SELECT * from sbtest? WHERE id = ?",
"repeat": 10,
"params": [
{
"type": "number",
"random_mode": "uniform",
"min": 1,
"max": 10,
"comment": "テーブル番号 (sbtest1 ~ sbtest10)"
},
{
"type": "number",
"random_mode": "uniform",
"min": 1,
"max": 10000,
"comment": "ID範囲 (1 ~ 10000)"
}
]
}
]
}
ポイント
-
concurrency: 同時実行スレッド数を指定します -
templates: 実行するSQLテンプレートを定義します。?プレースホルダに対して、paramsで定義したルールに従って値が埋め込まれます -
random_mode:"uniform"(一様分布) や"power_law"(偏りあり) などを指定するだけで、データの傾向を簡単に変更できます -
use_transaction: templates のクエリは begin~commit ブロックに入れてトランザクションとして実行されるか -
connection_type:longがコネクションプールで、shortは都度切断 -
rate_per_thread: templates のすべてのクエリを1つのトランザクションとして、秒間の実行回数の上限
使い方
ビルドして設定ファイルを指定するだけで実行可能です。
# ビルド
go build -o database_workload main.go
# 実行
./database_workload -config sysbench-config.json
config.json によく複雑な設定例があります。
例えば下記は、文字列の配列のランダムパラメーターを定義しています。文字列は数字から "abc_%d" のフォーマットに生成されて、数字は 1 ~ 100000000 に partition: 2000 の range に分けて、各Rangeにべき乗則分布 (Power Law)で生成されます。
{
"sql": "SELECT * FROM sbtest1 WHERE c in (?)",
"params": [
{
"type": "array",
"array_size": 4,
"element_type": "string",
"element_config": {
"type": "string",
"random_mode": "number_format",
"format": "abc_%d",
"number_config": {
"random_mode": "partition_power_law",
"min": 1,
"max": 100000000,
"exponent": 1.001,
"partition": 2000
}
}
}
]
}
おわりに
従来のベンチマークツールでは再現が難しかった「特定のデータにアクセスが集中する」といったシナリオも、設定ひとつで柔軟に作成できます。
データベースのパフォーマンスチューニングや検証にぜひお役立てください。