MySQL道普請便り

第23回mysqlslapを使って負荷テストをしてみよう

テスト環境で動かしていた時には問題なかったアプリケーションであっても、いざ本番にリリースしてみたら性能が出ていなかったり、高負荷でレスポンスを返せなくなってしまうことがあります。サーバの性能を確認していなかったためリリース後に思わぬしっぺ返しを受けることが無いように、事前にやっておきたいのが負荷テストです。

今回は、MySQLにバンドルされているmysqlslapを使って負荷テストを行う方法を紹介していきたいと思います。

実行環境

今回は、CentOS7上でyumを使い、MySQLバージョン5.7.13をインストールして実行しています。以下のコマンドを実行してmysqlをインストールしました。

$ sudo yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
$ sudo yum install mysql-community-server -y

mysqlslapとは?

mysqlslapとは、MySQLが公式でサポートしている 負荷エミュレーションクライアントです。公式のドキュメントはこちらにあります。

mysqlslapを使うメリットとしては以下の2点があげられます。

まず1点目はインストールが簡単であることです。mysqlコマンドクライアントをインストールした時に同時にインストールされるため、MySQLへ接続できる環境を用意したらすぐにテストをすることができます。

2点目はオプションが豊富に揃っていることです。並列実行数やSQLの自動生成など、多種多様なオプションが存在していて、簡単にテストを始めることができます。

次に実際に動かしてみて、どのような結果が得られるかを紹介していきたいと思います。

実行方法

以下に表示したコマンドを実行します。ユーザやパスワード、ポートやホストの指定といった設定は、mysqlコマンドクライアントと同じものが使えます。そのため、アプリケーションサーバからMySQLサーバへの負荷ベンチを取りたい場合にも使うことができます。

$ mysqlslap -uroot -ppassword -P 3306 -h localhost --auto-generate-sql --iterations=1 --concurrency=1

ここで使用しているオプションを以下の表にまとめました。

オプション説明
-u, --userMySQLサーバに接続するuser名
-p, --passwordMySQLサーバに接続する際のパスワード
-P, --portMySQLサーバに接続するポート番号
-h, --host指定したhost上のMySQLに接続する
--auto-generate-sqlSQLの自動生成を行う
--iterations実行するテストの回数
--concurrencySELECT ステートメントを発行する際、シミュレートするクライアントの数

ここでは以上のようなオプションを利用しています。実行した結果は次のようになります。

Benchmark
        Average number of seconds to run all queries: 0.001 seconds
        Minimum number of seconds to run all queries: 0.001 seconds
        Maximum number of seconds to run all queries: 0.002 seconds
        Number of clients running queries: 1
        Average number of queries per client: 0

平均実行時間や最小・最大の実行時間、実行したクライアント、クライアントが発行したSQLの数などが一目でわかるようになっています。

注意点としては、mysqlslapというデータベースを作成して、ベンチマーク終了後に削除するため、事前にmysqlslapというデータベースがある場合は削除されてしまいます。ご注意ください。

続いてmysqlslapのベンチマークを行う際に、便利なオプションのいくつかを簡単に説明します。

--only-printオプション

このオプションを付けて実行すると、データベースへの接続は行わず、負荷テストで実行されるSQLが表示されます。自動生成されたSQLを元に負荷テストを行う場合に、実際にどのようなSQLが実行されるのかを確認することができます。

$ mysqlslap -uroot --only-print  --auto-generate-sql  --auto-generate-sql --iterations=1 --concurrency=1
DROP SCHEMA IF EXISTS `mysqlslap`;
CREATE SCHEMA `mysqlslap`;
use mysqlslap;
CREATE TABLE `t1` (intcol1 INT(32) ,charcol1 VARCHAR(128));
INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');

--略--

SELECT intcol1,charcol1 FROM t1;
INSERT INTO t1 VALUES (364531492,'qMa5SuKo4M5OM7ldvisSc6WK9rsG9E8sSixocHdgfa5uiiNTGFxkDJ4EAwWC2e4NL1BpAgWiFRcp1zIH6F1BayPdmwphatwnmzdwgzWnQ6SRxmcvtd6JRYwEKdvuWr');
DROP SCHEMA IF EXISTS `mysqlslap`;

出力されたSQLを確認すると、はじめにmysqlslapがあったらdropして、mysqlslapを作り直して絵t1テーブルを作り、値を入れていることがわかります。そしてSELECTやinsert等を行い、テストが終わった後にmysqlslapデータベースを削除していることがわかります。

--auto-generate-sql-guid-primaryオプション

このオプションは、自動生成されたSQLのテーブルに対して主キーを設定するオプションになります。実行するコマンドは以下のようになります。

$ mysqlslap -uroot --only-print --auto-generate-sql --auto-generate-sql-guid-primary

このコマンドを実行すると、CREATE文中にprimary keyが設定されているのがわかります。idにはuuid()関数が使用されていることもわかります。

$ mysqlslap -uroot --only-print  --auto-generate-sql --auto-generate-sql-guid-primary

--略--

CREATE TABLE `t1` (id varchar(32) primary key,intcol1 INT(32) ,charcol1 VARCHAR(128));
INSERT INTO t1 VALUES (uuid(),100669,'qnMdipW5KkXdTjGCh2PNzLoeR0527frpQDQ8uw67Ydk1K06uuNHtkxYBxT5w8plb2BbpzhwYBgPNYX9RmICWGkZD6fAESvhMzH3yqzMtXoH4BQNylbK1CmEIPGYlC6');

--略--

--auto-generate-sql-load-typeオプション

このオプションはSQLを自動生成した時にテストとして生成されるSQLの種類を指定できます。デフォルトではmixedとなっています。オプションの種類と指定できるものは次の表の通りです。

オプション生成されるSQL
mixed挿入とテーブルスキャンするSELECTが半分ずつ実行
readテーブルスキャンをするSELECTを実行
writeテーブルに挿入
key主キーを使ったSELECTの実行
updateupdate文の実行

また、keyオプションを使用する際には主キーが必要となるので、前述の--auto-generate-sql-guid-primaryというオプションを付けて実行しましょう。

--create, --queryオプション

この2つのオプションを使用すると、自分で用意したテーブルとクエリで負荷テストを行うことができます。

使い方は以下のようになります。複数行指定を行っている関係で--delimiterオプションも使用しています。これは使用するsqlの区切り文字を指定するもので、今回はSQLを;で区切るために使用しています。

$ mysqlslap -uroot --delimiter=";" --create="CREATE TABLE t1 (a int);INSERT INTO t1 VALUES (23)"  --query="SELECT * FROM t1"

--only-printオプションを付けて何が行われるかを確認してみます。

$ mysqlslap -uroot --only-print --delimiter=";" --create="CREATE TABLE t1 (a int);INSERT INTO t1 VALUES (23)"  --query="SELECT * FROM t1"
DROP SCHEMA IF EXISTS `mysqlslap`;
CREATE SCHEMA `mysqlslap`;
use mysqlslap;
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (23);
SELECT * FROM t1;
DROP SCHEMA IF EXISTS `mysqlslap`;

以上のように、指定されたSQLが発行されていることがわかります。

--engineオプション

MySQLにはInnoDBの他にもMyISAMなどのさまざまなストレージエンジンがあります。このオプションに何も指定がなかった場合は、データベースのデフォルトのストレージエンジンが指定されます。データベースのデフォルト設定が違ったとしても、同じストレージエンジンで実行したい場合などには付けるようにしましょう。使い方は、以下のようにengineオプションに使いたいストレージエンジンを指定します。

$ mysqlslap -uroot  --auto-generate-sql  --engine=InnoDB
Benchmark
        Running for engine InnoDB

--略--

ストレージエンジンを指定することで、ベンチマークの結果中に指定したストレージエンジンが表示されるようになります。

以下はMyISAMを指定した時の例になります。

$ mysqlslap -uroot  --auto-generate-sql  --engine=MyISAM
Benchmark
        Running for engine MyISAM

--略--

結果だけを見た時に、どのストレージエンジンを使っているのかわかりやすいので、ベンチマークを他の人に見せる場合や、記録として残しておく場合はなるべく入れたほうが良いでしょう。

まとめ

今回は、mysqlslapを使って負荷テストを行う方法を紹介しました。mysqlslapには難しいインストール方法や設定があまりないので、気軽に負荷テストを行うことができると思います。皆さんも一度試してみてはいかがでしょうか。

おすすめ記事

記事・ニュース一覧