Я тестирую Apache / 2.2.3 (prefork), используя ab
и siege
с помощью следующей команды:
ab -kc 200 -t 120 http://www.mywebsite.com/test.php
siege -c200 -t2M http://www.mywebsite.com/test.php
test.php - это очень простой файл, который просто создает одно соединение 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);
?>
Результаты, которые я получаю много неудачных запросов в них. Я пытаюсь понять, как уменьшить количество неудачных запросов поскольку это довольно простой сценарий, загрузка сервера довольно низкая, у меня не должно возникнуть проблем с машиной Quad-Core Xeon 3Ghz с 8 ГБ оперативной памяти.
Выход из осада
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 одновременных подключений, так что максимум 100 экземпляров Apache могут разговаривать с ним одновременно. Поскольку ваш тестовый сценарий настолько прост, он будет проводить большую часть времени в активном состоянии, подключаясь к MySQL или, по крайней мере, подключаясь к нему. Добавьте немного больше для процессов Apache, которые находятся в других состояниях, и вы получите 100% параллелизма. Я не совсем уверен, почему ab получает более высокий уровень параллелизма 200, но, возможно, он считает вещи по-другому.
Если вы хотите получить более высокие контрольные цифры, просто установите более высокие ограничения на количество подключений для MySQL. Ограничение MySQL conn, вероятно, должно быть, по крайней мере, равно количеству процессов Apache для чего-то, что большую часть времени тратит на общение с БД.
Возможно, со стороны MySQL происходит что-то странное. Одна вещь, которая может легко произойти во время такого быстрого теста «создать соединение с базой данных - закрыть его», - это то, что mysql_max_connection_errors заполняется, по умолчанию только 10.
И еще: вы уже проверили, что максимальные ограничения на подключение равны между вашим более слабым (но работающим) и более быстрым (и не работающим) сервером? Может быть, значение по умолчанию 100 одновременных подключений MySQL заполнится.
К сожалению, с ab вы действительно тестируете производительность своего клиента. Вам нужен инструмент с более высокой производительностью, например httperf, который не убивает клиентский хост. Если вы хотите провести реальное тестирование, вам следует использовать для этого более 1 хоста или, в некоторых случаях, осада также является хорошим инструментом. Просто проверьте, что на самом деле делает ab, он может бороться с ограничениями открытых файлов. Также полезно проверить конфигурацию сервера.