Мемоизация кэша в Laravel: Как работает Cache::memo() и зачем он нужен

Как использовать мемоизацию кэша в Laravel для повышения производительности и сокращения сетевых обращений к Redis, Memcached и другим хранилищам.

Даже если вы используете кэш, Laravel каждый раз обращается к внешнему хранилищу. Это может быть Redis или Memcached — и каждый такой запрос может занимать лишние миллисекунды. В больших приложениях это превращается в серьёзную нагрузку.

use Illuminate\Support\Facades\Cache;

Cache::put('name', 'Cherika');
$name = Cache::get('name');

Однако при многократном использовании кэшированного значения в коде всё равно приходится обращаться к хранилищу кэша каждый раз, во время вызова Cache::get(). Это не бесплатно, поскольку, возможно, хранилище кэша находится на другом сервере, и каждый раз, обращаясь к нему, ему приходится совершать сетевой вызов для получения значения.

Драйвер мемоизации

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

use Illuminate\Support\Facades\Cache;

Cache::put('name', 'Cherika');
$name = Cache::get('name'); // Обращается к хранилищу кэша
$name = Cache::get('name'); // Обращается к хранилищу кэша

$name = Cache::memo()->get('name'); // Обращается к хранилищу кэша
$name = Cache::memo()->get('name'); // Не обращается к хранилищу кэша

Как видите, первые два вызова Cache::get() каждый раз обращаются к хранилищу кэша. Но при мемоизации значения кэша с помощью Cache::memo()->get() кэш-хранилище будет задействовано только в первый раз. Второй вызов Cache::memo()->get() извлекает значение из памяти, что гораздо быстрее, чем повторное обращение к хранилищу кэша.

Мемоизированные значения не мутируют

При мемоизации значения оно сохраняется в памяти на время выполнения запроса. Это означает, что если изменить значение в кэш-хранилище, это не повлияет на мемоизированное значение.

use Illuminate\Support\Facades\Cache;

Cache::put('name', 'Cherika');
$name = Cache::memo()->get('name'); // Cherika

Cache::put('name', 'John Doe'); // Изменение значения в хранилище кэша
$name = Cache::memo()->get('name'); // Cherika

Это необходимо для обеспечения консистентности мемоизированного значения на протяжении всего запроса, что важно для производительности и надёжности.

Пользовательский драйвер мемоизации

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

// Драйвер Redis...
Cache::memo('redis')->get('name');

// Драйвер Database...
Cache::memo('database')->get('name');

Каждый драйвер получит уникальный декоратор memo. Это означает, что значения не распределяются между разными драйверами.

Cache::driver('redis')->put('item', 'This is in Redis');
Cache::driver('database')->put('item', 'This is in the database');

Cache::memo('redis')->get('item'); // "This is in Redis"
Cache::memo('database')->get('item'); // "This is in the database"

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

Заключение

Мемоизация кэша в Laravel — это отличный способ повысить производительность и сократить количество сетевых обращений к хранилищу кэша. Используя метод Cache::memo(), можно хранить значения в памяти на время выполнения запроса и не обращаться к хранилищу кэша несколько раз. Это может быть особенно удобно при выполнении ресурсоёмких операций, таких как запросы к базе данных или вызовы API.

Используйте Cache::memo():

Узнайте больше об этой функции в этом PR: [12.x] Introduce memoized cache driver #55304.

Комментарии


Дополнительные материалы

Предыдущая Статья

Что такое this в JavaScript

Следующая Статья

CSS if(): новая функция условной логики доступна в Chrome 137+