2012年6月13日水曜日

Too many connectionsのエラーが出たからmax_connectionを増やす

アプリケーションのトラフィックが多くなってきたから、という。
よく聞く話ですが、多分あんまり効果ないです。

テストテーブルはこんな。

CREATE TABLE t1 (num serial,val char(32) not null);
numには1~1,000,000の整数値が、valにはMD5(num)の値が入ってます。

投げるクエリはこんな。
SELECT sql_no_cache * FROM t1 ORDER BY val LIMIT 1;
INDEXを全然使わない`重い'クエリ。転送量がネックになってほしくないのでLIMIT 1。
mysqlクライアントから直接叩いても2秒ちょいかかる。

これをPerlにしてapache越しに呼ぶ様にする。
MySQLのmax_connectionsを10に設定して、いざ測定。



ab -n 20 -c 10 http://localhost/cgi-bin/test.cgi &
ab -n 20 -c 10 http://localhost/cgi-bin/test.cgi &
abをバックグラウンドで2つ動かしてやって、10コネクション * 2回繰り返し * 2クライアントから、とする。

...

Time taken for tests:   33.176 seconds

Complete requests:      20
Failed requests:        1
...
Time taken for tests:   38.575 seconds
Complete requests:      20
Failed requests:        11



$ tail -f /var/log/httpd/error_log
...

[Tue Jun 12 23:15:38 2012] [error] [client ::1] DBI connect('d1','root',...) failed: Too many connections at /var/www/cgi-bin/test.cgi line 12
[Tue Jun 12 23:15:38 2012] [error] [client ::1] Can't call method "prepare" on an undefined value at /var/www/cgi-bin/test.cgi line 13.
...


都合12回Too many connectionsで失敗したのかな。
合計40のリクエストなんで、30%の失敗。



対比としてテーブルにINDEXをつけて`軽い'クエリに仕立て上げる。
ALTER TABLE t1 ADD INDEX (val);
mysqlクライアントから直接叩くと0.00秒で結果が返ってくる様になった。
これ以外は何も変えない。
apacheを再起動してから同じabを試す。

ab -n 20 -c 10 http://localhost/cgi-bin/test.cgi &
ab -n 20 -c 10 http://localhost/cgi-bin/test.cgi &
...
Time taken for tests:   8.606 seconds
Complete requests:      20
Failed requests:        0
...
Time taken for tests:   8.765 seconds
Complete requests:      20
Failed requests:        0
...

error_logにも何も出ない。
スクリプトもデータもパラメータもいじらず、ALTER TABLEだけで事情が解決することもあるってことで。


ちなみに、INDEX作る前の状態で、max_connections = 100にして測定しようとしたら、


ab -n 20 -c 10 http://localhost/cgi-bin/test.cgi &
ab -n 20 -c 10 http://localhost/cgi-bin/test.cgi &
...
Benchmarking localhost (be patient)...apr_poll: The timeout specified has expired (70007)
Benchmarking localhost (be patient)...apr_poll: The timeout specified has expired (70007)

abがタイムアウトして結果すら出なくなった。
タイムアウト値いくつか知らないけど、予想通り性能は劣化するよね。。

0 件のコメント :

コメントを投稿