さくらの専用サーバでベンチマークを実施してみた ~ 手順編 ~
目次
はじめに
こんにちは、株式会社スマートスタイルの中野です。
この記事は、以前投稿した『さくらの専用サーバでベンチマークを実施してみた ~ スコア編 ~』で実施したベンチマークの手順や注意点を紹介するものです。今後、MySQLのベンチマーク試験を実施しようと思っている方の参考になれば幸いです。
試験全体の流れ
前回の記事にも記載しましたが、今回のベンチマーク試験は以下のような流れで実施しています。
- Flashストレージのマウント、カーネル設定の変更(専用サーバのみ)
- DBサーバに MySQL5.7.18 と Percona XtraBackup2.4.8 をインストール
- 計測サーバに Sysbench 1.0 をインストール
- Sysbenchのデータロード実行
- XtraBackupで全体バックアップを取得
- ベンチマーク用のmy.cnfを設定
- Sysbenchのベンチマークを実行
- MySQLを停止し、XtraBackupの全体バックアップをリストア
- 6.に戻る
それでは、ステップ単位で切り取って詳細を見ていきましょう。
1. Flashストレージのマウント、カーネル設定の変更(専用サーバのみ)
※以下は専用サーバのみで実施した手順となります
最初に、用意して頂いたFlashストレージの設定(マウント)を行います。
今回の環境では、/data/にマウントしてその配下にMySQLのデータディレクトリを作成します。
# fdisk -c -u /dev/nvme0n1 Command (m for help): n ### "n" を入力 Command action ### "p" を入力、以下デフォルトで設定 e extended p primary partition (1-4) ... omitted ... Command (m for help): w The partition table has been altered! # yum install -y xfsprogs # mkfs.xfs -b size=4k /dev/nvme0n1p1 ### xfsでファイルシステムを作成 # mkdir /data/ # mount -o nobarrier,noatime,discard /dev/nvme0n1p1 /data ### マウントオプションは任意 # mount ... omitted ... /dev/nvme0n1p1 on /data type xfs (rw,noatime,nobarrier,discard) ### 正常にマウントされていることを確認
次にFlashストレージの性能を最大限引き出すため、一部のカーネル設定を変更します。
(1) CPUガバナーの変更
CPUの電力消費(クロック数)と発生熱量、ひいてはパフォーマンスを制御するLinux側のパラメータ。
# yum install -y cpufrequtils # cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor ### デフォルトは"ondemand" ondemand ondemand ... omitted ... # for i in `seq 0 39` \ do \ cpufreq-set -c $i -g performance \ done # cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor ### すべて"performance"に変更されたことを確認 performance performance ... omitted ...
(2) I/Oスケジューラの変更
アプリケーション(MySQL)から発行されたI/O命令を並び替える(スケジューリング)する時のルールを決める機能。
# cat /sys/block/sda/queue/scheduler ### デフォルトは"cfq" noop anticipatory deadline [cfq] # echo "noop" | tee /sys/block/sda/queue/scheduler ### "noop" もしくは "deadlineに変更" noop # cat /sys/block/sda/queue/scheduler [noop] anticipatory deadline cfq
2. DBサーバに MySQL5.7.18 と Percona XtraBackup2.4.8 をインストール
※ここからは専用サーバ、クラウドサーバ共通の手順となります。
ベンチマークの対象となるDBサーバに、MySQL5.7.18をインストールします。以下はCentOS6.9のDBサーバを想定した手順ですが、使用するディストリビューションやバージョンによって使用するリポジトリなどは変更してください。
# yum remove -y mysql-libs ### プリインストールされているMySQLを削除する # yum install http://dev.mysql.com/get/mysql57-community-release-el6-11.noarch.rpm ### 6系向けのMySQLリポジトリをインストール # yum install -y mysql-community-server mysql-community-libs-compat perl-DBD-MySQL ... omitted ... Installed: mysql-community-libs-compat.x86_64 0:5.7.18-1.el6 mysql-community-server.x86_64 0:5.7.18-1.el6 perl-DBD-MySQL.x86_64 0:4.013-3.el6 Dependency Installed: mysql-community-client.x86_64 0:5.7.18-1.el6 mysql-community-common.x86_64 0:5.7.18-1.el6 mysql-community-libs.x86_64 0:5.7.18-1.el6
次に、MySQLのバックアップを取得するためのツール Percona XtraBackup をインストールします。
# yum install -y epel-release ### epelのリポジトリ # yum install -y http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm ### Perconaのリポジトリ # yum install -y percona-xtrabackup-24 ... omitted ... Installed: percona-xtrabackup-24.x86_64 0:2.4.7-1.el6 Dependency Installed: libev.x86_64 0:4.03-3.el6
また、多くの同時接続数のベンチマークを実行する場合は、同時接続に耐えられるよう一部のカーネル設定を調整します(設定値は目安)。
# sysctl -w net.core.somaxconn=3000 # sysctl -w net.ipv4.tcp_max_syn_backlog=3000 # sysctl -p
次に、MySQLを起動します。専用サーバはデータディレクトリがデフォルト(/var/lib/mysql)と異なるため、初期化も必要です。
# mv /etc/my.cnf /etc/my.cnf.org # cp /tmp/flash_my.cnf /etc/my.cnf # mkdir -p /data/mysql/data /data/mysql/log # chown -R mysql:mysql /data/ # mysqld --defaults-file=/etc/my.cnf --initialize --user=mysql # service mysqld start
※ 使用するmy.cnfは以下の内容です。クラウドサーバでも datadir や ログのPATH 以外は同じものを使用しています。
なお、意図的にあえて低い設定値にしているパラメータ変数もあります
[mysqld] ### General ### datadir = /data/mysql/data/ server_id = 100 max_connections = 3000 back_log = 1200 max_allowed_packet = 4M performance_schema = ON skip_name_resolve query_cache_size = 0 query_cache_type = OFF max_prepared_stmt_count = 300000 ### Log ### log_bin = "/data/mysql/log/mysql-bin" # comment out when loading test data log_bin_index = "/data/mysql/log/mysql-bin-index" # comment out when loading test data sync_binlog = 1 binlog_format = STATEMENT max_binlog_size = 1G slow_query_log = ON long_query_time = 1 log_error = /data/mysql/log/mysqld.err log_timestamps = SYSTEM ### InnoDB ### innodb_io_capacity = 200 innodb_io_capacity_max = 2000 skip-innodb_doublewrite innodb_buffer_pool_size = 64G innodb_log_file_size = 512M # Small log files, more page flush innodb_log_files_in_group = 2 innodb_log_buffer_size = 8M innodb_flush_method = O_DIRECT innodb_flush_log_at_trx_commit = 1 innodb_file_per_table = 1 transaction_isolation = REPEATABLE-READ innodb_thread_concurrency = 0 innodb_write_io_threads = 10 innodb_lru_scan_depth = 5000 innodb_flush_neighbors = 0 innodb_read_ahead_threshold = 0 innodb_purge_threads = 4 innodb_page_cleaners = 4 innodb_adaptive_hash_index = 0 innodb_numa_interleave = ON innodb_buffer_pool_dump_at_shutdown = 0 innodb_buffer_pool_load_at_startup = 0 skip-innodb_doublewrite ### For unifying as Aurora setting ### core_file gtid_mode = OFF enforce_gtid_consistency = OFF eq_range_index_dive_limit = 10 explicit_defaults_for_timestamp = ON host_cache_size = 128 binlog_checksum = CRC32 innodb_buffer_pool_instances = 8 innodb_change_buffering = none innodb_checksum_algorithm = none innodb_checksums = OFF innodb_file_format = Antelope innodb_file_format_max = Antelope innodb_large_prefix = OFF innodb_open_files = 6000 innodb_purge_batch_size = 900 innodb_purge_threads = 3 innodb_read_io_threads = 16 innodb_strict_mode = OFF innodb_use_native_aio = OFF key_buffer_size = 16M log_output = TABLE log_warnings = 1 open_files_limit = 65535 read_buffer_size = 256K read_rnd_buffer_size = 512K relay_log_recovery = ON relay_log_space_limit = 1000000000 slave_net_timeout = 3600 sql_mode = "" table_definition_cache = 20000 table_open_cache = 6000 thread_cache_size = 58
MySQLが問題なくインストールで来たら、sysbench用のデータベース、ユーザを作成しておきます。
# cat /data/mysql/log/mysqld.err | grep temporary 2017-05-29T19:26:39.654417+09:00 1 [Note] A temporary password is generated for root@localhost: aIY0(gLPiKkJ # mysql -u root -paIY0(gLPiKkJ -S /data/mysql/data//mysql.sock mysql> SET PASSWORD = "Password"; mysql> CREATE DATABASE sbtest; mysql> GRANT ALL ON *.* TO sbuser@`%` IDENTIFIED BY "sbpass"; mysql> exit
3. 計測サーバに Sysbench 1.0 をインストール
今回の検証では、DBサーバの他に計測サーバを用意してそこからsysbenchを実行しています。そのため、sysbench1.0は計測サーバにインストールします。なお、計測サーバでは Ubuntu16.04 を使用していますが、CentOSでも問題はありません。
# wget https://repo.percona.com/apt/percona-release_0.1-4.$(lsb_release -sc)_all.deb ### Perconaのリポジトリ # dpkg -i percona-release_0.1-4.$(lsb_release -sc)_all.deb # apt-get update # apt-get install -y sysbench ### sysbench1.0系の最新版がインストールされる ... omitted ...
また、sysbenchが使用するMySQLクライアントと、ベンチマークの実行時に便利なscreenも併せてインストールします。
以降の作業は、screen(仮想コンソール)上で実施します。
# apt-get install -y mysql-client screen # screen ### 仮想コンソールで作業すれば、不慮の接続断があっても処理が継続できる
4. Sysbenchのデータロード実行
sysbenchのデータロードを実行します。専用サーバで実行した場合は、およそ300分(=5時間)ほどかかりました。
# sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql \ --table-size=25000000 --tables=60 --mysql-host=192.168.20.20 \ --mysql-user=sbuser --mysql-password=sbpass prepare ... omitted ...
5. XtraBackupで全体バックアップを取得
データロード直後の状態の全体バックアップを取得します。こちらも専用サーバで実行した場合は、およそ40分ほどかかりました。
# mkdir -p /data/backup_0606 # time innobackupex --user=root --password=Password \ /data/backup_0606 --no-timestamp ... omitted ... # innobackupex --apply-log /data/backup_0606 ... omitted ...
また、このバックアップをそのままクラウドサーバに転送することで「同じデータ」を用いたベンチマークが可能となります。
テストを自動実行するスクリプトを作成
ここまでの作業でベンチマークの準備はできましたので、これ以降はひたすらsysbenchの実行を繰り返していきます。そのため、以下の手順については自動実行するスクリプトを作成し、計測サーバ上に配置します。
6. ベンチマーク用のmy.cnfを設定
7. Sysbenchのベンチマークを実行
8. MySQLを停止し、XtraBackupの全体バックアップをリストア
9. 6.に戻る
スクリプトの注意点としては、DBサーバで実行する必要があるコマンド(XtraBackupのリストアなど)は、ssh経由でDBサーバ上のユーザとして実行しています。その際、パスワード認証をスルーするため sshpass を利用していますが、こちらはパスワード認証無しのSSH鍵認証などでも問題はありません。
【スクリプトの実行方法】
以下3つの引数を指定して、スクリプトファイルを実行して下さい。その際、標準出力+エラー出力を別途ログにリダイレクトすると何か問題が発生した時の調査がしやすくなります。この引数で指定した内容に合わせた名称で、sysbench の実行結果が/bench_result/ の下に出力されます。
・$1 : 使用するmy.cnfファイルの名前(例:/tmp/default_my.cnf であれば "default"を指定)
・$2 : sysbenchの同時接続数を指定する(今回は 8/16/32/64/128/512 の6パターン実行する)
・$3 : 何回目のテストかを指定する(同じテストを2回ずつ実行する場合は 1 or 2 となる)
# mkdir /bench_result/ # ./auto_sysbench.sh edit 64 2 ### 編集済みのmy.cnfを使い、64接続のsysbenchの、2回目実行
【スクリプトの内容】
#!/bin/bash -eu cnf=$1 thread=$2 count=$3 echo -e "Start shell script !\n" date echo -e "Start restore backup.\n" sshpass -p 'rootpass' ssh root@ rm -rf /data/mysql/data/* sshpass -p 'rootpass' ssh root@ time innobackupex --copy-back /data/backup_0606/ sshpass -p 'rootpass' ssh root@ chown -R mysql:mysql /data/mysql/data/ sshpass -p 'rootpass' ssh root@ cp -f /tmp/${cnf}_my.cnf /etc/my.cnf sshpass -p 'rootpass' ssh root@ service mysqld start sleep 10m echo -e "Finish restore backup !\n" echo -e "Start sysbench.\n" function main() { trap catch ERR sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --table-size=25000000 --tables=60 --mysql-host= --threads=${thread} --time=1800 --report-interval=30 --mysql-user=sbuser --mysql-password=sbpass run 2>&1 >> /bench_result/result_${cnf}_${thread}_${count}_`date "+%m%d_%H%M"`.log return 0 } function catch() { echo -e "sysbench Failed...\n" } function finally() { echo -e "Finish sysbench !\n" } # Entry Point set -eu trap catch ERR trap finally EXIT main sshpass -p 'rootpass' ssh root@ service mysqld stop echo -e "Finish shell script !\n" date
【スクリプトの内容】
スクリプトでは以下のような処理を行っています。なお、実行時DBサーバのMySQLは停止している必要があります。
(1) DBサーバのデータディレクトリを全て削除
(2) XtraBackupでデータロード時のバックアップをリストア
(3) リストア後のデータディレクトリのパーミッション変更(リストア後は root:root になっています)
(4) 使用する my.cnf を配置
(5) MySQLを起動
(6) sysbenchを実行
(7) MySQLを停止
あとは、必要なシナリオに合わせてスクリプトの実行を繰り返せばベンチマークは終了となります。
最後に
弊社スマートスタイルでも、MySQLに関連する技術情報を発信するためのブログを運営しています。もし興味があれば是非アクセスしてみてください。