Ромка!eu

  • Отдых
  • Работа
Главная — Блоги — Ромка's blog

Это старая (Drupal 6) версия сайта romka.eu. Она больше не обновляется, комментирование материалов отключено. Обновленная версия сайта доступна по адресу http://romka.eu.

Кеширование на Drupal-сайте. Сравнение встроенного в Drupal кеша, статического файлового кеша (модуль Boost) и Varnish

Ромка — Чт, 06/14/2012 - 23:15

Публикую текст своего доклада для Друпалконфа, который прошел 4 июня 2012 года в Москве. Хочу акцентировать внимание на том, что этот текст не адаптирован под блогпост и публикуется в том виде, в котором я рассказывал его на конференции.

Введение

В текущем Drupal 6 проекте, над которым я работаю последние 2 года, в пике мы отдаем до 2 млн просмотров страниц в день и забиваем полностью наш 200-мегабитный интернет-канал. Судя по отчетам нашей системы мониторинга с текущей архитектурой и железом (6 серверов: 2 фронтэнда с nginx, 2 бэкенда с Varnish + Apache + Drupal и 2 MySQL-сервера с master-slave репликацией) мы можем выдерживать втрое большую нагрузку, если решим вопрос с каналом.

За время работы этого проекта мы на нем успели применить и испытать если не все, то большинство технологий по оптимизации производительности, которые применимы к Друпалу, в том числе использовали собственные велосипеды, но в итоге пришли к использованию связки Прессфлоу + Варниш и эта связка показала себя самой производительной и простой в сопровождении (в сравнении с собственными патчами ядра и модулей).

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

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

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

Я рассмотрю три варианта кеширования:

  1. встроенная в Друпал система кеширования и механизмы её расширяющие,
  2. файловый кеш (модуль Boost),
  3. Pressflow + Varnish,
  4. Альтернативы?

Встроенные механизмы

Итак, приступим. Сначала рассмотрим схему работы Друпала из коробки и встроенную в него систему кеша. Логика работы простая:

  1. пользователь открывает страницу в браузере, браузер передает запрос нашему веб-серверу,
  2. веб-сервер определяет что делать с запросом: если запрашивается статический файл (картинка, css, java-script), то веб-сервер пытается отдать этот файл сам, если запрошена динамическая страница, то запрос передается приложению, в нашем случае Друпалу.
  3. Друпал генерирует страницу, делая при этом множество запросов к базе данных, и страница по обратной цепочке уходит пользователю.

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

В Друпале из коробки для этих целей в настройках производительности достаточно установить соответсвующий радиобаттон и тогда логика работы Друпала поменяется следующим образом:

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

Встроенное в Друпал кеширование это уже лучше чем ничего, но все равно оно полно недостатков:

  1. для отдачи кеша нужно грузить ядро Друпала,
  2. для отдачи кеша нужно делать запрос к БД,
  3. в случае падения БД пользователи не смогут увидеть даже закешированную версию сайта,
  4. ну и, хоть это и самый простой в настройке механизм кеширования, он и самый медленный по сравнению с любыми другими альтернативами.

Для решения второй проблемы (хранении кеша в БД), можно использовать такие модули как memcache или cacherouter, их суть состоит в том, что они предоставляют альтернативные базе данных хранилища для кеша, например Memcache. Кроме того они позволяют расширить стандартный Друпальский кеш такими фичами, как перенос сессий и кеша URL’ов в мемкеш, но, несмотря на это, эти механизмы для отдачи кеша по прежнему требуют загрузку ядра Друпала, а это дорогостоящая операция.

В Друпале есть 2 режима кеширования: нормальный и агрессивный. Отличие агрессивного от нормального в том, что в нормальном режиме даже при отдаче данных из кеша Друпал вызывает хуки hook_boot и hook_exit, в агрессивном режиме Друпал этого не делает, по этой причине с агрессивным режимом некорректно работают модули, использующие эти хуки, например, модуль ядра Statistics, так как он пишет статистику именно на hook_exit.

Boost

