Документация Laravel 10.x
Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.
Redis - это открытое программное обеспечение для создания распределенного хранилища данных. Его часто называют сервером структурированных данных, поскольку ключи могут содержать строки, хэши, списки, множества и сортированные множества.
Перед использованием Redis в Laravel мы рекомендуем установить и использовать расширение PHP phpredis через PECL. Установка этого расширения сложнее по сравнению с "user-land" PHP-пакетами, но она может обеспечить лучшую производительность для приложений, которые часто используют Redis. Если вы используете Laravel Sail, это расширение уже установлено в контейнере Docker вашего приложения.
Если вы не можете установить расширение phpredis, вы можете установить пакет predis/predis
с помощью Composer. Predis - это клиент Redis, написанный исключительно на PHP и не требует дополнительных расширений:
composer require predis/predis
Вы можете настроить настройки Redis вашего приложения с помощью файла конфигурации config/database.php
. В этом файле вы увидите массив redis
, содержащий серверы Redis, используемые вашим приложением:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), '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), ], ],
Каждый сервер Redis, определенный в вашем файле конфигурации, обязан иметь имя, хост и порт, если вы не определите единственный URL для представления соединения с Redis:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'default' => [ 'url' => 'tcp://127.0.0.1:6379?database=0', ], 'cache' => [ ], ],
По умолчанию клиенты Redis будут использовать схему tcp
при подключении к вашим серверам Redis; однако вы можете использовать шифрование TLS / SSL, указав параметр конфигурации scheme
в массиве конфигурации сервера Redis:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'default' => [ 'scheme' => 'tls', 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DB', 0), ], ],
Если ваше приложение использует кластер серверов Redis, вы должны определить эти кластеры в ключе clusters
вашей конфигурации Redis. Этот ключ конфигурации не существует по умолчанию, поэтому вам нужно создать его в файле конфигурации вашего приложения config/database.php
:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'clusters' => [ 'default' => [ [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => 0, ], ], ], ],
По умолчанию кластеры выполнят разделение данных на стороне клиента среди ваших узлов, что позволяет объединять узлы и создавать большое количество доступной оперативной памяти. Однако разделение данных на стороне клиента не обрабатывает сбои; поэтому оно в основном подходит для временных кешированных данных, доступных из другого основного источника данных.
Если вы хотите использовать нативное кластерное разделение Redis вместо разделения данных на стороне клиента, вы можете указать это, установив значение options.cluster
в redis
в файле конфигурации вашего приложения config/database.php
:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), ], 'clusters' => [ // ... ], ],
Если вы хотите, чтобы ваше приложение взаимодействовало с Redis с использованием пакета Predis, убедитесь, что значение переменной окружения REDIS_CLIENT
равно predis
:
'redis' => [ 'client' => env('REDIS_CLIENT', 'predis'), // ...],
Помимо опций конфигурации сервера по умолчанию, таких как host
, port
, database
и password
, Predis поддерживает дополнительные параметры соединения, которые могут быть определены для каждого из ваших серверов Redis. Чтобы использовать эти дополнительные параметры конфигурации, добавьте их в конфигурацию вашего сервера Redis в файле конфигурации вашего приложения config/database.php
:
'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => 0, 'read_write_timeout' => 60,],
Файл конфигурации Laravel config/app.php
содержит массив aliases
, который определяет все псевдонимы классов, которые будут зарегистрированы фреймворком. По умолчанию ни один псевдоним Redis
не включен, потому что это может конфликтовать с именем класса Redis
, предоставляемым расширением phpredis. Если вы используете клиент Predis и хотите добавить псевдоним Redis
, вы можете добавить его в массив aliases
в файле конфигурации вашего приложения config/app.php
:
'aliases' => Facade::defaultAliases()->merge([ 'Redis' => Illuminate\Support\Facades\Redis::class,])->toArray(),
По умолчанию Laravel будет использовать расширение phpredis для связи с Redis. Клиент, который Laravel будет использовать для связи с Redis, определяется значением опции конфигурации redis.client
, которая обычно отражает значение переменной окружения REDIS_CLIENT
:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), // Остальная конфигурация Redis...],
Помимо опций конфигурации сервера по умолчанию, таких как scheme
, host
, port
, database
и password
, phpredis поддерживает следующие дополнительные параметры соединения: name
, persistent
, persistent_id
, prefix
, read_timeout
, retry_interval
, timeout
и context
. Вы можете добавить любой из этих параметров в конфигурацию вашего сервера Redis в файле конфигурации config/database.php
:
'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => 0, 'read_timeout' => 60, 'context' => [ // 'auth' => ['username', 'secret'], // 'stream' => ['verify_peer' => false], ],],
Расширение phpredis также может быть настроено для использования различных алгоритмов сериализации и сжатия. Эти алгоритмы могут быть настроены с использованием массива options
в вашей конфигурации Redis:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'serializer' => Redis::SERIALIZER_MSGPACK, 'compression' => Redis::COMPRESSION_LZ4, ], // Остальная конфигурация Redis...],
В настоящее время поддерживаются следующие алгоритмы сериализации: Redis::SERIALIZER_NONE
(по умолчанию), Redis::SERIALIZER_PHP
, Redis::SERIALIZER_JSON
, Redis::SERIALIZER_IGBINARY
и Redis::SERIALIZER_MSGPACK
.
Поддерживаются следующие алгоритмы сжатия: Redis::COMPRESSION_NONE
(по умолчанию), Redis::COMPRESSION_LZF
, Redis::COMPRESSION_ZSTD
и Redis::COMPRESSION_LZ4
.
Вы можете взаимодействовать с Redis, вызывая различные методы на фасаде Redis
. Фасад Redis
поддерживает динамические методы, что означает, что вы можете вызывать любую команду Redis на фасаде, и команда будет передана непосредственно в Redis. В этом примере мы вызовем команду Redis GET
, вызвав метод get
на фасаде Redis
:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use Illuminate\Support\Facades\Redis;use Illuminate\View\View; class UserController extends Controller{ /** * Показать профиль для указанного пользователя. */ public function show(string $id): View { return view('user.profile', [ 'user' => Redis::get('user:profile:'.$id) ]); }}
Как упоминалось выше, вы можете вызывать любые команды Redis на фасаде Redis
. Laravel использует магические методы для передачи команд серверу Redis. Если команда Redis ожидает аргументы, вы должны передать их соответствующему методу фасада:
use Illuminate\Support\Facades\Redis; Redis::set('name', 'Taylor'); $values = Redis::lrange('names', 5, 10);
Кроме того, вы можете передавать команды серверу, используя метод command
фасада Redis
, который принимает имя команды в качестве первого аргумента и массив значений в качестве второго аргумента:
$values = Redis::command('lrange', ['name', 5, 10]);
Файл конфигурации вашего приложения config/database.php
позволяет вам определить несколько соединений/серверов Redis. Вы можете получить соединение с определенным сервером Redis, используя метод connection
фасада Redis
:
$redis = Redis::connection('connection-name');
Чтобы получить экземпляр соединения с сервером Redis по умолчанию, вы можете вызвать метод connection
без дополнительных аргументов:
$redis = Redis::connection();
Метод transaction
фасада Redis
предоставляет удобную обертку вокруг нативных команд MULTI
и EXEC
Redis. Метод transaction
принимает замыкание в качестве единственного аргумента. Это замыкание получит экземпляр соединения Redis и может выполнять любые команды на этом экземпляре. Все команды Redis, выпущенные внутри замыкания, будут выполнены в единственной, атомарной транзакции:
use Redis;use Illuminate\Support\Facades; Facades\Redis::transaction(function (Redis $redis) { $redis->incr('user_visits', 1); $redis->incr('total_visits', 1);});
Внимание При определении транзакции Redis вы не можете извлекать значения из соединения Redis. Помните, что ваша транзакция выполняется как единая, атомарная операция, и эта операция не выполняется, пока ваше замыкание не закончит выполнение своих команд.
Метод eval
предоставляет еще один способ выполнения нескольких команд Redis в единой, атомарной операции. Однако метод eval
имеет преимущество в том, что он может взаимодействовать и проверять значения ключей Redis во время этой операции. Скрипты Redis написаны на языке программирования Lua.
Метод eval
может показаться сложным сначала, но мы рассмотрим базовый пример, чтобы снять напряжение. Метод eval
ожидает несколько аргументов. Во-первых, вы должны передать скрипт Lua (в виде строки) методу. Во-вторых, вы должны передать количество ключей (в виде целого числа), с которыми взаимодействует скрипт. В-третьих, вы должны передать имена этих ключей. Наконец, вы можете передать любые другие дополнительные аргументы, которые вам нужны для доступа в вашем скрипте.
В этом примере мы увеличим счетчик, проверим его новое значение и увеличим второй счетчик, если значение первого счетчика больше пяти. Наконец, мы вернем значение первого счетчика:
$value = Redis::eval(<<<'LUA' local counter = redis.call("incr", KEYS[1]) if counter > 5 then redis.call("incr", KEYS[2]) end return counterLUA, 2, 'first-counter', 'second-counter');
Внимание Пожалуйста, ознакомьтесь с документацией Redis для получения дополнительной информации о скриптах Redis.
Иногда вам может потребоваться выполнить десятки команд Redis. Вместо того чтобы делать сетевой запрос к вашему серверу Redis для каждой команды, вы можете использовать метод pipeline
. Метод pipeline
принимает один аргумент: замыкание, которое получает экземпляр Redis. Вы можете выполнять все свои команды на этом экземпляре Redis, и все они будут отправлены на сервер Redis одновременно для уменьшения сетевых запросов к серверу. Команды будут выполнены в том порядке, в котором они были выпущены:
use Redis;use Illuminate\Support\Facades; Facades\Redis::pipeline(function (Redis $pipe) { for ($i = 0; $i < 1000; $i++) { $pipe->set("key:$i", $i); }});
Laravel предоставляет удобный интерфейс для команд Redis publish
и subscribe
. Эти команды Redis позволяют прослушивать сообщения на заданном «канале». Вы можете отправлять сообщения на канал из другого приложения или даже с использованием другого языка программирования, обеспечивая легкую связь между приложениями и процессами.
Сначала давайте настроим прослушиватель канала с использованием метода subscribe
. Мы поместим вызов этого метода в команду Artisan, поскольку вызов метода subscribe
начинает долгий процесс:
<?php namespace App\Console\Commands; use Illuminate\Console\Command;use Illuminate\Support\Facades\Redis; class RedisSubscribe extends Command{ /** * Имя и сигнатура консольной команды. * * @var string */ protected $signature = 'redis:subscribe'; /** * Описание консольной команды. * * @var string */ protected $description = 'Subscribe to a Redis channel'; /** * Выполнить консольную команду. */ public function handle(): void { Redis::subscribe(['test-channel'], function (string $message) { echo $message; }); }}
Теперь мы можем отправлять сообщения на канал с использованием метода publish
:
use Illuminate\Support\Facades\Redis; Route::get('/publish', function () { // ... Redis::publish('test-channel', json_encode([ 'name' => 'Adam Wathan' ]));});
С использованием метода psubscribe
вы можете подписаться на канал с использованием подстановочных символов, что может быть полезно для перехвата всех сообщений на всех каналах. Имя канала будет передано вторым аргументом в предоставленное замыкание:
Redis::psubscribe(['*'], function (string $message, string $channel) { echo $message;}); Redis::psubscribe(['users.*'], function (string $message, string $channel) { echo $message;});