Unetway

Laravel - Redis

Вступление

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

Перед использованием Redis с Laravel вам необходимо установить пакет через Composer:predis/predis

composer require predis/predis

Кроме того, вы можете установить PHP-расширение PhpRedis через PECL. Расширение сложнее в установке, но может дать лучшую производительность для приложений, которые интенсивно используют Redis.

 

Конфигурация

Конфигурация Redis для вашего приложения находится в файле конфигурации. В этом файле вы увидите массив, содержащий серверы Redis, используемые вашим приложением:config/database.phpredis

'redis' => [

    'client' => 'predis',

    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => env('REDIS_DB', 0),
    ],

    '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),
    ],

],

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

Конфигурирование кластеров

Если ваше приложение использует кластер серверов Redis, вы должны определить эти кластеры в clustersключе вашей конфигурации Redis:

'redis' => [

    'client' => 'predis',

    'clusters' => [
        'default' => [
            [
                'host' => env('REDIS_HOST', 'localhost'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_PORT', 6379),
                'database' => 0,
            ],
        ],
    ],

],

По умолчанию кластеры выполняют сегментирование на стороне клиента для всех узлов, что позволяет вам объединять узлы и создавать большой объем доступной оперативной памяти. Однако обратите внимание, что сегментирование на стороне клиента не обрабатывает аварийное переключение; следовательно, в первую очередь подходит для кэшированных данных, доступных из другого основного хранилища данных. Если вы хотите использовать собственную кластеризацию Redis, вы должны указать это в optionsключе вашей конфигурации Redis:

'redis' => [

    'client' => 'predis',

    'options' => [
        'cluster' => 'redis',
    ],

    'clusters' => [
        // ...
    ],

],

 

Predis

В дополнение к по умолчанию на hostportdatabaseи passwordпараметры конфигурации сервера, Predis поддерживает дополнительные параметры соединения , которые могут быть определены для каждого из ваших серверов Redis. Чтобы использовать эти дополнительные параметры конфигурации, добавьте их в конфигурацию сервера Redis в файле конфигурации:config/database.php

'default' => [
    'host' => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', 6379),
    'database' => 0,
    'read_write_timeout' => 60,
],

 

PhpRedis

Чтобы использовать расширение PhpRedis, вы должны изменить clientпараметр конфигурации Redis на phpredis. Эта опция находится в вашем файле конфигурации:config/database.php

'redis' => [

    'client' => 'phpredis',

    // Rest of Redis configuration...
],

В дополнение к по умолчанию на hostportdatabaseи passwordпараметры конфигурации сервера, PhpRedis поддерживает следующие дополнительные параметры соединения: persistentprefixread_timeoutи timeout. Вы можете добавить любой из этих параметров в конфигурацию вашего сервера Redis в файле конфигурации:config/database.php

'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, вызывая getметод на Redisфасаде:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        $user = Redis::get('user:profile:'.$id);

        return view('user.profile', ['user' => $user]);
    }
}

Как упоминалось выше, вы можете вызвать любую из команд Redis на Redisфасаде. Laravel использует магические методы для передачи команд серверу Redis, поэтому передайте аргументы, которые ожидает команда Redis:

Redis::set('name', 'Taylor');

$values = Redis::lrange('names', 5, 10);

В качестве альтернативы вы также можете передавать команды серверу, используя commandметод, который принимает имя команды в качестве первого аргумента и массив значений в качестве второго аргумента:

$values = Redis::command('lrange', ['name', 5, 10]);

Использование нескольких подключений Redis

Вы можете получить экземпляр Redis, вызвав метод:Redis::connection

$redis = Redis::connection();

Это даст вам экземпляр сервера Redis по умолчанию. Вы также можете передать имя соединения или кластера connectionметоду, чтобы получить конкретный сервер или кластер, как определено в вашей конфигурации Redis:

$redis = Redis::connection('my-connection');

 

Конвейерные команды

Конвейерная обработка должна использоваться, когда вам нужно отправить много команд на сервер за одну операцию. pipelineМетод принимает один аргумент: Closureкоторый получает экземпляр Redis. Вы можете выдать все свои команды этому экземпляру Redis, и все они будут выполнены в рамках одной операции:

Redis::pipeline(function ($pipe) {
    for ($i = 0; $i < 1000; $i++) {
        $pipe->set("key:$i", $i);
    }
});

 

Pub / Sub

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
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'redis:subscribe';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Subscribe to a Redis channel';

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        Redis::subscribe(['test-channel'], function ($message) {
            echo $message;
        });
    }
}

Теперь мы можем публиковать сообщения на канале, используя publishметод:

Route::get('publish', function () {
    // Route logic...

    Redis::publish('test-channel', json_encode(['foo' => 'bar']));
});

Подстановочные Подписки

Используя этот psubscribeметод, вы можете подписаться на подстановочный канал, который может быть полезен для перехвата всех сообщений на всех каналах. $channelИмя будет передано в качестве второго аргумента в функцию обратного вызова Closure:

Redis::psubscribe(['*'], function ($message, $channel) {
    echo $message;
});

Redis::psubscribe(['users.*'], function ($message, $channel) {
    echo $message;
});