Інвалідація кешу

Дата оновлення перекладу 2024-05-29

Інвалідація кешу

"В комп'ютерній науці є лише дві складні речі: інвалідація кешу та найменування сутностей." -- Філ Карлтон

Як тільки URL кешовано шлюзовим кешем, кеш більше не проситиме у додатку цього змісту. Це дозволяє кешу надавати швидкі відповіді та скорочує навантаження на ваш застосунок. Однак, ви ризикуєте відправкою застарілого змісту. Виходом з цієї дилеми буде використання довгих життєвих циклів кешу з активним повідомленням шлюзового кешу при зміні змісту. Зворотні проксі зазвичай надають канал для отримання таких повідомлень, частіше за все через спеціальні HTTP-запити.

Caution

Незважаючи на те, що інвалідація кешу потужна, краще її уникати за можливості. Якщо ви не зможете щось інвалідувати, застарілі кеші будуть обслуговуватися потенційно довгий час. Замість цього, використовуйте короткі життєві цикли кешу або модель інвалідації та просто налаштовуйте ваші контролери так, щоб вони виконували дієві перевірки валідації, як пояснюється у .

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

Але іноді вам необхідна ця додаткова потужність, яку ви можете отримати при чіткій інвалідації. Для інвалідації ваш застосунок має виявити, коли зміст змінюється, та повідомляти кешу про видалення URL, які містять ці дані, з кешу.

Tip

Якщо ви хочете використовувати інвалідацію кешу, подивіться на FOSHttpCacheBundle. Цей пакет надає сервіси, щоб допомогти вам з різноманітними концептами інвалідації кешу, а також документує конфігурацію для декількох розповсюджених проксі, що кешують.

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

Ось як ви можете налаштувати Зворотній проксі Symfony для підтримки HTTP-методу PURGE. Спочатку створіть ядро кешування, яке перевизначає invalidate() метод:

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;
    }
}

Потім зареєструйте клас як сервіс, який декорує. http_cache:

1
2
3
4
5
6
7
8
9
10
11
12
13
// src/CacheKernel.php
namespace App;

// ...
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

#[Autoconfigure(bind: ['$surrogate' => '@?esi'])]
#[AsDecorator(decorates: 'http_cache')]
class CacheKernel extends HttpCache
{
    // ...
}

Danger

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

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

У багатьох додатках, одна й та сама частина змісту використовується на різниз сторінках з різними URL. Для таких випадків існують гнучкіші концепти:

  • Бан інвалідує відповіді, які співпадають з регулярними виразами в URL або інших критеріях;
  • Тегування кешу довзоляє вам додавати тег для кожного змісту, який використано у відповіді, щоб ви могли інвалудвати всі URL, що мають певний зміст.