MySQL道普請便り

第263回go-tpccを使ってMySQLの負荷テストをする

MySQLの負荷試験といえば、sysbenchがよく使われると思います。oltp_read_onlyやoltp_read_writeといったシナリオは準備が軽く、短時間でおおまかな性能傾向を掴むのに便利です。本連載でも、sysbenchを使った負荷試験の進め方や実行例を扱ってきました第26回第163回⁠。

一方で運用者目線でMySQLの構成や設定を変更するとき、単純化された合成OLTPだけでは見えにくい、より実際の業務に近い複数テーブルにまたがる更新処理の負荷を見たいと思う場面があるかと思います。

そこで今回は、go-tpcc(PingCAP社が公開しているベンチマークツール)を使ってTPC-Cベンチマークを実行する方法を紹介します。また、sysbenchの一般的なシナリオと比較したときの違いや結果の見方をまとめます。

TPC-Cとは

TPC-Cは、卸売業者の受注処理(Order-Entry)をモデルにしたOLTPベンチマークです。倉庫(Warehouse)を起点に、注文・入金・在庫といった現実でよくある更新/参照がシミュレートされています。

具体的には以下の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(TiDBのデフォルト)になっています。MySQLで実行する場合は--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拠点分のデータセット(warehouse+10地区+約3,000顧客×10地区+在庫約10万件など)が追加されます。

ここでは例として、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/90th/95th/99th/99.9th それぞれのパーセンタイルでのレイテンシ
Max(ms) 最大レイテンシ

TPC-Cにおける主要な指標はtpmC(Transactions per Minute C)です。これは実質的にNEW_ORDERトランザクションにおける1分間の処理数を指します。まずはこの数値を基準として比較すると良いでしょう。

そのうえで、その他の指標もNEW_ORDERトランザクションのメトリクスを中心に分析できます。TPC-Cではレイテンシの95th/99th パーセンタイルやエラーの有無をあわせて確認することが有用です。

まとめ

今回紹介したTPC-Cは、複雑なトランザクションが組み合わさった中での挙動など、より実際のワークロードに近い負荷を測定することができます。一方でsysbenchの一般的なシナリオは、CPUやディスクI/Oといったサーバーそのものの基本的な限界値を測るのに適しています。たとえばsysbenchの結果は良好なのに、go-tpcでは極端に性能が落ちるといった現象に遭遇した場合、それはハードウェアリソースの不足ではなく、InnoDBの内部的な競合や設定値がボトルネックになっている可能性があります。

このように性質の異なる2つのベンチマークを測定することで、問題がサーバのリソースにあるのか、それもDB内部にあるのかを切り分けることが可能になると思います。go-tpcはsysbenchと同じような操作感で実行できますので、ぜひ一度試してみてください。

おすすめ記事

記事・ニュース一覧