Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Фреймворк Zotonic

Глава 9 из книги "Производительность приложений с открытым исходным кодом".

Оригинал: Zotonic
Авторы: Arjan Scherpenisse и Marc Worrell
Перевод: Н.Ромоданов

Слои кэширования

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

В этом разделе будет послойно сверху вниз описан механизм кэширования, используемый в Zotonic: от браузера и вниз через стек обработки к базе данных.

Кэширование на клиентской стороне

Кэширование на стороне клиента выполняется в браузере. Браузер кэширует изображения, файлы CSS и файлы JavaScript. Zotonic не позволяет на стороне клиента кэшировать страницы HTML, он всегда динамически генерирует все страницы. Поскольку это выполняется очень эффективно (так, как было описано в предыдущем разделе) и страницы HTML не кэшируются, старые страницы не будут показываться после того, как пользователь войдет в систему, выйдет из системы или разместит комментарии.

Zotonic улучшает производительность на стороне клиента следующими двумя способами:

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

Первое достигается путем добавления в запрос соответствующих заголовков HTTP [2]:

Last-Modified: Tue, 18 Dec 2012 20:32:56 GMT
Expires: Sun, 01 Jan 2023 14:55:37 GMT
Date: Thu, 03 Jan 2013 14:55:37 GMT
Cache-Control: public, max-age=315360000

Несколько файлов CSS или JavaScript объединяются в один файл, отдельные файлы разделяются символами тильды, а пути указываются только в том случае, если они у файлов различны:

http://example.org/lib/bootstrap/css/bootstrap
  ~bootstrap-responsive~bootstrap-base-site~
  /css/jquery.loadmask~z.growl~z.modal~site~63523081976.css

Число, указываемое в конце, является отметкой времени создания самого нового файла в списке. Необходимый тег ссылки CSS или скрипта JavaScript генерируется при помощи тега шаблона {% lib %}.

Кэширование на серверной стороне

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

Статические файлы CSS и JS и файлы изображений

Контроллер, обрабатывающий статических файлов, применяет для обработки этих файлов несколько вариантов оптимизаций. Он может преобразовывать запросы комбинированных файлов в списки отдельных файлов.

Контроллер, обрабатывающий состояние HTTP 304 Not Modified (Не изменилось), должен, при необходимости, проверять заголовок If-Modified-Since.

При первом запросе он объединит вместе содержимое всех статических файлов в один массив байтов (двоичный тип binary языка Erlang) [3]. Затем этот массив байтов кэшируется в центральном Деп-кэш (смотрите ниже раздел «Деп-кэш») в двух формах: в сжатом (с помощью gzip) и в несжатом. Zotonic, в зависимости от заголовков Accept-Encoding, отправляемых браузером, будет пользоваться сжатой или несжатой версией.

Этот механизм кэширования достаточно эффективен, так что его производительность аналогична производительности многих кэширующих прокси-серверов, и, в то же время, он полностью контролируется веб-сервером. В ранней версии системы Zotonic и на простых аппаратных средствах (процессор quad core 2.4 GHz Xeon 2008 года) мы получали пропускную способность около 6000 запросов/сек и могли получить насыщение гигабитного соединения ethernet, запрашивающего небольшой файл с изображением (~ 20 KB).

Совместное использование шаблонов при рендеринге

Шаблоны компилируются в модули языка Erlang, после чего байт-код сохраняется в памяти. Откомпилированные шаблоны вызываются как обычные функции языка Erlang.

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

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

Полностью собранный код JavaScript вместе с уникальным идентификатором страницы ID помещается в позицию, где находится тег шаблона {% script %}. Он должен быть непосредственно перед закрывающим тегом тела страницы </body>. Для того, чтобы обеспечить соответствие между данной отображаемой страницей и процессами в Erlang, осуществляющими обработку, а также для реализации через WebSocket/Comet взаимодействия со страницей, используется уникальный идентификатор страницы ID.

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

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

Еще одним методом кэширования частей шаблонов является использование блочного тега {% cache %} ... {% endcache %} который кэширует часть шаблона в течение заданного периода времени. Этот тег имеет те же параметры кэширования, как и тег include, но его преимущество в том, что его можно легко добавить в уже существующие шаблоны.

Кэширование в памяти процесса

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

Для сравнения, доступ к кэш памяти сервера обычно занимает 0,5 миллисекунд. В отличие от этого на доступ к основной памяти в том же самом процессе требуется 1 наносекунда при наличии данных в кэше процессора и 100 наносекунд в случае, если данные не находятся в кэше процессора, не говоря уже об огромном разнице в скорости доступа к памяти и доступе в сеть [4].

Для сравнения, доступ к кэш памяти сервера обычно занимает 0,5 миллисекунд. В отличие от этого на доступ к основной памяти в том же самом процессе требуется 1 наносекунда при наличии данных в кэше процессора и 100 наносекунд в случае, если данные не находятся в кэше процессора, не говоря уже об огромном разнице в скорости доступа к памяти и доступе в сеть [4].

  1. Деп-кэш (depcache) — центральное кэш-хранилище для каждого отдельного сайта
  2. Кэш-память словаря процесса

Продолжение статьи: Деп-кэш.