Оптимизация сайтов на Kohana для скорости и масштабируемости
Вчера сайт, который я построил с Kohana, был переполнен огромным количеством трафика, что заставило меня сделать шаг назад и оценить часть дизайна. Мне интересно, каковы некоторые стандартные методы оптимизации приложений на основе Kohana?
Я также заинтересован в бенчмаркинге. Нужно ли настраивать Benchmark::start()
а также Benchmark::stop()
для каждого метода контроллера, чтобы увидеть время выполнения для всех страниц, или я могу применить глобальный и быстрый сравнительный анализ?
Я буду использовать библиотеку Cache больше в будущем, но я открыт для большего количества предложений, так как я уверен, что я могу многое сделать, о чем я просто не знаю в данный момент.
6 ответов
То, что я скажу в этом ответе, не относится к Kohana и, вероятно, может применяться ко многим проектам PHP.
Вот некоторые моменты, которые приходят мне в голову, когда речь идет о производительности, масштабируемости, PHP, ...
Я использовал многие из этих идей, работая над несколькими проектами, и они помогли; так что они могли бы помочь и здесь.
Прежде всего, когда дело доходит до выступлений, есть много аспектов / вопросов, которые следует рассмотреть:
- настройка сервера (Apache, PHP, MySQL, другие возможные демоны и система); Вы можете получить дополнительную помощь об этом на ServerFault, я полагаю,
- Код PHP,
- Запросы к базе данных,
- Используете или нет ваш веб-сервер?
- Можете ли вы использовать какой-либо механизм кэширования? Или вам всегда нужно больше актуальных данных на сайте?
Использование обратного прокси
Первое, что может быть действительно полезным, - это использование обратного прокси-сервера, такого как varnish, перед вашим веб- сервером: пусть он кэширует как можно больше вещей, поэтому только запросы, которые действительно требуют вычислений PHP/MySQL (и, конечно, некоторые другие запросы, когда они не находятся в кеше прокси), делают это Apache/PHP/MySQL.
- Прежде всего, ваш CSS / Javascript / Images - ну, все, что статично - вероятно, не всегда должен обслуживаться Apache
- Таким образом, вы можете иметь кеш обратного прокси.
- Обслуживание этих статических файлов не составляет большого труда для Apache, но чем меньше он должен работать для них, тем больше он сможет делать с PHP.
- Помните: Apache может обслуживать только ограниченное количество запросов одновременно.
- Затем, пусть обратный прокси-сервер обслуживает как можно больше PHP-страниц из кэша: возможно, есть страницы, которые меняются не так часто и могут обслуживаться из кэша. Вместо использования некоторого кеша на основе PHP, почему бы не позволить другому, более легкому серверу обслуживать их (и время от времени извлекать их с PHP-сервера, чтобы они всегда были почти в курсе)?
- Например, если у вас есть несколько RSS-каналов (мы обычно склонны забывать те, когда пытаемся оптимизировать производительность), которые запрашиваются очень часто, их хранение в кэше в течение нескольких минут может сохранить сотни / тысячи запросов в Apache+PHP. +MySQL!
- То же самое для наиболее посещаемых страниц вашего сайта, если они не меняются в течение по крайней мере пары минут (например, домашней страницы?), То нет необходимости тратить ЦП на их повторную генерацию каждый раз, когда пользователь запрашивает их.
- Может быть, есть разница между страницами, обслуживаемыми анонимными пользователями ( одна и та же страница для всех анонимных пользователей), и страницами, обслуживаемыми для идентифицированных пользователей (например, "Здравствуйте, мистер Х, у вас есть новые сообщения")?
- Если это так, вы, вероятно, можете настроить обратный прокси-сервер для кэширования страницы, которая обслуживается анонимными пользователями (обычно на основе файла cookie, такого как файл cookie сеанса)
- Это будет означать, что с Apache+PHP меньше приходится иметь дело: только с идентифицированными пользователями, которые могут быть только небольшой частью ваших пользователей.
Об использовании обратного прокси-сервера в качестве кэша для приложения PHP можно, например, взглянуть на результаты тестов производительности, показывающие увеличение возможностей сервера на 400%-700% с APC и Squid Cache.
(Да, они используют Squid, а я говорил о лаке - это просто еще одна возможность ^^ Varnish более свежий, но более посвященный кешированию)
Если вы сделаете это достаточно хорошо, и вам удастся прекратить повторное создание слишком большого количества страниц снова и снова, возможно, вам даже не придется оптимизировать какой-либо код;-)
По крайней мере, может быть, не в какой-то спешке... И всегда лучше проводить оптимизацию, когда вы не находитесь под слишком большим давлением...
В качестве обозначения: вы говорите в ОП:
Вчера сайт, который я построил с Kohana, был переполнен огромным количеством трафика,
Это внезапная ситуация, когда обратный прокси-сервер может буквально сэкономить день, если ваш сайт может быть не обновлен с точностью до секунды:
- установить его, настроить его, пусть это всегда - каждый обычный день - запустить:
- Настройте его так, чтобы PHP-страницы не хранились в кэше; или только на короткое время; таким образом, у вас всегда отображаются актуальные данные
- И в тот день, когда вы берете эффект слешдот или копания:
- Сконфигурируйте обратный прокси-сервер для хранения страниц PHP в кэше; или на более длительный период времени; возможно, ваши страницы не будут обновляться с точностью до секунды, но это позволит вашему сайту пережить эффект digg!
О том, как я могу обнаружить и выжить, будучи "Слэшдоттом"? может быть интересным чтением.
На стороне PHP вещей:
Прежде всего: вы используете последнюю версию PHP? Регулярно улучшаются скорости, появляются новые версии;-)
Например, посмотрите на Benchmark PHP Branches 3.0 - 5.3-CVS.
Обратите внимание, что производительность - довольно веская причина для использования PHP 5.3 ( я сделал несколько тестов (на французском), и результаты отличные)...
Еще одна довольно веская причина, конечно, в том, что PHP 5.2 достиг конца своей жизни и больше не поддерживается!
Вы используете какой-либо кэш кода операции?
- Я имею в виду APC - альтернативный PHP Cache, например ( pecl, manual), который является решением, которое я видел чаще всего, и которое используется на всех серверах, на которых я работал.
- В некоторых случаях он действительно может значительно снизить нагрузку на процессор сервера (я видел, что загрузка процессора на некоторых серверах возрастала с 80% до 40%, просто за счет установки APC и активации его функции кэш-кода операции!)
- По сути, выполнение сценария PHP происходит в два этапа:
- Компиляция исходного кода PHP в коды операций (своего рода эквивалент байт-кода JAVA)
- Исполнение этих опкодов
- APC хранит их в памяти, поэтому при каждом выполнении скрипта / файла PHP требуется меньше работы: только извлекайте коды операций из ОЗУ и выполняйте их.
- Возможно, вам придется взглянуть на параметры конфигурации APC, кстати
- их довольно много, и некоторые из них могут оказать большое влияние как на скорость / загрузку процессора / простоту использования для вас
- Например, отключение
[apc.stat](http://php.net/manual/en/apc.configuration.php#ini.apc.stat)
может быть хорошо для загрузки системы; но это означает, что изменения, внесенные в файлы PHP, не будут приняты во внимание, если вы не очистите весь кэш кода операции; об этом, подробнее см., например, To stat() или Not To stat()?
Использование кеша для данных
Насколько это возможно, лучше избегать повторения одного и того же.
Главное, о чем я думаю, это, конечно, SQL-запросы: многие из ваших страниц, вероятно, выполняют одни и те же запросы, и результаты некоторых из них, вероятно, почти всегда одинаковы... Что означает множество "бесполезных" запросов. внесено в базу данных, которая должна тратить время на обслуживание одних и тех же данных снова и снова.
Конечно, это верно для других вещей, таких как вызовы веб-сервисов, получение информации с других веб-сайтов, тяжелые вычисления,...
Вам может быть очень интересно определить:
- Какие запросы выполняются много раз, всегда возвращая одни и те же данные
- Какие другие (тяжелые) вычисления выполняются много времени, всегда возвращая один и тот же результат
И храните эти данные / результаты в каком-то кеше, чтобы их было легче получить - быстрее - и вам не нужно ходить на ваш SQL-сервер "ни за что".
Великие механизмы кэширования, например:
- APC: в дополнение к коду операции, о котором я говорил ранее, он позволяет хранить данные в памяти,
- И / или memcached ( см. Также), что очень полезно, если у вас буквально много данных и / или вы используете несколько серверов, так как они распределены.
- конечно, вы можете думать о файлах; и, вероятно, многие другие идеи.
Я уверен, что ваш фреймворк содержит некоторые вещи, связанные с кешем; вы, вероятно, уже знаете, что, как вы сказали "я буду использовать Cache-библиотеку больше в будущем" в ОП;-)
профилирование
Теперь хорошо бы использовать расширение Xdebug для профилирования вашего приложения: оно часто позволяет довольно легко найти пару слабых мест - по крайней мере, если есть какая-либо функция, которая отнимает много времени.
При правильной настройке он будет генерировать файлы профилирования, которые можно анализировать с помощью некоторых графических инструментов, таких как:
- KCachegrind: мой любимый, но работает только на Linux / KDE
- Wincachegrind для окон; к сожалению, он делает немного меньше, чем KCacheGrind - обычно он не отображает графы вызовов.
- Webgrind, который работает на веб-сервере PHP, поэтому работает где угодно - но, вероятно, имеет меньше возможностей.
Например, вот пара скриншотов KCacheGrind:
http://extern.pascal-martin.fr/so/kcachegrind/kcachegrind-1.png http://extern.pascal-martin.fr/so/kcachegrind/kcachegrind-2.png
(Кстати, коллграф, представленный на втором скриншоте, как правило, является чем-то, что не могут сделать ни WinCacheGrind, ни Webgrind, если я правильно помню ^^)
(Спасибо @Mikushi за комментарий) Еще одна возможность, которую я мало использовал, - это расширение xhprof: оно также помогает с профилированием, может генерировать графы вызовов - но легче, чем Xdebug, что означает, что вы должны иметь возможность установить его на производственный сервер.
Вы должны быть в состоянии использовать его вместе с XHGui, который поможет для визуализации данных.
На стороне SQL вещей:
Теперь, когда мы немного поговорили о PHP, обратите внимание, что более чем возможно, что ваше узкое место - не сторона PHP, а база данных...
По крайней мере, две или три вещи, здесь:
- Вы должны определить:
- Какие наиболее частые запросы выполняет ваше приложение?
- Оптимизированы ли они (используя правильные индексы, в основном?), Используя
EXPLAIN
инструкция, если вы используете MySQL- Смотрите также: Оптимизация SELECT и других операторов
- Вы можете, например, активировать
log_slow_queries
чтобы получить список запросов, которые занимают "слишком много" времени, и приступить к их оптимизации.
- можете ли вы кэшировать некоторые из этих запросов (посмотрите, что я сказал ранее)
- Хорошо ли настроен ваш MySQL? Я не знаю много об этом, но есть некоторые параметры конфигурации, которые могут оказать некоторое влияние.
- Оптимизация MySQL Server может дать вам некоторую интересную информацию об этом.
Тем не менее, две самые важные вещи:
- Не заходите в БД, если вам не нужно: кэшируйте как можно больше!
- Когда вам нужно перейти к БД, используйте эффективные запросы: используйте индексы; и профиль!
И что теперь?
Если вы все еще читаете, что еще можно оптимизировать?
Ну, есть еще возможности для улучшений... Пара архитектурно-ориентированных идей может быть:
- Переключиться на n-уровневую архитектуру:
- Поместите MySQL на другой сервер (2 уровня: один для PHP; другой для MySQL)
- Используйте несколько серверов PHP (и распределите нагрузку между пользователями)
- Используйте другие машины для статических файлов с более легким веб-сервером, например:
- Используйте несколько серверов для MySQL, несколько серверов для PHP и несколько обратных прокси-серверов перед ними.
- Конечно, установите http://memcached.org/ демоны на любом сервере, имеющем любое количество свободной оперативной памяти, и используйте их для кэширования настолько, насколько вы можете / имеет смысл.
- Использовать что-то "более эффективное", что Apache?
- Я все чаще и чаще слышу о nginx, что должно быть замечательно, когда речь заходит о PHP и больших сайтах; Я никогда не использовал это сам, но вы можете найти некоторые интересные статьи об этом в сети;
- например, производительность PHP III - Запуск nginx.
- См. Также: PHP-FPM - менеджер процессов FastCGI, который поставляется с PHP >= 5.3.3 и творит чудеса с nginx.
- Я все чаще и чаще слышу о nginx, что должно быть замечательно, когда речь заходит о PHP и больших сайтах; Я никогда не использовал это сам, но вы можете найти некоторые интересные статьи об этом в сети;
Ну, может быть, некоторые из этих идей немного излишни в вашей ситуации ^^
Но все же... Почему бы не изучить их немного, на всякий случай?;-)
А как насчет Кохана?
Ваш первоначальный вопрос был об оптимизации приложения, которое использует Kohana... Хорошо, я опубликовал некоторые идеи, которые верны для любого приложения PHP... Что означает, что они верны и для Kohana;-)
(Даже если это не относится к этому ^^)
Я сказал: использовать кэш; Кажется, что Kohana поддерживает некоторые вещи, связанные с кэшированием (Вы говорили об этом сами, так что ничего нового здесь)
Если есть что-то, что можно сделать быстро, попробуйте;-)
Я также сказал, что вы не должны делать ничего ненужного; есть ли в Kohana по умолчанию что-то, что вам не нужно?
Просматривая сеть, кажется, есть хоть что-то в фильтрации XSS; тебе это нужно?
Тем не менее, вот несколько ссылок, которые могут быть полезны:
- Kohana Общая дискуссия: кеширование?
- Поддержка сообщества: Оптимизация веб-сайта: максимальная производительность веб-сайта с использованием Kohana
Заключение?
И, в заключение, простая мысль:
- Сколько будет стоить вашей компании 5 дней? - учитывая, что это разумное количество времени, чтобы сделать некоторые большие оптимизации
- Сколько будет стоить вашей компании покупка (оплата?) Второго сервера и его обслуживание?
- Что делать, если вам нужно масштабировать больше?
- Сколько будет стоить потратить 10 дней? Больше? оптимизировать каждый возможный бит вашего приложения?
- А сколько еще на пару серверов?
Я не говорю, что вы не должны оптимизировать: вы определенно должны!
Но перейдите к "быстрой" оптимизации, которая сначала принесет вам большие выгоды: использование некоторого кэша кода операции может помочь вам получить от 10 до 50 процентов от загрузки процессора вашего сервера... И это займет всего пару минут для настройки;) С другой стороны, тратить 3 дня на 2 процента...
Да, и, между прочим: прежде чем что-то делать: поставьте некоторые элементы мониторинга на место, чтобы вы знали, какие улучшения были сделаны и как!
Без мониторинга вы не будете иметь представления о том, что вы сделали... Даже если это настоящая оптимизация или нет!
Например, вы можете использовать что-то вроде RRDtool + cacti.
И показывать вашему боссу хорошую графику с падением загрузки процессора на 40% - это всегда здорово;-)
Во всяком случае, и действительно, чтобы сделать вывод: веселиться!
(Да, оптимизировать это весело!)
(Э-э, я не думал, что напишу так много... Надеюсь, что хотя бы некоторые части этого полезны... И я должен помнить этот ответ: может быть полезным в другой раз...)
Используйте XDebug и WinCacheGrind или WebCacheGrind для профилирования и анализа медленного выполнения кода.
Kohana работает очень быстро, за исключением использования объектов базы данных. Процитируем Zombor: "Вы можете уменьшить использование памяти, гарантируя, что вы используете объект результата базы данных вместо массивов результатов". Это делает разницу в производительности HUGEE на сайте, который захлопывается. Он не только использует больше памяти, но и замедляет выполнение сценариев.
Также - вы должны использовать кеширование. Я предпочитаю memcache и использую его в своих моделях следующим образом:
public function get($e_id)
{
$event_data = $this->cache->get('event_get_'.$e_id.Kohana::config('config.site_domain'));
if ($event_data === NULL)
{
$this->db_slave
->select('e_id,e_name')
->from('Events')
->where('e_id', $e_id);
$result = $this->db_slave->get();
$event_data = ($result->count() ==1)? $result->current() : FALSE;
$this->cache->set('event_get_'.$e_id.Kohana::config('config.site_domain'), $event_data, NULL, 300); // 5 minutes
}
return $event_data;
}
Это также значительно повысит производительность. Вышеуказанные два метода улучшили производительность сайта на 80%.
Если бы вы дали больше информации о том, где, по вашему мнению, узкое место, я уверен, что мы могли бы дать некоторые лучшие идеи.
Также проверьте yslow (Google это) для некоторых других советов по производительности.
Код профиля с XDebug.
Используйте много кеширования. Если ваши страницы относительно статичны, то лучшим способом сделать это может быть обратный прокси.
Строго связано с Kohana (вы, вероятно, уже сделали это или нет):
В производственном режиме:
- Включите внутреннее кэширование (это только кеширует результаты Kohana::find_file, но на самом деле это может сильно помочь.
- Отключить профилировщик
Просто мои 2 цента:)
Я полностью согласен с XDebug и кешированием ответов. Не ищите оптимизацию в слое Kohana, пока не определите свои самые большие узкие места в скорости и масштабе.
XDebug скажет вам, где вы проводите большую часть своего времени, и определит "горячие точки" в вашем коде. Сохраните эту информацию профилирования, чтобы вы могли оценить и оценить улучшения производительности.
Пример проблемы и решения: если вы обнаружите, что каждый раз вы создаете дорогие объекты из базы данных, которые не часто меняются, то вы можете посмотреть на их кэширование с помощью memcached или другого механизма. Все эти исправления производительности требуют времени и усложняют вашу систему, поэтому убедитесь, что у вас есть узкие места, прежде чем вы начнете их исправлять.