MySQLの負荷試験といえば、sysbenchがよく使われると思います。oltp_
一方で運用者目線でMySQLの構成や設定を変更するとき、単純化された合成OLTPだけでは見えにくい、より実際の業務に近い複数テーブルにまたがる更新処理の負荷を見たいと思う場面があるかと思います。
そこで今回は、go-tpcc
TPC-Cとは
TPC-Cは、卸売業者の受注処理
具体的には以下の5つのトランザクションが一定の比率で実行されます。
| トランザクション | 比率 | 業務イメージ | 主なDB操作 |
|---|---|---|---|
| New-Order | 45% | 新規注文 | 注文/明細追加+在庫更新 |
| Payment | 43% | 入金処理 | 顧客/売上の更新+履歴追加 |
| Order-Status | 4% | 注文照会 | 最新注文と明細を参照 |
| Delivery | 4% | 配送処理 | 未配送注文をまとめて更新 |
| Stock-Level | 4% | 在庫確認 | 直近注文に基づく在庫参照 |
sysbenchにおける一般的なベンチマークとの違いは、複数テーブルにまたがるトランザクションを前提にしている点です。単一テーブルへの読み書きが中心のシナリオに比べ、TPC-Cはトランザクション分離レベルの影響やロック待ち、デッドロックといった挙動が結果に出やすくなります。スレッド数を上げると急にレイテンシが跳ねるなどといった、本番環境で遭遇しがちな現象を再現しやすいのが特徴です。
go-tpcでベンチマーク測定
今回使用するgo-tpcは、TiDBの開発元であるPingCAP社が公開しているベンチマークツールです。Go言語製でインストールが容易なうえ、MySQL互換プロトコルで動作するため、通常のMySQLに対してもそのまま使用できます。
インストール
公式READMEでワンライナー導入が案内されており、以下のコマンドでインストールできます。
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/pingcap/go-tpc/master/install.sh | sh go-tpc --help
なお、go-tpc ではデフォルトの接続ポートが4000--port 3306を明示的に指定する必要がある点に注意してください。
①データの準備(prepare)
まず、ベンチマーク用のデータベースを作成しておきます。
mysql -h 127.0.0.1 -P 3306 -u root -p'P@ssw0rd' -e 'CREATE DATABASE tpcc;'
次にprepareコマンドでテストデータを準備します。go-tpcでは、 --warehouseオプションでデータ規模を指定します。warehousesを1つ増やすと単に行数が増えるのではなく、倉庫1拠点分のデータセット
ここでは例として、warehouses 10で準備します。
go-tpc tpcc \ --host 127.0.0.1 --port 3306 --user root --password 'P@ssw0rd' \ --db tpcc --warehouses 10 prepare --threads 4
②ベンチマーク実行(run)
prepareが完了したら、runコマンドでベンチマークを実行します。--timeで実行時間、--threadsで並列度を指定します。
go-tpc tpcc \ --host 127.0.0.1 --port 3306 --user root --password 'P@ssw0rd' \ --db tpcc --warehouses 10 run --threads 32 --time 600s
③整合性チェック(check)
ベンチマークが取れたら、checkコマンドでデータの整合性を確認できます。sysbenchの一般的なシナリオでは結果のQPSやLatencyを見れば基本的には良いですが、TPC-Cのような複雑なワークロードではデッドロックやタイムアウトによるロールバックによって、数字上のスループットはでているがデータとしては不整合がある状態になる可能性があります。
check コマンドで、注文・
go-tpc tpcc \ --host 127.0.0.1 --port 3306 --user root --password 'P@ssw0rd' \ --db tpcc --warehouses 10 check
④片付け(cleanup)
検証が終わったら、cleanupでテストデータを削除します。
go-tpc tpcc \ --host 127.0.0.1 --port 3306 --user root --password 'P@ssw0rd' \ --db tpcc --warehouses 10 cleanup
結果の見方
go-tpcは実行中に [Current]、完走後に [Summary] の形式で、トランザクション種別ごとの統計を出力します。[Current]には一定間隔ごとの区間統計が表示されます。TPC-Cのシナリオでは、上述の表のように各トランザクションを決められた比率で発生させるため、全てのトランザクション種別が毎回出るわけではありません。
[Current] STOCK_LEVEL - Takes(s): 4.1, Count: 1, TPM: 14.7, Sum(ms): 7.4, Avg(ms): 7.6, 50th(ms): 7.9, 90th(ms): 7.9, 95th(ms): 7.9, 99th(ms): 7.9, 99.9th(ms): 7.9, Max(ms): 7.9 [Current] DELIVERY - Takes(s): 9.4, Count: 3, TPM: 19.1, Sum(ms): 2746.0, Avg(ms): 912.3, 50th(ms): 1342.2, 90th(ms): 1342.2, 95th(ms): 1342.2, 99th(ms): 1342.2, 99.9th(ms): 1342.2, Max(ms): 1342.2 [Current] NEW_ORDER - Takes(s): 8.0, Count: 5, TPM: 37.7, Sum(ms): 5232.9, Avg(ms): 1041.3, 50th(ms): 1342.2, 90th(ms): 1946.2, 95th(ms): 1946.2, 99th(ms): 1946.2, 99.9th(ms): 1946.2, Max(ms): 1946.2 [Current] ORDER_STATUS - Takes(s): 4.2, Count: 1, TPM: 14.4, Sum(ms): 34.7, Avg(ms): 34.6, 50th(ms): 35.7, 90th(ms): 35.7, 95th(ms): 35.7, 99th(ms): 35.7, 99.9th(ms): 35.7, Max(ms): 35.7 [Current] PAYMENT - Takes(s): 9.4, Count: 6, TPM: 38.3, Sum(ms): 2443.3, Avg(ms): 406.8, 50th(ms): 352.3, 90th(ms): 671.1, 95th(ms): 704.6, 99th(ms): 704.6, 99.9th(ms): 704.6, Max(ms): 704.6 [Current] STOCK_LEVEL - Takes(s): 4.2, Count: 1, TPM: 14.5, Sum(ms): 8.3, Avg(ms): 8.1, 50th(ms): 8.4, 90th(ms): 8.4, 95th(ms): 8.4, 99th(ms): 8.4, 99.9th(ms): 8.4, Max(ms): 8.4 [Current] NEW_ORDER - Takes(s): 9.6, Count: 10, TPM: 62.5, Sum(ms): 5425.7, Avg(ms): 544.1, 50th(ms): 637.5, 90th(ms): 1275.1, 95th(ms): 1342.2, 99th(ms): 1342.2, 99.9th(ms): 1342.2, Max(ms): 1342.2 [Current] PAYMENT - Takes(s): 8.9, Count: 6, TPM: 40.5, Sum(ms): 4408.0, Avg(ms): 729.8, 50th(ms): 671.1, 90th(ms): 671.1, 95th(ms): 1208.0, 99th(ms): 1208.0, 99.9th(ms): 1208.0, Max(ms): 1208.0 Finished [Summary] DELIVERY - Takes(s): 536.7, Count: 35, TPM: 3.9, Sum(ms): 38807.3, Avg(ms): 1103.2, 50th(ms): 1275.1, 90th(ms): 1946.2, 95th(ms): 2550.1, 99th(ms): 3087.0, 99.9th(ms): 3087.0, Max(ms): 3087.0 [Summary] NEW_ORDER - Takes(s): 599.1, Count: 340, TPM: 34.0, Sum(ms): 295684.8, Avg(ms): 869.6, 50th(ms): 671.1, 90th(ms): 1879.0, 95th(ms): 1879.0, 99th(ms): 2684.4, 99.9th(ms): 4295.0, Max(ms): 4295.0 [Summary] ORDER_STATUS - Takes(s): 586.6, Count: 34, TPM: 3.5, Sum(ms): 1567.1, Avg(ms): 46.9, 50th(ms): 5.2, 90th(ms): 29.4, 95th(ms): 35.7, 99th(ms): 1275.1, 99.9th(ms): 1275.1, Max(ms): 1275.1 [Summary] PAYMENT - Takes(s): 596.1, Count: 326, TPM: 32.8, Sum(ms): 263314.1, Avg(ms): 809.3, 50th(ms): 671.1, 90th(ms): 1811.9, 95th(ms): 1946.2, 99th(ms): 3087.0, 99.9th(ms): 3758.1, Max(ms): 3758.1 [Summary] STOCK_LEVEL - Takes(s): 594.1, Count: 26, TPM: 2.6, Sum(ms): 895.4, Avg(ms): 35.0, 50th(ms): 8.9, 90th(ms): 29.4, 95th(ms): 35.7, 99th(ms): 604.0, 99.9th(ms): 604.0, Max(ms): 604.0 tpmC: 34.0, tpmTotal: 76.9, efficiency: 26.5%
各行に表示される要素の意味は以下の通りです。
| 指標 | 意味 |
|---|---|
| Takes(s) | その区間で計測した経過時間 |
| Count | 完了したトランザクション数 |
| TPM | 1分あたりのトランザクション処理数 |
| Sum(ms) | 全トランザクションの合計レスポンスタイム |
| Avg(ms) | 平均レイテンシ |
| 50th/ |
それぞれのパーセンタイルでのレイテンシ |
| Max(ms) | 最大レイテンシ |
TPC-Cにおける主要な指標はtpmC
そのうえで、その他の指標もNEW_
まとめ
今回紹介したTPC-Cは、複雑なトランザクションが組み合わさった中での挙動など、より実際のワークロードに近い負荷を測定することができます。一方でsysbenchの一般的なシナリオは、CPUやディスクI/
このように性質の異なる2つのベンチマークを測定することで、問題がサーバのリソースにあるのか、それもDB内部にあるのかを切り分けることが可能になると思います。go-tpcはsysbenchと同じような操作感で実行できますので、ぜひ一度試してみてください。