Оптимизация производительности сайта PHP, сообщества MYSQL - PullRequest
2 голосов
/ 17 ноября 2009

У меня есть веб-сайт сообщества с примерно 12.000 пользователей (интенсивно пишу), максимум 100 одновременно работающих пользователей на одном VPS с оперативной памятью 1 Гб. Нагрузка редко превышает 3, и отклик довольно хороший.

В настоящее время для хранения результатов запросов к БД используется простой файловый кеш, что облегчает загрузку БД, но веб-сайт по-прежнему может замедлять работу более 220 одновременно работающих пользователей (нагрузочный тест).

Как я могу узнать, что является узким местом?

Я предполагаю, что с БД все в порядке, так как кеш работает нормально, однако дисковый ввод-вывод может вызвать проблемы. Каждая загрузка страницы имеет около 10 включений и 10-20 запросов из БД или из файлового кэша, а также множество обработок php.

Я попытался использовать memcache вместо файлового кеша, но, к моему удивлению, нагрузочный тест показался файловым кешем больше.

Я планирую использовать Alternative PHP Cache, но я до сих пор не понимаю, как этот кеш становится недействительным. У меня есть один index.php, который обрабатывает все запросы. Будет ли кеш хранить результат для каждого отдельного запроса? Будет ли он очищать кеш автоматически при изменении одного из моих включений (или результатов запроса из кеша)?

Любые другие предложения для поиска узких мест (пробовал xdebug)?

Спасибо, Гамлет

Ответы [ 5 ]

5 голосов
/ 17 ноября 2009

Я планирую использовать Alternative PHP Cache, но я до сих пор не понимаю как этот кеш недействителен. я имею один index.php, который обрабатывает все Запросы. Будет ли кеш хранить результат для каждого отдельного запроса? Будет ли он очищать кеш автоматически если один из моих включает (или результат запроса из кеша) поменять?

APC не кэширует вывод. Он кэширует ваш скомпилированный байт-код.

По сути, обычный PHP-запрос выглядит так:

  1. PHP-файлы анализируются и компилируются в байт-код
  2. Интерпретатор PHP выполняет байт-код

APC кэширует результат первого шага, так что вы не будете перекомпилировать / перекомпилировать один и тот же код снова и снова. По умолчанию он по-прежнему stat() хранит ваши PHP-файлы при каждом запросе, чтобы увидеть, был ли файл изменен с момента компиляции его кэшированной копии, поэтому любые изменения в вашем коде автоматически сделают недействительной кэшированную копию.

Вы также можете использовать APC так же, как вы бы использовали memcached для хранения произвольных пользовательских данных. Имейте в виду, однако:

  1. Memcached сервер может обслуживать данные на нескольких серверах; Данные, кэшированные в APC, действительно могут использоваться только локально. Лучше обслуживать данные с одного ящика memcached на четыре сервера, чем иметь 4 копии этих данных в APC на каждом отдельном сервере.
  2. По моему опыту Memcached лучше обрабатывает большое количество одновременных записей в один ключ кеша.
  3. APC, похоже, не очень хорошо справляется с заполнением кеша. Фрагментация увеличивается, а производительность падает.

Кроме того, будьте осторожны: если вы не настроили какой-либо механизм блокировки, ваш файловый кэш может быть поврежден из-за одновременной записи. Если вы внедрили блокировку, это может стать узким местом. IMO, параллелизм сложен - пусть memcached / APC / база данных справится с этим.

1 голос
/ 17 ноября 2009

Вы упомянули, что использовали XDebug - что вы не смогли сделать? Как правило, чтобы начать поиск узкого места, вы включаете профилирование запроса, а затем просматриваете полученный файл «cachegrind» в KCacheGrind или WinCacheGrind .

Что касается использования системы кеша, такой динамический скрипт, как ваш, обычно делает что-то вроде этого

  • построить кеш-ключ из уникальных входных данных для скрипта
  • спросите систему кэширования, есть ли у нее данные для этого ключа. Если есть, ты в порядке!
  • в противном случае выполните всю тяжелую работу по генерации данных и попросите систему кэширования сохранить их под нужным ключом в следующий раз.

APC Cache может помочь ускорить процесс, кэшируя проанализированную версию кода PHP.

0 голосов
/ 18 ноября 2009

Я бы сказал, что, скорее всего, ваша база данных связана с IO, я точно не знаю, что такое «VPS», но если это какая-то виртуальная машина, то почти гарантированно будет очень плохо выполнять IO.

Получите это на реальном оборудовании как можно скорее; и получите разумное количество баранов (1G крошечный; 16G звучит более разумно).

Тогда вы сможете настроить свою БД, чтобы она могла вести себя правильно. Насколько велики ваши данные? Если вы можете заставить их всех (или большинство из них) поместиться в кеше вашей базы данных (не в каверзном кеше запросов, а в пуле буферов innodb), тогда сделайте это.

Я предполагаю, что вы используете движок innodb; если это так, то настройте буферный пул так, чтобы он был достаточно большим для всех ваших данных - если вам не хватает оперативной памяти, покупайте больше, пока не сделаете (Нет, правда!).

Тогда ваши запросы к БД должны быть быстрыми, даже если они довольно плохие (да).

Сложность в том, что, если у вас есть одна машина, как разделить использование оперативной памяти между mysql и PHP - веб-сервер (я полагаю, Apache), особенно если вы используете prefork и большое количество MaxClients, может использовать до баран и лишить его вашей базы данных.

Получите достойный мониторинг на работе (с трендами), тщательно внесите изменения и запишите точно, когда вы их сделали.

0 голосов
/ 17 ноября 2009

Я включил и настроил APC на тестовом сервере и получил увеличение производительности примерно на 400%

300 одновременно работающих пользователей с временем ответа не более 1,4 с :) Хорошо для начала.


Обновление:

Результаты тестов живого сервера

Оригинал:

Нет APC: 220 одновременных пользователей, загрузка сервера 20, время ответа 5000 мс

Нет APC: 250 одновременных пользователей, загрузка сервера 20+, сайт недоступен

Новое:

APC включен: 250 одновременных пользователей, загрузка сервера 2, время ответа 600 мс

APC включен: 350 одновременных пользователей, загрузка сервера 10, время отклика 1500 мс

APC включен: 500 одновременных пользователей, загрузка сервера 20, ответ 5000 мс + сайт полностью работоспособен, но немного медленен, но может использоваться нормально

Спасибо за предложения, это довольно большое улучшение.

Кэш запросов отключен, так как сайт загружен, поэтому кэш будет постоянно аннулироваться для целых таблиц.

0 голосов
/ 17 ноября 2009

MySQL имеет собственный кеш запросов.

Вы можете включить его, установив для query_cache_size более 0.

Результаты запроса берутся из кэша, если запрос повторяется дословно и не содержит определенных вещей, таких как недетерминированные функции, переменные сеанса и некоторые другие вещи, которые описывают здесь :

Кэш для запроса становится недействительным, если выполнить любую операцию DML для любого из базовых запросов.

...