次のコマンドでab
とsiege
を使用してApache/2.2.3(プリフォーク)のベンチマークを行っています。
ab -kc 200 -t 120 http://www.mywebsite.com/test.php
siege -c200 -t2M http://www.mywebsite.com/test.php
test.phpは、1つのmysql接続を作成してから閉じる非常に単純なファイルです。
<?php
$link = mysql_connect("localhost", "username", "password");
mysql_select_db("dbname");
if(!$link) {
die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);
?>
私が得た結果には多くの失敗したリクエストが含まれています。 失敗したリクエストの数を減らす方法を見つけようとしていますこれはかなり単純なスクリプトであるため、サーバーの負荷は非常に低く、クアッドでは問題はないはずです- 8GのRAMを搭載したコアXeon3Ghzマシン。
siegeからの出力
Transactions: 9438 hits
Availability: 98.33 %
Elapsed time: 119.39 secs
Data transferred: 0.38 MB
Response time: 1.31 secs
Transaction rate: 79.05 trans/sec
Throughput: 0.00 MB/sec
Concurrency: 103.37
Successful transactions 9438
Failed transactions: 160
Longest transaction: 21.24
Shortest transaction 0.21
abからの出力:
Benchmarking www.mywebsite.com (be patient)
Server Software: Apache/2.2.3
Server Hostname: www.mywebsite.com
Server Port: 80
Document Path: /test.php
Document Length: 22 bytes
Concurrency Level: 200
Time taken for tests: 35.851520 seconds
Complete requests: 50000
Failed requests: 618
(Connect: 0, Length: 618, Exceptions: 0)
Write errors: 0
Keep-Alive requests: 49600
Total transferred: 12932098 bytes
HTML transferred: 1149345 bytes
Requests per second: 1394.64 [#/sec] (mean)
Time per request: 143.406 [ms] (mean)
Time per request: 0.717 [ms] (mean, across all concurrent requests)
Transfer rate: 352.26 [Kbytes/sec] received
私のApache構成の簡単なハイライト
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
<IfModule prefork.c>
StartServers 20
MinSpareServers 20
MaxSpareServers 50
ServerLimit 500
#default 200
MaxClients 500
MaxRequestsPerChild 4000
</IfModule>
別の弱いサーバーで同じスクリプトを使用して同じテストを実行しましたが、失敗したリクエストはゼロで、テストはより速く終了しました。だから、これは何が悪いのだろうか。
更新されたMySQL構成:
変数
mysql> show variables LIKE '%connect%';
+--------------------------+-------------------+
| Variable_name | Value |
+--------------------------+-------------------+
| character_set_connection | latin1 |
| collation_connection | latin1_swedish_ci |
| connect_timeout | 10 |
| init_connect | |
| max_connect_errors | 10 |
| max_connections | 100 |
| max_user_connections | 0 |
+--------------------------+-------------------+
グローバルステータス
mysql> SHOW GLOBAL STATUS LIKE '%connect%';
+--------------------------+---------+
| Variable_name | Value |
+--------------------------+---------+
| Aborted_connects | 343 |
| Connections | 1463797 |
| Max_used_connections | 101 |
| Ssl_client_connects | 0 |
| Ssl_connect_renegotiates | 0 |
| Ssl_finished_connects | 0 |
| Threads_connected | 3 |
+--------------------------+---------+
同時実行の制限は間違いなくMySQL側にありますが、これが実際のパフォーマンスにとって必ずしも悪いことであるかどうかはわかりません。 MySQLは100の同時接続を受け入れることができるため、一度に通信できるApacheインスタンスは最大で100になります。テストスクリプトは非常に単純なので、アクティブに接続されているか、少なくともMySQLに接続している時間の大部分を費やします。他の状態にあるApacheプロセスにもう少し追加すると、100の包囲で同時実行が得られます。abが200のより高い同時実行レベルを取得する理由は正確にはわかりませんが、カウントが異なる可能性があります。
ベンチマーク数を高くしたい場合は、MySQLの接続制限を高く設定してください。 MySQLの接続制限は、DBとの通信に大部分の時間を費やすものの場合、少なくともApacheプロセスの数と同じである必要があります。
残念ながら、abを使用すると、クライアントのパフォーマンスを実際にベンチマークできます。クライアントホストを強制終了しないhttperfのようなより優れたパフォーマンスツールが必要です。実際のテストを実行したい場合は、複数のホストを使用するか、場合によっては包囲することもできます。 abが実際に何をしているのかを確認するだけで、開いているファイルの制限に苦労する可能性があります。サーバーの構成を確認することもお勧めします。
おそらく、MySQLの側で何か奇妙なことが起こっています。この種の迅速な「db接続の作成-閉じる」テスト中に簡単に発生する可能性があることの1つは、mysql_max_connection_errorsがいっぱいになり、デフォルトでは10個しかないことです。
そして別のこと:最大接続制限が弱い(しかし機能している)サーバーとこの速い(そして機能していない)サーバーの間で等しいことをすでに確認しましたか?たぶん、100の同時MySQL接続のデフォルト値がいっぱいになります。