И, таким образом, я делаю подводку к идее, что Друпал, как минимум, не должен отвечать за отдачу кеша, а как максимум еще и за его генерацию, но об этом позже. И таким решением является модуль Boost. Суть его состоит в том, что сгенерированная Друпалом страница складывается не в БД, не в мемкеш, а в файловую систему в виде html-файла. Конфиг веб-сервера дорабатывается таким образом, чтобы при запросе страницы веб-сервер сначала пытался найти закешированную страницу в файловой системе и только в случае отсутствия кеша запрашивал Друпал.

Этот метод из коробки работает только для кеша для анонимов, по этому может и должен использоваться с методами, о которых я рассказал ранее.

По сравнению с предыдущими методами этот имеет несколько больших плюсов:

  1. значительно выше скорость отдачи кеша, так как отдает его веб-сервер не трогая Друпал,
  2. как следствие, снижается нагрузка на Друпал, так как теперь он должен в основном только обслуживать зарегистрированных пользователей,
  3. при падении БД, анонимы будут продолжать получать закешированные версии страниц.

Также в плюсы Буста можно записать относительную простоту его настройки и нетребовательность к ресурсам сервера: если у разработчика хватило умений настроить Друпал, то он сможет настроить и Буст; если на сервере запустился Друпал, то на нем будет работать и Буст, не нужно устанавливать и настраивать дополнительный софт типа Мемкеша или Варниша.

К недостаткам Буста можно отнести следующие пункты:

  1. из коробки не умеет работать в случае если Друпал разнесен на несколько бэкендов, мы в свое время патчили Буст, чтобы решить эту проблему.
  2. Работает только для анонимов. Существуют ситуации, в которых подобный механизм мог бы использоваться и для зарегистрированных юзеров. Теоретически, Буст также можно пропатчить для решения этой проблемы, но на практике нам оказалось гораздо проще вообще отказаться от использования Буста в пользу перехода на Прессфлоу и Варниш.

Есть еще одна интересная идея развития подхода, который реализует Буст. Это просто идея, думаю, что применительно к Друпалу ее никто не использует, так как с Друпалом проще использовать Варниш, хотя я не раз натыкался на описание такого подхода в недрупальских проектах.

Замечательный веб-сервер nginx умеет читать данные из мемкеша, то есть также как и в случае использования Буста, веб-сервер получив запрос сначала пытается найти в файловой системе закешированную версию запрошенной страницы, nginx, получив запрос, может сначала попытаться найти закешированную версию страницы в мемкеше. То есть можно написать модуль аналогичный Бусту, который будет складывать кеш страниц в мемкеш, а отдавать его будет nginx. В отличии от Drupal-модулей memcache и cacherouter при такоим подходе кеш будет отдаваться мимо Друпала и будет работать в случае падения Друпала и БД.

Pressflow + Varnish

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

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

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

В случае если в кеше Варниша запрошенной страницы нет, он передаст запрос приложению и закеширует полученную в ответ страницу.

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

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

  1. таки Варниш для своей настройки требует некоторых знаний в области администрирования *nix-систем, он сложнее в настройке, чем Буст или встроенное в Друпал кеширование, но я уверен, что профессиональный разработчик с опытом работы с *nix-системами сможет установить и настроить Варниш.
  2. Варниш требует установки себя на сервер, то есть очень вероятно, что на обычных виртуальных хостингах использовать его не получится.

