Оптимизация сайтов, основанных на коханах, для скорости и масштабируемости

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

Я тоже интересуюсь бенчмаркингом. Нужно ли мне настраивать Benchmark::start() и Benchmark::stop() для каждого метода-контроллера, чтобы видеть время выполнения для всех страниц, или я могу применять бенчмаркинг глобально и быстро?

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

Ответ 1

То, что я скажу в этом ответе, не относится к 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-приложения вы можете, например, взглянуть на Benchmark Results Show 400% -700% увеличения возможностей сервера с APC и Squid Cache.
(Да, они используют Squid, а я говорил о лаке - это просто еще одна возможность ^^ Varnish более свежая, но более посвященная кешированию)

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


В качестве обозначения: вы говорите в ОП:

Вчера сайт, который я построил с Kohana, был переполнен огромным количеством трафика,

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

  • установить его, настроить его, пусть это всегда - каждый обычный день - запустить:
    • Настройте его так, чтобы страницы PHP не хранились в кэше; или только на короткое время; таким образом, у вас всегда отображаются актуальные данные
  • И в тот день, когда вы берете эффект слешдот или копания:
    • Настройте обратный прокси-сервер, чтобы PHP-страницы оставались в кэше; или на более длительный период времени; может быть, ваши страницы не будут обновляться с точностью до секунды, но это позволит вашему сайту пережить эффект digg!

О том, как я могу обнаружить и выжить, будучи "Slashdotted"? может быть интересным чтением.


На стороне 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](https://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:

KCacheGrind : main screen
(источник: pascal-martin.fr)
KCacheGrind : Callgraph exported as an image
(источник: pascal-martin.fr)

(Кстати, коллграф, представленный на втором скриншоте, как правило, является чем-то, что не может сделать ни WinCacheGrind, ни Webgrind, если я правильно помню ^^)


(Спасибо @Mikushi за комментарий) Еще одна возможность, которую я мало использовал, это расширение xhprof: оно также помогает с профилированием, может генерировать графы вызовов - но легче, чем Xdebug, что означает, что вы должны иметь возможность установить его на производственный сервер.

Вы должны быть в состоянии использовать его вместе с XHGui, который поможет для визуализации данных.


На стороне SQL вещей:

Теперь, когда мы немного поговорили о PHP, обратите внимание, что более чем возможно, что ваше узкое место - не сторона PHP, а база данных...

По крайней мере, две или три вещи, здесь:

  • Вы должны определить:
    • Какие наиболее частые запросы выполняет ваше приложение?
    • Оптимизированы ли они (используя правильные индексы, в основном?), Используя инструкцию EXPLAIN, если вы используете MySQL
    • можете ли вы кешировать некоторые из этих запросов (посмотрите, что я сказал ранее)
  • Хорошо ли настроен ваш MySQL? Я не знаю много об этом, но есть некоторые параметры конфигурации, которые могут оказать некоторое влияние.

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

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


И что теперь?

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

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

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

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


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

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

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

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

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


Заключение?

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

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

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

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

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


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

Ответ 2

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

WebCacheGrind
(источник: jokke.dk)
WinCacheGrind

Ответ 3

Код профиля с XDebug.

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

Ответ 4

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 it) для некоторых других советов по производительности.

Ответ 5

Строго связано с Коханой (вы, вероятно, уже сделали это, или нет):

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

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

Только мои 2 цента:)

Ответ 6

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

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

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