CLOVER🍀

That was when it all began.

データベースやCPU、ファイルシステムなどへのベンチマークツール、sysbenchをMySQLで試す

これは、なにをしたくて書いたもの?

  • MySQLに、単純でもいいので簡単に負荷をかけられるツールを探していた
  • sysbenchというものがあるらしい

というわけで、sysbenchを使ってMySQLに負荷…というかベンチマークを取ってみる、ということで。

sysbenchとは?

こちらのツールです。

GitHub - akopytov/sysbench: Scriptable database and system performance benchmark

Luaを使った、ベンチマークツールです。データベースへの負荷をかけるのに、よく使われるようです。

以下のようなベンチマークを実行することができます。

今回は、oltp_*.luaを使用して、MySQLにOLTP系の負荷をかけます。

データベースは、MySQLとPostgreSQLが使えるようです。

環境

今回の環境は、Ubuntu Linux 18.04 LTSです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.1 LTS
Release:    18.04
Codename:   bionic

また、MySQLは8.0.13を使用します。

インスートール

インストール方法は、こちら。

Installing from Binary Packages / Linux

実行。

$ curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash
$ sudo apt install sysbench

インストールできたら、まずはヘルプを参照。

$ sysbench --help
Usage:
  sysbench [options]... [testname] [command]

Commands implemented by most tests: prepare run cleanup help

...

Compiled-in tests:
  fileio - File I/O test
  cpu - CPU performance test
  memory - Memory functions speed test
  threads - Threads subsystem performance test
  mutex - Mutex performance test

See 'sysbench <testname> help' for a list of options for each test.

いろいろとオプションが表示されます。ここで表示されるヘルプは、テストの種類を跨いだグローバルに使えるもの、
ログのオプション、データベースのテストに使えるものなどが、カテゴリ別に表示されます。

テストの指定は、「fileio」、「cpu」、「memory」、「threads」、「mutex」、そして「/usr/share/sysbench」ディレクトリ配下に
インストールされたLuaスクリプトから指定することができます。

各テストに対して、「help」を指定することで、テストごとのヘルプを表示することができます。

$ sysbench cpu help
sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2)

cpu options:
  --cpu-max-prime=N upper limit for primes generator [10000]

「oltp_read_write」の場合。

$ sysbench oltp_read_write help
sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2)

oltp_read_write options:
  --auto_inc[=on|off]           Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on]
  --create_secondary[=on|off]   Create a secondary index in addition to the PRIMARY KEY [on]
  --delete_inserts=N            Number of DELETE/INSERT combinations per transaction [1]
  --distinct_ranges=N           Number of SELECT DISTINCT queries per transaction [1]
  --index_updates=N             Number of UPDATE index queries per transaction [1]
  --mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb]
  --non_index_updates=N         Number of UPDATE non-index queries per transaction [1]
  --order_ranges=N              Number of SELECT ORDER BY queries per transaction [1]
  --pgsql_variant=STRING        Use this PostgreSQL variant when running with the PostgreSQL driver. The only currently supported variant is 'redshift'. When enabled, create_secondary is automatically disabled, and delete_inserts is set to 0
  --point_selects=N             Number of point SELECT queries per transaction [10]
  --range_selects[=on|off]      Enable/disable all range SELECT queries [on]
  --range_size=N                Range size for range SELECT queries [100]
  --secondary[=on|off]          Use a secondary index in place of the PRIMARY KEY [off]
  --simple_ranges=N             Number of simple range SELECT queries per transaction [1]
  --skip_trx[=on|off]           Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]
  --sum_ranges=N                Number of SELECT SUM() queries per transaction [1]
  --table_size=N                Number of rows per table [10000]
  --tables=N                    Number of tables [1]

ここで、「oltp_read_write」はどこから出てきたのか?ですが、Ubuntu Linuxの場合「/usr/share/sysbench」ディレクトリ配下にある
Luaスクリプトから、「.lua」拡張子を除いたものを指定することになります。