Теперь о плюсах:

  1. Варниш поддерживает несколько типов хранения кеша, в том числе он может хранить его в файловой системе или в оперативной памяти. Отдача кеша из оперативной памяти сильно быстрее отдачи кеша из ФС.
  2. В случае полного падения бэкенда: сломался веб-сервер, упала база, сгорел блок питания и т.п., пользователи будут получать закешированные версии страниц. В случае с Бустом посетители получали бы ошибки 50х, Варниш же, умеет в случае падения бэкенда отдавать кеш и авторизованным юзерам, это лучше чем отдавать ошибки.
  3. Варниш позволяет сколько угодно горизонтально масштабировать систему, мне знаком проект, в котором стоит 8 фронтендов с Варнишами (по 24 Гб ОЗУ в каждом).
  4. Варниш поддерживает ESI-инструкции, это означает, что при некоторой доработке приложения, кеш Варниша может быть использован и для авторизованных юзеров. Мы сейчас ведем работу в этом направлении, под “некоторой доработкой” я понимаю замену уникальных для зарегистрированных пользователей блоков (вход в систему, форма комментариев и т.п) заглушками, которые будут заменяться контентом либо Варнишем через ESI, либо аяксом (в этом плане очень выручает модуль ctools с его очень удобным плагином ajax).
  5. Варниш быстрее отдает кеш, чем любой из описанных мною ранее механизмов, в том числе и быстрее Буста (http://cruncht.com/95/drupal-caching/). Думаю, посоперничать в производительности с Варнишем могло бы только решение со сязкой nginx + memcache, о которой я говорил выше, но такого готового решения под Друпал нет и в условиях постоянной нехватки времени Варниш является максимально удобным решением по соотношению скорость работы / скорость внедрения.

Варниш, Друпал и Прессфлоу

Из коробки Друпал 6 не умеет работать с Ванишем, и бытует мнение, что для того чтобы подружить Друпал с Варнишем нужно обязательно заменить Друпал на его форк — Прессфлоу.

Это ошибка, использование Прессфлоу это самый простой путь внедрения Варниша, но, тем не менее, подружить Варниш с родным Друпалом все же можно. Причина того, что Варниш невозможно подружить с голым Друпалом состоит в том, что Варниш должен уметь отличать авторизованного юзера от анонима. Самый простой способ сделать это — зацепиться за куку SESS*, а для этого нужно, чтобы такая кука существовала только у авторизованных юзеров, но Друпал создает сессии для всех юзеров, в том числе и анонимов, по этому эта кука существует у всех юзеров.

Одна из особенностей Прессфлоу состоит в том, что он не создает сессии для анонимов, как следствие, Варниш может по наличию/отсутствию куки SESS* решать отдавать пользователю данные из кеша или нет. Решение резать сессии для анонимов достаточно радикальное и не все сайты могут пойти на такой шаг.

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

Одно из таких усовершенствований — возможность посылать SELECT-запросы на slave-сервер базы данных, это позволяет разгрузить мастер-сервер.

Выводы

Boost — простой в настройке, эффективный и нетребовательный к ПО сервера метод ускорить любой сайт на Друпае. Varnish — решение более эффективное чем Boost, но и более требовательное к профессиональным навыкам разработчика и окружению, в котоом работает сайт.

Ссылки

http://cruncht.com/slides/drupal-performance-scalability.html

  • Boost
  • cache
  • Drupal
  • Varnish
  • доклад
  • кеш
  • Работа
  • Ромка's blog

Отличная статья

drupal-admin → Сб, 06/23/2012 - 21:25

Спасибо, за отличную обзорную статью.
По поводу Вашей идеи модуля аналога Boost, который умеет складывать кэшированные страницы в memcache:
как вариант можно на сервере сделать диск в оперативной памяти, примонтировать его в каталог Drupal и на него складывать кэш Boost.
Из минусов, то что memcache лучше масштабируется по сравнению с этим решением.
--
С уважением, Роман
drupal-admin.ru

Обо мне

Всем привет!
Меня зовут
Роман Архаров, я профессиональный веб-разработчик, программирую на языках PHP, Python и Action-Script, в работе использую фреймворки Drupal и Django. В этом блоге я размещаю заметки и статьи, связанные с моей работой, отдыхом и другими интересными мне темами.

Похожие заметки

  • Пример разработки плагина для модуля CCK
  • Swftools и модуль Pdf2SWfField для Друпала
  • Доклад на DrupalConfMoscow 2011
  • Тестирование модуля "Inner poll"
  • Несколько статей о Друпале

Популярные заметки

  • Авторизация на Drupal-сайте с помощью аккаунта ВКонтакте
  • Перетаскивание строк таблицы. Table drag and drop — плагин для jQuery
  • Темизация Drupal. Часть 3. Основы Drupal Forms API и темизация форм
  • Темизация Drupal. Часть 4. Темизация Views
  • AJAX. Обмен данными между клиентом и сервером, закачка на сервер файлов без перезагрузки страницы при помощи библиотеки jQuery.
  • Кеширование на Drupal-сайте. Сравнение встроенного в Drupal кеша, статического файлового кеша (модуль Boost) и Varnish
  • Тестирование модуля "Inner poll"
  • Несколько панорам из путешествия по Перу и Боливии
  • Arduino + bluetooth, небольшая проблема
  • Пример разработки плагина для модуля CCK

Подписка


Последние комментарии

  • drupal-admin → Кеширование на Drupal-сайте. Сравнение эффективности встроенного в Drupal кеша, статического файлового кеша (модуль Boost) и Var → Отличная статья
  • Меховщиков Руслана → Проверка имени пользователя на наличие букв из разных алфавитов → Re: Читал про это уже на
  • Вероника → Куба. Лето 2008. Часть 3 → По поводу "приветливых жителей" Тринидада
  • Sfero → Статья в PC Magazine/RE. Drupal: разработка модуля → Немного о контенте
  • RemaGe → Статья в PC Magazine/RE. Drupal: разработка модуля → -)
  • Ромка → Статья в PC Magazine/RE. Drupal: разработка модуля → Да, будет сборка, та которую
  • RemaGe → Статья в PC Magazine/RE. Drupal: разработка модуля → -)
  • anatinge → Поездка в Киев → спасибо :)
  • Ромка → Поездка в Киев → Да, в общем-то, ничего
  • GogA → Поездка в Киев → Заинтриговал, что там за

