Назад | Перейти на главную страницу

Длительное время подключения PHP к MySQL на EC2

У меня периодически возникают проблемы с подключением к ведомому устройству базы данных с помощью InnoDB. Время от времени у меня соединение занимает более 2 секунд. Эти серверы размещены на Amazon EC2.

Сервер приложений - PHP 5.2 / Apache, работающий на Ubuntu. Подчиненное устройство БД работает под управлением Percona XtraDB 5.1 на Ubuntu 9.10. Для хранения данных используется массив EBS Raid.

Мы уже используем разрешение пропуска имени и привязку к адресу 0.0.0.0.

Это заглушка кода PHP, которая не работает.

        $tmp = mysqli_init();
        $start_time = microtime(true);
        $tmp->options(MYSQLI_OPT_CONNECT_TIMEOUT, 2);
        $tmp->real_connect($DB_SERVERS[$server]['server'], 
                   $DB_SERVERS[$server]['username'], 
                   $DB_SERVERS[$server]['password'], 
                   $DB_SERVERS[$server]['schema'], 
                   $DB_SERVERS[$server]['port']);
        if(mysqli_connect_errno()){
            $timer = microtime(true) - $start_time;
            mail($errors_to,'DB connection error',$timer);
        }

На сервере БД доступно более 300 МБ для новых подключений, а размер сервера далек от максимально допустимого (60 из 1200). Загрузка на обоих серверах <2 на 4 основных экземплярах m1.xlarge.

Некоторые особенности конфигурации mysql

max_connections = 1200

thread_stack = 512K
thread_cache_size = 1024
thread_concurrency = 16

innodb-file-per-table
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 13G

Любая помощь в отслеживании источника замедления приветствуется.

[РЕДАКТИРОВАТЬ] Я обновляю значения sysctl для сети, но, похоже, они не решают проблему. Я внес следующие изменения как в базу данных, так и на сервер приложений.

net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_sack = 0
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_fin_timeout = 20
net.ipv4.tcp_keepalive_time = 180
net.ipv4.tcp_max_syn_backlog = 1280
net.ipv4.tcp_synack_retries = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 87380 16777216

[РЕДАКТИРОВАТЬ] По предложению jaimieb, я добавил трассировку и записал следующие данные, используя время. Этот сервер обрабатывает около 51 запроса в секунду в это время суток. Ошибка подключения возникла один раз (в 13:06:36) в течение 3-минутного окна, описанного ниже. Поскольку произошел 1 сбой и около 9 200 успешных подключений, я думаю, что это не даст ничего значимого с точки зрения отчетности.

Сценарий:

date >> /root/database_server.txt
(time mysql -h database_Server -D schema_name -u appuser -p apppassword -e '') > /dev/null 2>> /root/database_server.txt

Полученные результаты:


=== Application Server 1 ===
Mon Feb 22 13:05:01 EST 2010
real    0m0.008s
user    0m0.001s
sys     0m0.000s

Mon Feb 22 13:06:01 EST 2010
real    0m0.007s
user    0m0.002s
sys     0m0.000s

Mon Feb 22 13:07:01 EST 2010
real    0m0.008s
user    0m0.000s
sys     0m0.001s

=== Application Server 2 ===
Mon Feb 22 13:05:01 EST 2010
real    0m0.009s
user    0m0.000s
sys     0m0.002s

Mon Feb 22 13:06:01 EST 2010
real    0m0.009s
user    0m0.001s
sys     0m0.003s

Mon Feb 22 13:07:01 EST 2010
real    0m0.008s
user    0m0.000s
sys     0m0.001s

=== Database Server ===
Mon Feb 22 13:05:01 EST 2010
real    0m0.016s
user    0m0.000s
sys     0m0.010s

Mon Feb 22 13:06:01 EST 2010
real    0m0.006s
user    0m0.010s
sys     0m0.000s

Mon Feb 22 13:07:01 EST 2010
real    0m0.016s
user    0m0.000s
sys     0m0.010s

[РЕДАКТИРОВАТЬ] В соответствии с предложением, полученным по вопросу LinkedIn, я попытался установить значение back_log выше. Мы использовали значение по умолчанию (50) и увеличили его до 150. Мы также увеличили значение ядра / proc / sys / net / core / somaxconn (максимальное количество подключений к сокетам) до 256 как на сервере приложения, так и на сервере базы данных с 128 по умолчанию. В результате мы наблюдали некоторое повышение загрузки процессора, но по-прежнему получали таймауты подключения.

Насколько хорошо это работает, если исключить PHP из уравнения? Используйте клиент CLI mysql для подключения к серверу. Попробуйте его как с самого сервера db, так и с сервера приложений:

time mysql -h localhost -D dbname -u username -ppassword -e ''

Проверьте свои DNS-серверы, я думаю, что mysql может пытаться разрешить обратный DNS подключенного хоста. Также убедитесь, что / etc / hosts в порядке и имеет "127.0.0.1 localhost"

Это может быть даже не близко, но не могли бы вы ждать сброса на диск? Может тайм-аут?

Учтите, что в случае сбоя вы можете потерять до 1 минуты данных.

innodb_flush_log_at_trx_commit = 0 (по умолчанию 1)

Это приведет к тому, что InnoDB будет записывать и очищать буфер журнала только один раз в секунду. : http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit