Wadslog

[mysql][Apache] mod_log_sql関連のベンチマーク

Dec 2, 2008

前回設定した項目についてベンチマークをとりました。 今回のテストケースは

  1. 通常のaccess_log(ファイル)に保存
  2. BufferedLogsディレクティブをONにしたaccess_log
  3. mod_log_sql+MyISAMストレージエンジン
  4. mod_log_sql+Archiveストレージエンジン

の4つです。 それぞれ上記設定をしたwebサーバに、apacheのabコマンドを使ってテストしました。``` # /usr2/apache2/bin/ab -c 100 -n 10000 http://example.com/

1度に100ユーザ同時接続し、合計で10000回リクエストをかけています。 リクエストをかけると、以下のようなシンプルなレスポンスが帰ってきます。 これは静的ファイルで用意されています。

test


テストケース

リクエスト数/秒

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ストレージエンジンという組み合わせがよいですね。
comments powered by Disqus