Глава 4. Массивно масштабируемое кэширование содержания

Введение

Кэширование ускоряет обслуживание содержимого сохраняя отклики запросов для обслуживания ими в последующем. Кэширование содержимого снижает нагрузку на серверы восходящего потока, сохраняя в кэше весь отклик целиком вместо того чтобы проводить вычисления и запросы вновь для в точности такого же запроса. Кэширование увеличивает производительность и снижает нагрузку, что означает что вы способны выполнять обслуживание быстрее, причём меньшими ресурсами. Масштабирование и распределение серверов кэширования в стратегических местоположениях может оказывать впечатляющее воздействие на практику пользователей. Для достижения наилучшей производительности оптимальным является размещение содержимого как можно ближе к самому потребителю. Вы также можете выполнять кэширование поближе к всоим пользователям. Именно это и является основным шаблоном для сетевых сред доставки содержимого, или CDN (content delivery networks). При помощи NGINX у вас есть возможность кэшировать ваше содержимое всякий раз когда вы можете поместить некий сервер NGINX, что действенным образом позволяет вам создавать свою собственную CDN. При помощи кэширования NGINX вы также имеете возможность осуществлять пассивное кэширование и обслуживать отклики кэширования в случае отказа восходящего потока.

Зоны кэширования

Задача

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

Решение

Воспользуйтесь директивой proxy_cache_path для определения разделяемой памяти зон кэширования и местоположения для их содержимого:


proxy_cache_path /var/nginx/cache
                 keys_zone=CACHE:60m
                 levels=1:2
                 inactive=3h
                 max_size=20g;
                 proxy_cache CACHE;
 	   

Данный пример определения кэширования создаёт некий каталог для кэшируемых откликов в вашей файловой системе по адресу /var/nginx/cache и создаёт некое пространство совместно используемой памяти с названием CACHE и объёмом в 60 Мегабайт. Этот пример устанавливает уровни структуры даннго каталога, определяет значение высвобождения кэшированных откликов после того как они были запрошены в 3 часа и задаёт максимальный размер этого кэша в 20 Гигабайт. имеющаяся директива proxy_cache информирует некий определённый контекст для применения в данной зоне кэширования. Директива proxy_cache_path допустима в контексте HTTP, а директива proxy_cache допустима в контекстах HTTP? server и location.

Обсуждение

Для настройки кэширования в NGINX необходимо объявить для применения некие путь и зону. Зона кэширования в NGINX создаётся при помощи соответствующей директивы proxy_cache_path. Эта директива proxy_cache_path назначает некое местоположение для хранения всей кэшируемой информации и некое пространство совместно используемой памяти для хранения активных ключей и метаданных отклика. Необязательные параметры для данной директивы предоставляют дополнительный контроль над тем как данный кэш сопровождается и как к нему осуществляется доступ. Значение параметра levels определяет как создаётся необходимая файловая структура. Его значение представляется разделяемыми двоеточиями величинами, которые определяют значение длины названий подкаталогов при максимальном значении в три уровня. NGINX выполняет кэширование на основе значения ключа кэширования, который является неким хэшируемым значением. Затем NGINX сохраняет полученный результат в производимой файловой структуре при помощи полученного ключа хэша в качестве некого пути файла и рабивает каталоги на основе установленного значения levels. Значение параметра inactive позоляет упралять продолжительностью времени некого кэшированного элемента, которое он будет размещаться после своего последнего использования. Значение размера самого кэша также настраивается при помощи величины параметра max_size. Прочие параметры относятся к процессу загрузки кэша, который загружает ключи кэша в зону общей памяти из кэшированных на диске файлов.

Хэш ключи кэширования

Задача

Вам требуется контролировать тем как ваше содержимое кэшируется и отыскивается.

Решение

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


proxy_cache_key "$host$request_uri $cookie_user";
 	   

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

Обсуждение

