Введение

Всем известно, что CakePHP медленный. А вот что известно не всем — то что это запланировано изначально. У меня могут быть проблемы из-за того, что я делаю этот секрет достоянием общественности, но я осознанно иду на риск. У меня есть доказательства — список длиной в километр, в котором наглядно показано, что разработчики CakePHP активно скупают акции Dell, IBM, Cisco и других компаний, производящих серверное оборудование. Мы все слышали выражение «сервера стоят дешево, а программисты — дорого». Команда CakePHP нашла способ монетизировать его, выпустив фреймворк, который позволяет разрабатывать быстро, но работает медленно. Они хотят, чтобы вы покупали больше железа. Оригинально, да? Так что я здесь, чтобы положить конец всему этому. Каждый совет в этой статье — это минус одна золотая цепь на шее разработчиков CakePHP.

Примечания.

Я предполагаю, что вы уже используете ContainableBehavior, а также индексировали таблицы и оптимизировали SQL-запросы Я использовал утилиту ab для замеров производительности каждого из этих изменений относительно базовой производительности простого приложения с уровнем дебага 0. Я не привожу цифры, так как они очень отличаются в зависимости от приложения/компьютера. Вместо этого я привожу примерный уровень прироста производительности в процентах. Нет, вы не можете увидеть исходники тестового приложения

1. Установите Debug=0

Не хитро, да? Есть куча сообщений в гугл-группе, которые говорят об обратном. Прежде чем даже думать об ускорении своего приложения, убедитесь, что Debug=0.

Вот на что это влияет. Для работы Cake генерирует 2 раздела кэша.

Первый — это /tmp/cache/models. В нем хранятся схемы БД для каждой из моделей вашего приложения. Ну эти бесчисленные «DESCRIBE table» которые вы видите в отладочном выводе. Они для этого. Этих запросов не будет, если Debug=0.

Второй — /tmp/cache/persistent. Это немножко другие файлы, которые кэйк использует при запуске приложения. Дольше всего генерируется cake_core_file_map. Этот файл хранит пути к классам вашего приложения. Чтобы построить его, кэйк делает очень времязатратный поиск по дереву каталогов в поиске нужного файла.

Таким образом, какая же разница между Debug=0 и Debug>0? Эээ… около 2.73517104 лет. Когда Debug>0 — время жизни кэша — 10 секунд, а Debug=0 — 999 дней.

Прирост

от 80% до 100%

2. Кэшируйте медленные SQL-запросы, запросы к веб-сервисам и все такое

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

Прирост

от 0% до 1000000% — в зависимости от того, как и что вы кэшируете

3. Кэширование страниц

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

Примечание

В документации описано несколько движков кэширования. Но в данный момент (версия 1.2.2), кэширование страниц использует кэширование в файлах и независимо от кэширования, описанного в пункте 2.

Прирост

от 130% до 160%

4. HTML кэширование

Это мое творение, основывающееся на том же принципе, что и Super Cache for WordPress. Оно берет отрисованную страницу и пишет её в корень вашего сайта в виде HTML-файла. При следующем запросе страницы веб-сервер сможет отдать ее даже без участия PHP. Конечно существуют явные ограничения, такие как отсутствие динамического содержимого на странице, а также отсутствие автоматического очищения кэша. Но все равно это отличная штука для rss-фидов или для страниц с одинаковым контентом для всех посетителей.

Прирост

60000% — это не гипербола, а реальное увеличение

5. APC (или другой опкод-кэшер)

Википедия описывает APC как «свободный, опен-соурс фреймворк, который оптимизирует байт-код PHP и кэширует данные и компилированный код, полученный от PHP компилятора, в разделяемой памяти». В общем, он делает PHP гораздо быстрее.

Прирост

от 25% до 100%

6. Persistent Models

Они не упомянуты в документации, но ими просто пользоваться. Просто добавьте в контроллер строчку

var $persistModel = true;

После обновления страницы, вы обнаружите два новых файла в /tmp/cache/persistent для каждой модели, подключенной к контроллеру. Первый — закэшированная модель, а второй — кэш для объектов в ClassRegistry. Как и кэширование страниц, упомянутое выше, этот кэш может существовать только в файлах.

Прирост

от 0% до 200% Насколько эта штука помогает зависит от вашего приложения. Если у контроллера только одна модель и она не ассоциирована с другими, то прироста вы не увидите. В моем тестовом приложении было около 100% ускорения. У меня была одна модель в контроллере, ассоциированная с тремя другими моделями, каждая со своими ассоциациями.

7. Хранение системного кэша в APC

Чтобы воспользоваться этим советом, вам нужен установленный APC и настроенная на его использование конфигурация кэша "cake_core" . В core.php напишите

Cache::config('cake_core', array('engine' => 'Apc', 'duration'=> 3600, 'probability'=> 100, ));

Это заставит кэйк кэшировать файлы, которые обычно располагаются в /tmp/cache/persistent (кроме persistent models), в памяти.

Прирост

примерно 25%

8. Ускорения обратного разрешения маршрутов (reverse routing)

Есть два способа сделать это. Первый описан здесь. Этот метод работает только для определенных видов ссылок и отключает reverse routing. Мой использует кэширование

Прирост

около 50%, в зависимости от вашего приложения

Это перевод. Оригинал статьи — здесь.