[mysql][Apache] mod_log_sql関連のベンチマーク
前回設定した項目についてベンチマークをとりました。
今回のテストケースは
- 通常のaccess_log(ファイル)に保存
- BufferedLogsディレクティブをONにしたaccess_log
- mod_log_sql+MyISAMストレージエンジン
- mod_log_sql+Archiveストレージエンジン
の4つです。
それぞれ上記設定をしたwebサーバに、apacheのabコマンドを使ってテストしました。
# /usr2/apache2/bin/ab -c 100 -n 10000 http://example.com/
1度に100ユーザ同時接続し、合計で10000回リクエストをかけています。
リクエストをかけると、以下のようなシンプルなレスポンスが帰ってきます。
これは静的ファイルで用意されています。
<html> <body> test </body> </html>
まずは1秒間あたりのリクエスト処理数です。
■1秒間あたりのリクエスト処理数
| テストケース | リクエスト数/秒 | 1に対する割合 |
| 1 | 7598.81 | 100% |
| 2 | 8670.88 | 114.1% |
| 3 | 4340.90 | 56.7% |
| 4 | 3119.29 | 41.0% |
mod_log_sqlを使うと、MyISAMを用いた場合はもともとの57%弱、Archiveに至っては40%程度しかパフォーマンスが出ていません。結構性能が落ちていますね。
INSERTパフォーマンスは、ArchiveだとMyISAMの1.5倍くらいあると聞いていたので、Archiveのほうがパフォーマンスがよくなると予測していたのですが、そのような結果にはなりませんでした。同時接続数とか条件で変わってくるのかもしれませんが、今回は検討しません。
続いて、ログファイルのサイズについて検討します。
dbに保存されたデータについては、
SHOW TABLE STATUS LILE 'access_log'\G *************************** 1. row *************************** Name: access_log Engine: ARCHIVE Version: 10 Row_format: Compressed Rows: 119070 Avg_row_length: 11072 Data_length: 2764858 Max_data_length: 1318343040 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2008-12-02 16:30:49 Update_time: 2008-12-02 16:30:49 Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec)
のData_lengthフィールドで確認します。Row_formatフィールドからArchiveではデータが圧縮されて保存されることもわかります。
10000回リクエストをかけた後のログのサイズは以下のとおりです。
■10000リクエスト後のログのサイズ
| テストケース | Kbyte | 1に対する割合 |
| 1 | 646 | 100% |
| 2 | 658 | 101.9% |
| 3 | 1100 | 170.3% |
| 4 | 256 | 39.6% |
なんと、Archiveではもともとのaccess_logの40%程度のサイズに圧縮されています。本領発揮というところでしょうか。
逆に、MyISAMでは70%もサイズが増えてしまいました。これはちょっと実運用では厳しい感じがします。
ただし、まだ試していませんが、myisampackというものでデータを圧縮することができます。
定期的にテーブルの圧縮をすることでログのサイズが抑えることができそうです(テーブルの変更が不可となりますが)。また、読み込みも早くなるということなので、時間があれば試してみたいです。
最後に、保存したログについてMyISAMとArchiveについてSELECTのパフォーマンスを調べました。
テスト条件は以下のとおりです。
データはこんな感じです。
mysql> desc access_log; +------------------+----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------+----------------------+------+-----+---------+-------+ | id | char(19) | YES | | NULL | | | agent | varchar(255) | YES | | NULL | | | bytes_sent | int(10) unsigned | YES | | NULL | | | child_pid | smallint(5) unsigned | YES | | NULL | | | cookie | varchar(255) | YES | | NULL | | | machine_id | varchar(25) | YES | | NULL | | | request_file | varchar(255) | YES | | NULL | | | referer | varchar(255) | YES | | NULL | | | remote_host | varchar(50) | YES | | NULL | | | remote_logname | varchar(50) | YES | | NULL | | | remote_user | varchar(50) | YES | | NULL | | | request_duration | smallint(5) unsigned | YES | | NULL | | | request_line | varchar(255) | YES | | NULL | | | request_method | varchar(10) | YES | | NULL | | | request_protocol | varchar(10) | YES | | NULL | | | request_time | char(28) | YES | | NULL | | | request_uri | varchar(255) | YES | | NULL | | | request_args | varchar(255) | YES | | NULL | | | server_port | smallint(5) unsigned | YES | | NULL | | | ssl_cipher | varchar(25) | YES | | NULL | | | ssl_keysize | smallint(5) unsigned | YES | | NULL | | | ssl_maxkeysize | smallint(5) unsigned | YES | | NULL | | | status | smallint(5) unsigned | YES | | NULL | | | time_stamp | int(10) unsigned | YES | | NULL | | | virtual_host | varchar(255) | YES | | NULL | | | bytes_in | int(10) unsigned | YES | | NULL | | | bytes_out | int(10) unsigned | YES | | NULL | | +------------------+----------------------+------+-----+---------+-------+ 27 rows in set (0.00 sec) mysql> select COUNT(*) access_log; +------------+ | access_log | +------------+ | 10060 | +------------+ 1 row in set (0.00 sec)
テーブルの読み込む条件は以下のとおりです。
mysql> select * from access_log; mysql> select count(*) from access_log where time_stamp >=1227852970 AND time_stamp < 1227853300;
結果は以下のようになりました
■DB読み込みのテスト(where条件なし)
| 秒 | MyISAMに対する割合 | |
| MyISAM | 0.72 | 100% |
| Archive | 4.12 | 580.3% |
■DB読み込みのテスト(where条件あり) ※ヒット件数は71472件
| 秒 | MyISAMに対する割合 | |
| MyISAM | 0.59 | 100% |
| Archive | 3.87 | 655.9% |
MyISAMのほうがぜんぜん早いですね。Archiveのほうはデータが圧縮されているので、その分読み込みに時間がかかっているのかもしれません。
読み込みに結構な差が出ていますが、これに関してはログを収集するサーバをマスタ-スレーブ構成にして、スレーブのほうでSELECTをかけるような処理を行えば対処できそうなきがします。
■まとめ
今回の結果では、結局テストケースとして用いたものについてはどれも一長一短で、それぞれの目的や用途に合わせる必要があるという事になりました。
無難に行くなら通常のaccess_logを用いて、どうしてもパフォーマンスをあげたい場合は、現在β版という位置づけではありますがBufferedLogsディレクティブをONにする方法が考えられます。
逆に、パフォーマンスはそれほど問題にならなくて、ログの管理のしやすさやサイズが重要な項目になるならば、迷わずmod_log_sql+Archiveストレージエンジンという組み合わせがよいですね。