Устанавливаемым по умолчанию значением proxy_cache_key, которое удовлетворяет большинству вариантов применения, является "$scheme$proxy_host$request_uri". Эти используемые переменные содержат значения схемы, HTTP или HTTPS, значение proxy_host, куда отправляется данный запрос и сам URI запроса. Всё это вместе отражает тот URL, на который NGINX отправляет данный запрос. Вы можете обнаружить, что существует множество прочих сторон, которые определяют некую идентичность запроса для приложения, например, параметры, заголовки, идентификаторы сеанса запроса и тому подобное, для которых вы бы хотели создавать свой собственный ключ хэша. (В виде некого ключа хэша могут быть использованы любые комбинации текста или выставляемых в NGINX переменных. Перечень переменных доступен в NGINX).

Выбор хорошего ключа хэша очень важен и должен приниматься на основе понимания самого приложения. Выбор некого ключа кэширования статического содержимого обычно достаточно прямолинеен; вполне достаточно применение значения имени хоста и URIю Выбор ключа кэширования для должным образом динамичного содержимого такого как страницы некого приложения инструментальной панели требует больших знаний о том как пользователи взаимодействуют с самим приложением и значение степени вариативности между практиками пользователей. Исходя из соображений безопасности вы можете пожелать не представлять кэшированные для одного из пользователей данные другому без полного понимания их содержания. Данная директива proxy_cache_key настраивает значение строки, выступающей в виде хэша для ключа кэширования. Значение proxy_cache_key может быть настроено в контексте блоков HTTP, server и location, предоставляя гибкое управление над тем как выполняется кэширование запросов.

Обход кэширования

Задача

Вам необходима возможность обхода имеющегося кэширования.

Решение

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


proxy_cache_bypass $http_cache_bypass;
 	   

Данная конфигурация сообщает NGINX обходить имеющийся кэш если значение заголовка в запросе HTTP с названием cache_bypass установлено в любое отличное от 0 значение.

Обсуждение

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

По множеству причин вы можете пожелать обходить установленное кэширование. Одной из важнейших является выявление неисправности и отладка. Повторение проблем может быть тяжёлой задачей если вы непрерывно доставляете кэшированные страницы или если ваши ключи кэша являются особыми для идентификатора пользователя. Имея возможность обхода установленного кэширования жизненно важно. Варианты этого включают в себя, обход кэша при установленных определённых куки, заголовках или параметрах запроса, но не ограничены ими. Вы также имеете возможность отключать полностьб кэширование для заданного контекста, например блока location устанавливая roxy_cache off;.

Производительность кэширования

Задача

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

Решение

Применяйте заголовки управления кэшированием стороны клиента:


location ~* \.(css|js)$ {
  expires 1y;
  add_header Cache-Control "public";
}
 	   

данный блок location определяет что его клиент может кэшировать получаемое содержимое файлов CSS и JavaScript. Установленная директива expires указывает такому клиенту что его ресурс кэширования будет иметь допустимой длительность не более одного года. Директивва add_header добавляет в свой отклик значение заголовка отклика HTTP Cache-Control с неким значением public, которое позволяет любому выполняющему кэширование серверу по его пути осуществлять кэширование данного ресурса. Если предписывается pri‐vate, кэшировать это значение разрешается только самому клиенту.

Обсуждение

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

Продувка

Задача

Вам необходимо отменить действие кэширования для некого объекта.

Решение

Воспользуйтесь свойством продувки (purge) NGINX Plus, а именно директивой proxy_cache_purge, с не пустой или не нулевой переменной:


map $request_method $purge_method {
    PURGE 1;
    default 0;
}
server {
    ...
    location / {
        ...
        proxy_cache_purge $purge_method;
    }
}
 	   

В данном примере значение кэша для некого определённого объекта будет продуто если он запрашивается с методом PURGE. Ниже приводится образец некого curl для продувки значения кэша файла с названием main.js:


$ curl -XPURGE localhost/main.js
		

Обсуждение

