Оптимизация сайтов на 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? Я не знаю много об этом, но есть некоторые параметры конфигурации, которые могут оказать некоторое влияние.

Тем не менее, две самые важные вещи:

  • Не заходите в БД, если вам не нужно: кэшируйте как можно больше!
  • Когда вам нужно перейти к БД, используйте эффективные запросы: используйте индексы; и профиль!


И что теперь?

Если вы все еще читаете, что еще можно оптимизировать?

Ну, есть еще возможности для улучшений... Пара архитектурно-ориентированных идей может быть:

  • Переключиться на n-уровневую архитектуру:
    • Поместите MySQL на другой сервер (2 уровня: один для PHP; другой для MySQL)
    • Используйте несколько серверов PHP (и распределите нагрузку между пользователями)
    • Используйте другие машины для статических файлов с более легким веб-сервером, например:
      • Lighttpd
      • или nginx - этот становится все более и более популярным, кстати.
    • Используйте несколько серверов для MySQL, несколько серверов для PHP и несколько обратных прокси-серверов перед ними.
    • Конечно, установите http://memcached.org/ демоны на любом сервере, имеющем любое количество свободной оперативной памяти, и используйте их для кэширования настолько, насколько вы можете / имеет смысл.
  • Использовать что-то "более эффективное", что Apache?

Ну, может быть, некоторые из этих идей немного излишни в вашей ситуации ^^
Но все же... Почему бы не изучить их немного, на всякий случай?;-)


А как насчет Кохана?

Ваш первоначальный вопрос был об оптимизации приложения, которое использует Kohana... Хорошо, я опубликовал некоторые идеи, которые верны для любого приложения PHP... Что означает, что они верны и для Kohana;-)
(Даже если это не относится к этому ^^)

Я сказал: использовать кэш; Кажется, что Kohana поддерживает некоторые вещи, связанные с кэшированием (Вы говорили об этом сами, так что ничего нового здесь)
Если есть что-то, что можно сделать быстро, попробуйте;-)

Я также сказал, что вы не должны делать ничего ненужного; есть ли в Kohana по умолчанию что-то, что вам не нужно?
Просматривая сеть, кажется, есть хоть что-то в фильтрации XSS; тебе это нужно?

Тем не менее, вот несколько ссылок, которые могут быть полезны:


Заключение?

И, в заключение, простая мысль:

  • Сколько будет стоить вашей компании 5 дней? - учитывая, что это разумное количество времени, чтобы сделать некоторые большие оптимизации
  • Сколько будет стоить вашей компании покупка (оплата?) Второго сервера и его обслуживание?
  • Что делать, если вам нужно масштабировать больше?
    • Сколько будет стоить потратить 10 дней? Больше? оптимизировать каждый возможный бит вашего приложения?
    • А сколько еще на пару серверов?

Я не говорю, что вы не должны оптимизировать: вы определенно должны!
Но перейдите к "быстрой" оптимизации, которая сначала принесет вам большие выгоды: использование некоторого кэша кода операции может помочь вам получить от 10 до 50 процентов от загрузки процессора вашего сервера... И это займет всего пару минут для настройки;) С другой стороны, тратить 3 дня на 2 процента...

Да, и, между прочим: прежде чем что-то делать: поставьте некоторые элементы мониторинга на место, чтобы вы знали, какие улучшения были сделаны и как!
Без мониторинга вы не будете иметь представления о том, что вы сделали... Даже если это настоящая оптимизация или нет!

Например, вы можете использовать что-то вроде RRDtool + cacti.
И показывать вашему боссу хорошую графику с падением загрузки процессора на 40% - это всегда здорово;-)


Во всяком случае, и действительно, чтобы сделать вывод: веселиться!
(Да, оптимизировать это весело!)
(Э-э, я не думал, что напишу так много... Надеюсь, что хотя бы некоторые части этого полезны... И я должен помнить этот ответ: может быть полезным в другой раз...)

Используйте XDebug и WinCacheGrind или WebCacheGrind для профилирования и анализа медленного выполнения кода.

http://jokke.dk/media/2008-webgrind/webgrind_small.pngWinCacheGrind

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 (вы, вероятно, уже сделали это или нет):

В производственном режиме:

  1. Включите внутреннее кэширование (это только кеширует результаты Kohana::find_file, но на самом деле это может сильно помочь.
  2. Отключить профилировщик

Просто мои 2 цента:)

Я полностью согласен с XDebug и кешированием ответов. Не ищите оптимизацию в слое Kohana, пока не определите свои самые большие узкие места в скорости и масштабе.

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

Пример проблемы и решения: если вы обнаружите, что каждый раз вы создаете дорогие объекты из базы данных, которые не часто меняются, то вы можете посмотреть на их кэширование с помощью memcached или другого механизма. Все эти исправления производительности требуют времени и усложняют вашу систему, поэтому убедитесь, что у вас есть узкие места, прежде чем вы начнете их исправлять.

Другие вопросы по тегам