Полностью понять PDO ATTR_PERSISTENT
Вопрос:
Каковы правила/логика управления постоянным подключением при использовании PDO?
Окружающая среда:
Веб-сервер
- Windows 7 x64
- Двухъядерный процессор с 16 ГБ оперативной памяти
- Apache 2.2.17
- PHP 5.3.5
- Подключение по строке DSN с IP-адресом, портом, именем службы и т.д.
- Нет ODBC для подключения к DB (пытались создать его на 2 часа, спасибо Oracle!)
Сервер БД
- Oracle 10g в Linux
- Многоядерный с 4 ГБ оперативной памяти
- Имя пользователя, специально созданное для моего веб-приложения (да, это подделка)
Мое понимание/наблюдения:
Непрерывные соединения
<?php
// Open a new connection
// Session created in Oracle
$dbh = new PDO('DSN', 'webuser', 'password');
// webuser is active in v$session with a SID=1
$dbh = NULL;
// webuser removed from v$session
// Manually calling $dbh = NULL; will remove the session from v$session
// OR
// Wait for script EOL so a kill-session command is sent to Oracle?
?>
- Script надежно занимает ~.09 секунд для выполнения с накладными ресурсами фрейма и т.д.
Постоянные соединения
<?php
// Open a new connection and make it persistent
// Session created in Oracle
// Is Apache maintaining some sort of keep-alive with Oracle here?
// because I thought php.exe is only alive for the duration of the script
$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));
// webuser is active in v$session with a SID=1
$dbh = NULL;
// webuser is still active in v$session with a SID=1
$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));
// webuser is still active in v$session with a SID=1
// Manually calling $dbh = NULL; does not kill session
// OR
// Script EOL does not kill session
// ^^ this is good, just as expected
?>
- Script занимает ~.12 секунд для выполнения при первом посещении с использованием служебных данных структуры и т.д.
- Выполняется подсеквенция. ~.04
Проблема:
Я посещаю страницу, а webuser
получает SID=1
Мой коллега посещает страницу и webuser
получает дополнительный SID=2
< - rinse, repeat и increment SID для новых компьютеров, посещающих эту страницу
Не следует ли повторять использование нового посетителя SID=1
?
Приветствуются все ответы, предложения, запросы на альтернативное тестирование, ссылки на материалы для чтения.
У меня есть RTFM'ed какое-то время, и Googling только создавал скудные блоги Advantages of Persistent vs. Non-persistent
.
Ответы
Ответ 1
Точка зрения апачей
Apache имеет один родительский процесс. Этот процесс создает дочерние процессы, которые будут обрабатывать любые запросы, поступающие на веб-сервер.
Начальное количество дочерних процессов, запущенных при запуске веб-сервера, настраивается директивой StartServers
в конфигурации apache. Число увеличивается по мере необходимости с увеличением количества запросов, поражающих веб-сервер, до достижения ServerLimit
.
PHP и постоянные соединения
Если PHP (запущенный как mod_php, поскольку CGI все ресурсы освобождены в конце выполнения script), теперь говорят, чтобы установить постоянное соединение с базой данных для запроса, это соединение сохраняется даже после script отделки.
Соединение, которое теперь выполняется, представляет собой соединение между дочерним процессом apache, с которым был обработан запрос, и сервером базы данных и может быть повторно использован любым запросом, который обрабатывается этим точным дочерним процессом.
Если по какой-либо причине (не спрашивайте меня, почему именно) дочерний процесс занят дольше, чем фактический запрос, и приходит другой запрос, родительский процесс apache перенаправляет этот запрос на (новый) дочерний процесс, который может до этого времени не установил соединение с базой данных. Если это необходимо во время выполнения script, он вызывает SID, как вы это заметили. Теперь есть два соединения для двух разных дочерних процессов apache.
Имейте в виду, что...
Важно знать, что это также может вызвать массу проблем.
Если существует бесконечный цикл или прерванная транзакция или какая-либо другая может быть даже непредсказуемой ошибкой во время выполнения script, соединение блокируется и не может быть повторно использовано.
Также может случиться, что все доступные соединения базы данных используются, но есть еще один дочерний процесс сервера Apache, пытающийся получить доступ к базе данных.
Этот процесс блокируется до тех пор, пока соединение не будет освобождено базой данных или apache (тайм-аут или добровольно по окончании).
Дополнительная информация по этой теме на этой странице: http://www.php.net/manual/en/features.persistent-connections.php
Надеюсь, что у меня есть все, что мы обсудили в нашем разговоре, который правильно изложил и ничего не забыл.
Если да, пожалуйста, оставьте мне подсказку, и я добавлю.:)
Edit:
Я только что закончил читать статью @MonkeyZeus, упомянутую в этом комментарии.
Он описывает процесс, который я обобщил выше, и предоставляет полезную информацию о том, как оптимизировать ваш сервер Apache для лучшей работы вместе с постоянными соединениями.
Однако он может использоваться с бэкэндами базы данных oracle.
Вы должны посмотреть: http://www.oracle.com/technetwork/articles/coggeshall-persist-084844.html
Ответ 2
PDO как-то смешно. Даже тот же пользователь/посетитель может создать второй или даже третий экземпляр. То же самое произошло со мной на моей локальной машине, проверяя производительность моих запросов db.
Это не о чем беспокоиться, потому что эти экземпляры рано или поздно истекут, точный тайм-аут зависит от конфигурации вашего сервера.
Почему это происходит? Если текущий экземпляр занят, то будет создан новый экземпляр, а старший будет раньше или позже. По крайней мере, это кажется мне логичным.