$ find /usr/share/sysbench -maxdepth 1 -type f
/usr/share/sysbench/oltp_write_only.lua
/usr/share/sysbench/select_random_ranges.lua
/usr/share/sysbench/oltp_update_index.lua
/usr/share/sysbench/oltp_read_only.lua
/usr/share/sysbench/oltp_common.lua
/usr/share/sysbench/oltp_read_write.lua
/usr/share/sysbench/oltp_delete.lua
/usr/share/sysbench/select_random_points.lua
/usr/share/sysbench/oltp_update_non_index.lua
/usr/share/sysbench/bulk_insert.lua
/usr/share/sysbench/oltp_insert.lua
/usr/share/sysbench/oltp_point_select.lua

なお、テストの種類を指定するところに、ファイルパスを直接指定してもOKです。

MySQLに負荷をかけてみる

では、sysbenchを使ってMySQLに負荷をかけてみましょう。

MySQLサーバーを用意し、データベースを「sbtest」、ユーザーとパスワードを「myuser / password」とします。

今回は、テストシナリオのうち「oltp_read_write」を使用することにします。

各テストの内容は、Luaスクリプトのコメントなどを見た方がよいのかもしれません。

https://github.com/akopytov/sysbench/tree/1.0.15/src/lua

例えば…

https://github.com/akopytov/sysbench/blob/1.0.15/src/lua/oltp_read_write.lua

-- ----------------------------------------------------------------------
-- Read/Write OLTP benchmark
-- ----------------------------------------------------------------------

まず最初に、「prepare」でテーブルを作成します。データを100万行として実行。

$ sysbench oltp_read_write \
  --db-driver=mysql --table-size=1000000 \
  --mysql-host=172.17.0.3 \
  --mysql-db=sbtest \
  --mysql-user=myuser \
  --mysql-password=password \
  prepare
sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2)

Creating table 'sbtest1'...
Inserting 1000000 records into 'sbtest1'
Creating a secondary index on 'sbtest1'...

「sbtest1」というテーブル、インデックスができたらしいです。

続いて、「run」でテストを実行します。8スレッドで、120秒間、負荷をかけつづけます。

$ sysbench oltp_read_write \
  --threads=8 \
  --time=120 \
  --db-driver=mysql \
  --table-size=1000000 \
  --mysql-host=172.17.0.3 \
  --mysql-db=sbtest \
  --mysql-user=myuser \
  --mysql-password=password \
  run
sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2)

Running the test with following options:
Number of threads: 8
Initializing random number generator from current time


Initializing worker threads...

Threads started!

このあたりのテスト実行に関するスレッド数などを見るには、

General Command Line Options

を見るか、ヘルプをじっくり眺めましょう。

手元の環境では、このような結果になりました。

SQL statistics:
    queries performed:
        read:                            266462
        write:                           76132
        other:                           38066
        total:                           380660
    transactions:                        19033  (158.54 per sec.)
    queries:                             380660 (3170.86 per sec.)
    ignored errors:                      0      (0.00 per sec.)
    reconnects:                          0      (0.00 per sec.)

General statistics:
    total time:                          120.0471s
    total number of events:              19033

Latency (ms):
         min:                                   19.74
         avg:                                   50.44
         max:                                  513.93
         95th percentile:                      110.66
         sum:                               960040.61

Threads fairness:
    events (avg/stddev):           2379.1250/3.14
    execution time (avg/stddev):   120.0051/0.01

120秒で、19,033トランザクション(秒間158トランザクション)が実行できたようです。read/writeの内訳も出ていますね。
※MySQLには、チューニングなどはなにもしていません

どんなSQLが使われているかは、このあたりを見ればよさそうな感じです。

https://github.com/akopytov/sysbench/blob/1.0.15/src/lua/oltp_common.lua

テストで使ったテーブルを削除する場合は、「cleanup」を指定します。

$ sysbench oltp_read_write \
  --db-driver=mysql \
  --mysql-host=172.17.0.3 \
  --mysql-db=sbtest \
  --mysql-user=myuser \
  --mysql-password=password \
  cleanup
sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2)

Dropping table 'sbtest1'...

これで、後片付け完了です。

簡単にですが、使い方はなんとなくわかった気がします。