Redis
Redis — это высокопроизводительное хранилище данных типа "ключ-значение" с открытым исходным кодом, которое может использоваться как база данных, кэш и брокер сообщений.
Для работы с Redis, вы можете использовать один из двух драйверов:
- PhpRedis (рекомендуется) — PHP-расширение, обеспечивающее лучшую производительность
- Predis — PHP-пакет, устанавливаемый через Composer:
composer require predis/predis
Конфигурирование
Базовая конфигурация Redis соедениений настраивается в файле config/database.php:
'redis' => [
// Выбор клиента: 'phpredis' (по умолчанию) или 'predis'
'client' => env('REDIS_CLIENT', 'phpredis'),
// Глобальные опции для всех подключений
'options' => [
// Режим кластеризации
'cluster' => env('REDIS_CLUSTER', 'redis'),
// Префикс для всех ключей
'prefix' => env('REDIS_PREFIX', 'myapp_database_'),
// Сериализатор (только для PhpRedis)
'serializer' => Redis::SERIALIZER_PHP,
// Сжатие (только для PhpRedis)
'compression' => Redis::COMPRESSION_LZ4,
],
// Основное подключение
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
'timeout' => 5.0, // сек
'retry_interval' => 100, // мс
'persistent' => false,
'persistent_id' => null,
'read_timeout' => 3.0, // только для Predis
],
// Подключение для кэша (отдельная БД)
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
'timeout' => 3.0,
],
],
Работа с кластерами
'redis' => [
'client' => 'phpredis',
'options' => [
'cluster' => 'redis',
'timeout' => 5.0,
'read_timeout' => 3.0,
'failover' => RedisCluster::FAILOVER_ERROR,
'persistent' => false,
],
'clusters' => [
'default' => [
[
'host' => 'redis-node1',
'port' => 6379,
'database' => 0,
'password' => 'secret',
],
[
'host' => 'redis-node2',
'port' => 6379,
'database' => 0,
'password' => 'secret',
],
[
'host' => 'redis-node3',
'port' => 6379,
'database' => 0,
'password' => 'secret',
],
],
],
],
Подключение к Redis
Для получения экземпляра менеджера Redis, используйте соответствующий фасад:
use Imhotep\Facades\Redis;
// Получение подключения по умолчанию (default)
$redis = Redis::connection();
// Получение именованного подключения
$redisCache = Redis::connection('cache');
Взаимодействие с Redis
Фасад Redis за счет поддержки динамических методов, позволяет вызывать любую команду Redis.
Базовые операции
use Imhotep\Facades\Redis;
// SET / GET
Redis::set('user:1:name', 'John Doe');
$name = Redis::get('user:1:name');
// GETSET (установить и получить старое значение)
$oldValue = Redis::getSet('user:1:name', 'Jane Doe');
// EXISTS
if (Redis::exists('user:1:name')) {
// Ключ существует
}
// DEL (удаление)
Redis::del(['user:1:name', 'user:1:email']);
// EXPIRE (установка времени жизни)
Redis::expire('user:1:session', 3600);
// TTL (получение времени жизни)
$ttl = Redis::ttl('user:1:session');
// INCR / DECR (инкремент/декремент)
Redis::incr('counter');
Redis::incrBy('counter', 10);
Redis::decr('counter');
При необходимости, можно передавать прямые команды на сервер Redis, используя метод Redis::command(...), где первым аргументом передается имя команды, а вторым массив параметром:
$values = Redis::command('lrange', ['name', 5, 10]);
// Эквивалентно
$values = Redis::lrange('queue', 5, 10);
Работа со списками
// LPUSH / RPUSH
Redis::lpush('queue', 'task1', 'task2');
Redis::rpush('queue', 'task3');
// LPOP / RPOP
$task = Redis::lpop('queue');
// LRANGE
$tasks = Redis::lrange('queue', 0, -1); // Получить все элементы
Работа с хешами
// HSET / HGET
Redis::hset('user:1', 'name', 'John');
Redis::hset('user:1', 'email', 'john@example.com');
$name = Redis::hget('user:1', 'name');
// HGETALL
$user = Redis::hgetall('user:1');
// HMSET / HMGET
Redis::hmset('user:1', ['age' => 30, 'city' => 'New York']);
$data = Redis::hmget('user:1', ['age', 'city']);
Работа с множествами
// SADD / SMEMBERS
Redis::sadd('tags', 'php', 'laravel', 'redis');
$tags = Redis::smembers('tags');
// SISMEMBER
if (Redis::sismember('tags', 'php')) {
// Тег существует
}
Работа с сортированными множествами
// ZADD
Redis::zadd('leaderboard', 100, 'user:1');
Redis::zadd('leaderboard', 85, 'user:2', 95, 'user:3');
// ZREVRANGE (топ-3)
$top3 = Redis::zrevrange('leaderboard', 0, 2, 'WITHSCORES');
// ZINCRBY
Redis::zincrby('leaderboard', 10, 'user:1');
Публикация/Подписка
// Публикация
Redis::publish('channel:1', 'Hello, World!');
// Подписка (лучше через консольную команду)
Redis::subscribe(['channel:1', 'channel:2'], function($message, $channel) {
echo "Получено сообщение '{$message}' из канала '{$channel}'";
});
Работа с транзакциями
// MULTI / EXEC
Redis::multi();
Redis::set('key1', 'value1');
Redis::set('key2', 'value2');
$result = Redis::exec(); // [true, true]
Lua скрипты
$script = "
local current = redis.call('GET', KEYS[1]) or 0
current = current + ARGV[1]
redis.call('SET', KEYS[1], current)
return current
";
$newValue = Redis::eval($script, 1, 'counter', 5);
Конвейерные операции (Pipeline)
Для повышения производительности при множественных операциях используйте конвейер:
use Imhotep\Facades\Redis;
$results = Redis::pipeline(function($pipe) {
$pipe->set('key1', 'value1');
$pipe->set('key2', 'value2');
$pipe->get('key1');
$pipe->get('key2');
});
События
Каждая выполненная команда генерирует событие Imhotep\Redis\Events\CommandExecuted:
use Imhotep\Facades\Redis;
// Подписка на события
Redis::listen(function($event) {
Log::debug("Выполнена Redis команда: {$event->command}", [
'parameters' => $event->parameters,
'time' => $event->time,
'connection' => $event->connectionName
]);
});
// Отключение событий (для повышения производительности)
Redis::disableEvents();
// Включение событий
Redis::enableEvents();
Макросы
Расширение функциональности через макросы:
use Imhotep\Facades\Redis;
Redis::macro('incrementAndGet', function($key, $by = 1) {
return Redis::incrBy($key, $by);
});
$newValue = Redis::incrementAndGet('counter', 5);