Введение
Redis — открытое продвинутое хранилище пар ключ/значение. Его часто называют сервисом структур данных, так как ключи могут содержать строки, хэши, списки, наборы и сортированные наборы.
Чтобы начать использовать Redis с Laravel, необходимо либо установить пакет predis/predis с помощью Composer:
shcomposer require predis/predis
Либо, вы можете установить расширение для PHP PhpRedis через PECL. Расширение сложнее установить, но оно даёт большую производительность для приложений, которые активно используют Redis.
Настройка
Настройки вашего подключения к Redis хранятся в файле config/database.php. В нём вы найдёте массив redis, содержащий список серверов, используемых приложением:
'redis' => [
'client' => 'predis',
'cluster' => false,
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
Значения по умолчанию должны подойти для разработки. Однако вы свободно можете изменять этот массив в зависимости от своего окружения. У каждого сервера Redis, определённого в файле конфигурации, должны быть имя, хост и порт.
Параметр cluster сообщает клиенту Redis Laravel, что нужно выполнить фрагментацию узлов Redis (client-side sharding), что позволит вам обращаться к ним и увеличить доступную RAM. Однако заметьте, что фрагментация не справляется с падениями, поэтому она в основном используется для кэшированных данных, которые доступны из основного источника.
Predis
Помимо стандартных опций настройки сервера host, port, database и password Predis поддерживает дополнительные параметры подключения, которые можно определить для каждого из ваших серверов Redis. Чтобы использовать эти дополнительные опции, просто добавьте их в конфигурацию вашего сервера Redis в файле config/database.php:
conf'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, 'read_write_timeout' => 60, ],
PhpRedis
Если ваше расширение Redis установлено через PECL, вам нужно переименовать псевдоним для Redis в файле config/app.php.
Чтобы использовать расширение PhpRedis, вы должны задать опции client в конфигурации Redis значение phpredis. Эта опция находится в файле config/database.php:
conf'redis' => [ 'client' => 'phpredis', // остальные настройки Redis... ],
Помимо стандартных опций настройки сервера host, port, database и password PhpRedis поддерживает следующие дополнительные параметры подключения: persistent, prefix, read_timeout и timeout. Вы можете добавить любые из этих опций в настройки своего сервера Redis в файле config/database.php:
conf'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, 'read_timeout' => 60, ],
Взаимодействие с Redis
Вы можете взаимодействовать с Redis, вызывая различные методы фасада Redis. Фасад Redis поддерживает динамические методы, а значит вы можете вызвать любую Redis-команду на фасаде, и команда будет передана прямо в Redis. В этом примере мы вызовем Redis-команду GET с помощью вызова метода PHPget()
фасада Redis:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Redis;
//для версии 5.2 и ранее:
//use Redis;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Показать профиль данного пользователя.
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
$user = Redis::get('user:profile:'.$id);
return view('user.profile', ['user' => $user]);
}
}
Как уже было сказано, вы можете вызывать любые Redis-команды фасада Redis. Laravel использует магические методы PHP для передачи команд на сервер Redis, поэтому просто передайте необходимые аргументы Redis-команде:
Redis::set('name', 'Taylor');
$values = Redis::lrange('names', 5, 10);
добавлено в 5.0 ()
Когда у вас есть экземпляр клиента Redis, вы можете выполнить любую команду Redis.
$redis->set('name', 'Taylor');
$name = $redis->get('name');
$values = $redis->lrange('names', 5, 10);
В качестве альтернативы вы можете передавать команды на сервер методом PHPcommand()
, который принимает первым аргументом имя команды, а вторым — массив значений:
$values = Redis::command('lrange', ['name', 5, 10]);
Использование нескольких подключений Redis
Вы можете получить экземпляр Redis методом PHPRedis::connection()
:
$redis = Redis::connection();
Так вы получите экземпляр подключения по умолчанию. Если вы не используете фрагментацию, то можно передать этому методу имя сервера для получения конкретного подключения, как оно определено в файле настроек:
$redis = Redis::connection('other');
Конвейер команд
Конвейер должен использоваться, когда вы отправляете много команд на сервер за одну операцию. Метод PHPpipeline()
принимает один аргумент — замыкание, которое получает экземпляр Redis. Вы можете выполнить все ваши команды на этом экземпляре Redis, и все они будут выполнены в рамках одной операции:
Redis::pipeline(function ($pipe) {
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", $i);
}
});
Издатель/подписчик (Pub/Sub)
Laravel предоставляет удобный интерфейс к Redis-командам publish и subscribe. Эти команды позволяют прослушивать сообщения на заданном «канале». Вы можете публиковать сообщения в канал из другого приложения или даже при помощи другого языка программирования, что обеспечивает простую связь между приложениями и процессами.
Сначала давайте настроим слушатель канала с помощью метода PHPsubscribe()
. Мы поместим вызов этого метода в Artisan-команду, так как вызов метода PHPsubscribe()
запускает длительный процесс:
<?php
namespace App\Console\Commands;
use Illuminate\Support\Facades\Redis;
//для версии 5.2 и ранее:
//use Redis;
use Illuminate\Console\Command;
class RedisSubscribe extends Command
{
/**
* Название и сигнатура терминальной команды.
*
* @var string
*/
protected $signature = 'redis:subscribe';
/**
* Описание терминальной команды.
*
* @var string
*/
protected $description = 'Subscribe to a Redis channel';
/**
* Выполнение терминальной команды.
*
* @return mixed
*/
public function handle()
{
Redis::subscribe(['test-channel'], function ($message) {
echo $message;
});
}
}
Теперь мы можем публиковать сообщения в канал методом PHPpublish()
:
Route::get('publish', function () {
// Логика маршрута...
Redis::publish('test-channel', json_encode(['foo' => 'bar']));
});
С помощью метода PHPpsubscribe()
вы можете подписаться на канал по маске, это может быть полезно для отлова всех сообщений на всех каналах. Название канала PHP$channel
будет передано вторым аргументом в предоставляемый обратный вызов замыкания:
Redis::psubscribe(['*'], function ($message, $channel) {
echo $message;
});
Redis::psubscribe(['users.*'], function ($message, $channel) {
echo $message;
});