Redis в Laravel: варианты настройки проектов
Базовая схема
Для обычного Laravel-проекта на одном Redis-инстансе удобнее разделять данные по назначению: основное подключение, кэш, сессии и очереди. Это не даёт жёсткой изоляции, но сильно упрощает диагностику и очистку отдельных типов данных.
REDIS_DB=0
REDIS_CACHE_DB=1
REDIS_SESSION_DB=2
REDIS_QUEUE_DB=3
Такая схема хорошо читается: 0 — служебные ключи приложения, 1 — кэш, 2 — сессии, 3 — очереди.
Подключения в config/database.php
В стандартном Laravel-конфиге обычно уже есть default и cache. Для отдельных баз под сессии и очереди нужно добавить подключения session и queue в секцию redis.
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'),
'persistent' => env('REDIS_PERSISTENT', false),
],
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
'session' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_SESSION_DB', '2'),
],
'queue' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_QUEUE_DB', '3'),
],
],
REDIS_SESSION_DB и REDIS_QUEUE_DB сами по себе ничего не переключают, пока в конфиге нет подключений, которые их читают.
.env для одного проекта
Для одного проекта без соседних сайтов на том же Redis-инстансе достаточно такой настройки:
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_DB=0
REDIS_CACHE_DB=1
REDIS_SESSION_DB=2
REDIS_QUEUE_DB=3
CACHE_STORE=redis
REDIS_CACHE_CONNECTION=cache
SESSION_DRIVER=redis
SESSION_CONNECTION=session
QUEUE_CONNECTION=redis
REDIS_QUEUE_CONNECTION=queue
REDIS_QUEUE=default
Если Redis защищён паролем:
REDIS_PASSWORD=СЛОЖНЫЙ_ПАРОЛЬ
После изменения .env:
php artisan config:clear
php artisan cache:clear
php artisan config:cache
Несколько сайтов на одном Redis
Когда один Redis-инстанс обслуживает несколько сайтов, я не начинаю нарезать каждому проекту свой набор баз 0/1/2/3, 4/5/6/7 и так далее. Практичнее оставить одинаковую ролевую схему баз и развести проекты по префиксам.
REDIS_PREFIX=my_project_prod_
CACHE_PREFIX=my_project_prod_cache_
SESSION_COOKIE=my_project_prod_session
REDIS_QUEUE=my_project_prod_default
REDIS_PREFIX отделяет Redis-ключи проекта, CACHE_PREFIX отдельно маркирует кэш Laravel, SESSION_COOKIE не даёт браузеру смешивать сессии соседних сайтов, а REDIS_QUEUE разводит имена очередей.
Имена для production
Префикс лучше делать явно: my_project_prod_, my_project_stage_. Короткие app_ и site_ быстро становятся бесполезными, когда проектов больше двух.
Пример для двух сайтов
Shop production
APP_NAME=shop
REDIS_DB=0
REDIS_CACHE_DB=1
REDIS_SESSION_DB=2
REDIS_QUEUE_DB=3
REDIS_PREFIX=shop_prod_
CACHE_PREFIX=shop_prod_cache_
SESSION_COOKIE=shop_prod_session
REDIS_QUEUE=shop_prod_default
CRM production
APP_NAME=crm
REDIS_DB=0
REDIS_CACHE_DB=1
REDIS_SESSION_DB=2
REDIS_QUEUE_DB=3
REDIS_PREFIX=crm_prod_
CACHE_PREFIX=crm_prod_cache_
SESSION_COOKIE=crm_prod_session
REDIS_QUEUE=crm_prod_default
Оба сайта используют одну и ту же ролевую карту баз, но ключи и очереди не пересекаются из-за префиксов.
Когда нужны отдельные Redis-инстансы
Отдельные Redis-инстансы нужны не для красоты конфигов, а для реальной изоляции. Я выношу проект или отдельный тип нагрузки в другой инстанс, когда требуется:
- разная
maxmemory-policyдля кэша и очередей; - отдельный лимит памяти, который не делится с соседними сайтами;
- высокая нагрузка на очереди или кэш;
- жёсткая изоляция между проектами, окружениями или клиентами;
- отдельный мониторинг, бэкапы или права доступа.
Разные Redis DB внутри одного инстанса не дают такой изоляции. Политика памяти, процесс Redis и общий лимит RAM остаются общими.
Проверка
Проверить кэш из Tinker:
php artisan tinker
Cache::put('redis_test', 'ok', 60);
Cache::get('redis_test');
Ожидаемый ответ — "ok".
Посмотреть ключи проекта:
redis-cli SCAN 0 MATCH 'my_project_prod_*'
redis-cli SCAN 0 MATCH 'my_project_prod_cache_*'
Если ключи не находятся, сначала проверяю php artisan config:clear и не остался ли старый кэш конфигурации.
Коротко
Для стандартного проекта: разные Redis DB под роли.
REDIS_DB=0
REDIS_CACHE_DB=1
REDIS_SESSION_DB=2
REDIS_QUEUE_DB=3
Для нескольких сайтов на одном Redis: префиксы и уникальные имена cookie/queue.
REDIS_PREFIX=my_project_prod_
CACHE_PREFIX=my_project_prod_cache_
SESSION_COOKIE=my_project_prod_session
REDIS_QUEUE=my_project_prod_default