Распространённым способом обработки статических файлов является помещение некого хэша такого файла со значением имени файла. Это гарантирует вам что когда вы раскрутите новый код и содержимое, ваш CDN распознает его как новый файл по причине изменения значения URI. Однако это не обязательно работает для динамического содержимого, для которого вы настроили ключи кэширования и которые на удовлетворяют такой модели. NGINX Plus предоставил простой метод продувки кэшированных откликов Его директива proxy_cache_purge, будучи установленной в не пустое или не нулевое значение, продует те кэшированные значения, которые соответствуют данному запросу. Неким простейшим способом продувки является установленный в соответствие данному запросу метод для PURGE. Однако вы можете пожелать применять его совместно с установленным модулем geo_ip, либо просто выполнять аутентификацию чтобы гарантировать что ни кто угодно может продувать ваши предварительно кэшированные элементы. NGINX также допускает применение *, что выполнит продувку всех элементов кэширования, которые соответствуют некому общему префиксу URI. Для использования групповых символов вам понадобится настроить свою директиву proxy_cache_path соответствующим параметром purger=on.

Расслоение кэширования

Задача

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

Решение

Воспользуйтесь директивой slice и её встроенными переменными для разделения получаемого результата кэширования на фрагменты:


proxy_cache_path /tmp/mycache keys_zone=mycache:10m;
server {
    ...
    proxy_cache mycache;
    slice 1m;
    proxy_cache_key $host$uri$is_args$args$slice_range;
    proxy_set_header Range $slice_range;
    proxy_http_version 1.1;
    proxy_cache_valid 200 206 1h;

    location / {
        proxy_pass http://origin:80;
    }
}
 	   

Обсуждение

Данная настройка определяет некую зону кэширования и разрешает её для данного сервера. Хатем применяется установленная директива slice чтобы указать NGINX на необходимость расщепления получаемого отклика на сегменты файла по 1 МБ. Эти файлы кэша сохраняются в соответствии с имеющейся директивой proxy_cache_key. Обратите внимание на применение встроенной переменной с названием slice_range. Та же самая переменная применяется в качестве некого заголовка при выполнении запроса к его первоисточнику и версия этого запроса обновляется до HTTP/1.1, так как 1.0 не поддерживает запросы с диапазоном в байтах. Значение срока действия кэширования устанавливается на один час для кодов отклика 200 или 206, а затем определяются местоположение и происхождение.

Модуль Cache Slice был разработан для доставки видео HTML5, которое использует запросы диапазона в байтах для содержимого псевдопотока к своему браузеру. По умолчанию NGINX способен обслуживать из своего кэша запросы с диапазоном в байтах. Если некий запрос для диапазона в байтах выполнен для не кэшированного содержимого, NGINX запрашивает этот файл целиком у первоисточника. Когда вы применяете обсуждаемый модуль Cache Slice, NGINX запрашивает у этого первоисточника только необходимые ему сегменты. Запросы диапазона превышающие установленный размер нарезки, в том числе весь файл целиком, включают подзапросы для каждого требующегося сегмента, а затем эти сегменты кэшируются. После того как кэшированы все сегменты, данный запрос собирается и отправляется своему клиенту, что позволяет NGINX более действенно кэшировать и обслуживать запрашиваемое содержимое диапазонами. Данный модуль Cache Slice следует применять только для больших файлов, которые не изменяются. NGINX проверяет значение ETag всякий раз когда он получает от своего первоисточника некий фрагмент. Если значение ETag от его первоисточника изменено, NGINX прерывает весь обмен, так как имеющийся кэш более не верен. Если изменилось само содержимое и данный файл меньше, либо ваш первоисточник способен обрабатывать всплески активности в процессе наполнения кэша, будет лучше применять тот модуль Cache Lock, который описывается в блоге, приводимом в следующем разделе Также ознакомьтесь.

Также ознакомьтесь

Smart and Efficient Byte-Range Caching with NGINX & NGINX Plus