Новые заметки

  • Кеширование на Drupal-сайте. Сравнение встроенного в Drupal кеша, статического файлового кеша (модуль Boost) и Varnish
  • Любопытное поведение модуля syslog в шестом Друпале (баг?)
  • Arduino + bluetooth, небольшая проблема
  • Гугл 1 марта прекратил поддержку сервиса Google Friend Connect
  • Проба пера в HTML5 + canvas. Эффект ластика
  • Шесть рукопожатий
  • Доклад на DrupalConfMoscow 2011
  • Статусы разных сущностей в Друпале 6
  • Футер, прибитый к низу страницы
  • Путешествие по Перу и Боливии. Часть 2

Тэги

Drupal jquery Куба Лето 2007 Лето 2008 Отдых Работа Штуки-дрюки лето модуль статья цитата
еще тэги

Навигация

  • Exchange rate
  • Переход по внешней ссылке
  • Последние сообщения
  • Фотогалереи

Курсы валют

  • 100 Казахстанских тенге — 21,3687 (-0.43)
  • 10 Украинских гривен — 27,2852 (-13.04)
  • 1 Китайский юань — 10,2706 (-40.98)
  • 100 Японских иен — 53,5332 (+12.67)
  • 1 Доллар США — 65,6210 (+33)
  • 1 Евро — 69,8076 (+29.42)
  • 10000 Белорусских рублей — 36,3310 (-2.51)
  • 1 Турецкая лира — 22,9540 (+4.99)

10 случайных заметок

  • Друпал ограничен только способностями разработчика!
  • С Новым Годом!
  • Любопытное поведение модуля syslog в шестом Друпале (баг?)
  • Автоматическая "газетная" верстка (верстка в несколько колонок)
  • Лето 2007. Путешествие в Камбоджу – Таиланд – Малайзию. Часть 2. Камбоджа, Сиануквилль.
  • Кнопки Home, End и Page Up, Page Down в Mac OS
  • Баг jQuery в Firefox 3 и WebKit
  • Несколько статей о Друпале
  • Поездка в Киев
  • Путешествие по Перу и Боливии. Часть 2

Случайные фото

Радуга над футбольным полем в Лужниках
Тринидадские спортсменчики
Дом, плавающий по морю на больших поплавках
Замок Акерхус вечером
Норвегия, Нордсетер
Я, какой-то дед и местные детишки
Горы
В аэропорту
Просто море
Буквы
Я и мой автопарк :))
Копенгаген, Кристиания, Граффити 3
Пеликан
Автописта
Я и кокос... Где то я это уже видел...
В Сингапурском зоопарке. Попугай
  • Отдых
  • Работа

При использовании материалов с сайта, пожалуйста, ставьте ссылку на источник. E-mail для связи: mne@romka.eu.