PHP и SimpleDB. Проблемы скорости соединения.
Здравствуйте! В этой заметке хочу рассказать о практическом опыте использования связки PHP и SimpleDB и проблемах, которые могут возникнуть в плане общей производительности соединения на начальных этапах разработки.
Не так давно один из наших клиентов, в связи с резким ростом аудитории захотел избежать проблем горизонтального масштабирования путем использования служб Amazon WS — Amazon EC2 и Amazon SimpleDB.
Прежде всего, клиента волновала производительно базы данных на собственном сервере в виду роста контента, генерируемого пользователями.
Мы перевели структуру и данные клиента в структуру SimpleDB базы данных, взяли Instance Debian-а на EC2 и стали тестировать.
После внедрения и тестирования, мы неожиданно выяснили, что время выполнения скриптов достигает 100 мс, в то время как на сервере заказчика изначальное время выполнения до перехода на SimpleDB составляло 15.
О том что случилось и как мы с этим боролись — ниже.
Итак, время выполнения — 100 мс. Что с этим делать и откуда это взялось?
Прежде всего мы впервые применили XHProf — PHP профилировщик от Facebook о котором много услышали не так давно — и вот наконец то довелось использовать его в деле.
Профилирование в XHProf заключается в установке модуля и включении
и
Более подобную информацию об использовании XHProf можно прочитать на странице документации по адресу http://mirror.facebook.com/facebook/xhprof/doc.html
(к сожалению, в настоящий момент XHProf компилируется только под Linux и FreeBSD — MacOSX и Windows версии еще не реализованы)
Первичный анализ показал что львиную долю времени занимает не выполнение запроса к SimpleDB — о чем мы думали, а собственно процесс соединения с ней для передачи запроса.
Для того чтобы объяснить причины — нужно объяснить технологию работы библиотеки SimpleDB и базой данных.
В отличие от классических баз даных, сервер SimpleDB принимает данные не по собственному протоколу основанному на tcp/ip, а в рамках HTTP-протокола. Запрос передается в виде POST-данных на URL службы, ответом от службы — в XML формате — является результат выполненного запроса.
PHP-клиент SimpleDB от Amazon использует fsockopen для передачи каждого запроса к базе, и получив ответ закрывает соединение. Затем, посредством класса DOMDocument и XPath — происходит разбор ответа и окончательное получение данных.
Первым делом, мы заглянули внутрь классов SimpleDB и начали пошагово вести борьбу за милисекунды.
0. Профилировщик показал долгую работу класса Mock. Этот класс, предназанченый для UNIT-тестирования подключается и в production-коде.
Комментирование подключение класса позволило выйграть 15 мс.
Итого время выполнения: 85 мс.
1. класс Client. Класс реализует собственно процесс соединения с базой — оттуда мы и решили копать.
Прежде всего мы решили проверить — как именно соединяется класс с базой.
что же передается за URL?
взглянем немного выше…
… так-так-так, а сколько же времени уйдет на DNS-resolving.
Заменив днс-имя на айпи адрес получаем выигрыш в 20 мс.
Итого: 65 мс.
Что делать если IP-адрес изменится?
Мы создали программу, которая регулярно опрашивала днс на предмет айпи-адреса указанного сервера с целью записать IP в конфиг SimpleDB класса. Программу поставили в крон.
3.
Ребята, что это?
По умолчанию соединение устанавливается через SSL. Что будет если мы заменим https на http в конфигурационной строке? — Выигрыш в 30 мс.
Итого время выполнения 35 мс.
4. Что же еще мы можем сделать? Естественно мы используем PHP-акселераторы в production-среде — может быть структура классов подойдет для одного но не подойдет для другого?
Замена Eaccelerator на XCache успеха не принесла, но вернувшись к профилировщику мы увидели что очень большое количество времени тратится на require_once функции — подключалось 32 класса из папки Model.
cat * >includes.php
дальше нужно было отключить реквайры из SimpleDB класса подключив их уровнем выше.
удаление их из Client.php прошло совершенно безболезенно, однако кода мы перешли к Model.php мы увидели следующее
Интересно, как к этому относились PHP-акселераторы? И чего мы достигнем теперь?
Экономия — 15 мс.
Итого время выполнения — 20 мс.
5. Дальнейшая оптимизация кода привела к удалению одного из двух запросов к SimpleDB от уровня логики приложения.
Таким образом мы достигли скорости в 15 мс., что уже устраивало и нас и клиента — для этапа тестирования работоспособности сервисов.
Таким образом мы вспомнили славные времена экономии машинного времени, узнали в работе профилировщик XHProf (рекомендуем всем), а так же поняли — что практически не понятно как живут люди использующие SimpleDB на высоких нагрузках и использующие предлагаемые по умолчанию классы клиентов.
Если такие есть — просьба ответить, мы будем рады обменяться опытом и информацией.
Куда можно копать дальше?
Из оставшегося — мы планируем заменить обработку DOMDocument на SimpleXML и отказаться от XPath в выборках — это явно не лучшее, что можно использовать для разбора данных которые возвращает БД.
Мы планируем для запросов-выборок устанавливать Keep-Alive соединения для того, чтобы не устанавливать соединение на каждый запрос.
Продакшен-тестирование на высокой нагрузке ожидается через неделю.
Ждите отчета!
Не так давно один из наших клиентов, в связи с резким ростом аудитории захотел избежать проблем горизонтального масштабирования путем использования служб Amazon WS — Amazon EC2 и Amazon SimpleDB.
Прежде всего, клиента волновала производительно базы данных на собственном сервере в виду роста контента, генерируемого пользователями.
Мы перевели структуру и данные клиента в структуру SimpleDB базы данных, взяли Instance Debian-а на EC2 и стали тестировать.
После внедрения и тестирования, мы неожиданно выяснили, что время выполнения скриптов достигает 100 мс, в то время как на сервере заказчика изначальное время выполнения до перехода на SimpleDB составляло 15.
О том что случилось и как мы с этим боролись — ниже.
Итак, время выполнения — 100 мс. Что с этим делать и откуда это взялось?
Прежде всего мы впервые применили XHProf — PHP профилировщик от Facebook о котором много услышали не так давно — и вот наконец то довелось использовать его в деле.
Профилирование в XHProf заключается в установке модуля и включении
xhprof_enable(); — в начале скриптаи
$xhprof_data = xhprof_disable(); в конце.Более подобную информацию об использовании XHProf можно прочитать на странице документации по адресу http://mirror.facebook.com/facebook/xhprof/doc.html
(к сожалению, в настоящий момент XHProf компилируется только под Linux и FreeBSD — MacOSX и Windows версии еще не реализованы)
Первичный анализ показал что львиную долю времени занимает не выполнение запроса к SimpleDB — о чем мы думали, а собственно процесс соединения с ней для передачи запроса.
Для того чтобы объяснить причины — нужно объяснить технологию работы библиотеки SimpleDB и базой данных.
В отличие от классических баз даных, сервер SimpleDB принимает данные не по собственному протоколу основанному на tcp/ip, а в рамках HTTP-протокола. Запрос передается в виде POST-данных на URL службы, ответом от службы — в XML формате — является результат выполненного запроса.
PHP-клиент SimpleDB от Amazon использует fsockopen для передачи каждого запроса к базе, и получив ответ закрывает соединение. Затем, посредством класса DOMDocument и XPath — происходит разбор ответа и окончательное получение данных.
Первым делом, мы заглянули внутрь классов SimpleDB и начали пошагово вести борьбу за милисекунды.
0. Профилировщик показал долгую работу класса Mock. Этот класс, предназанченый для UNIT-тестирования подключается и в production-коде.
Комментирование подключение класса позволило выйграть 15 мс.
Итого время выполнения: 85 мс.
1. класс Client. Класс реализует собственно процесс соединения с базой — оттуда мы и решили копать.
Прежде всего мы решили проверить — как именно соединяется класс с базой.
if ($socket = @fsockopen($scheme . $url['host'], $port, $errno, $errstr, 10))что же передается за URL?
взглянем немного выше…
private $_config = array ('ServiceURL' => 'https://sdb.amazonaws.com' … так-так-так, а сколько же времени уйдет на DNS-resolving.
Заменив днс-имя на айпи адрес получаем выигрыш в 20 мс.
Итого: 65 мс.
Что делать если IP-адрес изменится?
Мы создали программу, которая регулярно опрашивала днс на предмет айпи-адреса указанного сервера с целью записать IP в конфиг SimpleDB класса. Программу поставили в крон.
3.
switch ($url['scheme']) {
case 'https':
$scheme = 'ssl://';
$port = $port === null ? 443 : $port;
break;
default:
$scheme = '';
$port = $port === null ? 80 : $port;
}
Ребята, что это?
По умолчанию соединение устанавливается через SSL. Что будет если мы заменим https на http в конфигурационной строке? — Выигрыш в 30 мс.
Итого время выполнения 35 мс.
4. Что же еще мы можем сделать? Естественно мы используем PHP-акселераторы в production-среде — может быть структура классов подойдет для одного но не подойдет для другого?
Замена Eaccelerator на XCache успеха не принесла, но вернувшись к профилировщику мы увидели что очень большое количество времени тратится на require_once функции — подключалось 32 класса из папки Model.
cat * >includes.php
дальше нужно было отключить реквайры из SimpleDB класса подключив их уровнем выше.
удаление их из Client.php прошло совершенно безболезенно, однако кода мы перешли к Model.php мы увидели следующее
require_once (CLASSES_DIR.''.str_replace('_', DIRECTORY_SEPARATOR, $fieldType[0]) . ".php");Интересно, как к этому относились PHP-акселераторы? И чего мы достигнем теперь?
Экономия — 15 мс.
Итого время выполнения — 20 мс.
5. Дальнейшая оптимизация кода привела к удалению одного из двух запросов к SimpleDB от уровня логики приложения.
Таким образом мы достигли скорости в 15 мс., что уже устраивало и нас и клиента — для этапа тестирования работоспособности сервисов.
Таким образом мы вспомнили славные времена экономии машинного времени, узнали в работе профилировщик XHProf (рекомендуем всем), а так же поняли — что практически не понятно как живут люди использующие SimpleDB на высоких нагрузках и использующие предлагаемые по умолчанию классы клиентов.
Если такие есть — просьба ответить, мы будем рады обменяться опытом и информацией.
Куда можно копать дальше?
Из оставшегося — мы планируем заменить обработку DOMDocument на SimpleXML и отказаться от XPath в выборках — это явно не лучшее, что можно использовать для разбора данных которые возвращает БД.
Мы планируем для запросов-выборок устанавливать Keep-Alive соединения для того, чтобы не устанавливать соединение на каждый запрос.
Продакшен-тестирование на высокой нагрузке ожидается через неделю.
Ждите отчета!



комментарии (35)