Инвалидация кеша

Дата обновления перевода 2023-01-16

Инвалидация кеша

"В компьютерной науке есть только две сложные вещи: инвалидация кеша и именование сущностей." -- Фил Карлтон

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

Caution

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

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

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

Tip

Если вы хотите использовать инвалидацию кеша, посмотрите на FOSHttpCacheBundle. Этот пакет предоставляет сервисы, чтобы помочь вам с разнличными концептами инвалидации кеша, а также документирует конфигурацию для некольких распространённых кеширующих прокси.

Если одно содержимое соответствует одному URL, то хорошо работает модель PURGE. Вы отправляете запрос к кешу прокси с HTTP-методом PURGE (использование слова "PURGE" - это соглашение, технически это может быть любой строкой) вместо GET, и заставляеть прокси-кеш определить это и удалить данные из кеша, вместо того, чтобы обращаться к приложению за ответом.

Вот как вы можете сконфигурировать обратный прокси Symfony (см. HTTP-кеширование), чтобы он поддерживал HTTP-метод PURGE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// src/CacheKernel.php
namespace App;

use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// ...

class CacheKernel extends HttpCache
{
    protected function invalidate(Request $request, bool $catch = false): Response
    {
        if ('PURGE' !== $request->getMethod()) {
            return parent::invalidate($request, $catch);
        }

        if ('127.0.0.1' !== $request->getClientIp()) {
            return new Response(
                'Invalid HTTP method',
                Response::HTTP_BAD_REQUEST
            );
        }

        $response = new Response();
        if ($this->getStore()->purge($request->getUri())) {
            $response->setStatusCode(Response::HTTP_OK, 'Purged');
        } else {
            $response->setStatusCode(Response::HTTP_NOT_FOUND, 'Not found');
        }

        return $response;
    }
}

Caution

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

Очистка заставляет кеш сбросить ресурс во всех его вариантах (в соответствии с заголовком Vary, см. Варьирование ответа для HTTP-кеша). Альтернативой очистке может быть обновление содержимого. Обновление означает, что кеширующий прокси должен удалить весь локальный кеш и получить содержимое снова. Таким образом, новое содержимое уже доступно в кеше. Недостаток обновления заключается в том, что варианты не инвалидируются.

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

  • Запрещение инвалидирует ответы, совпадающие с ргулярными выражениями в URL или других критериях;
  • Тегирование кеша позвляет вам добавлять тег для каждого содержимого, использованного в ответе, чтобы вы могли инвалидировать все URL, имеющие определённое содержимое.