Lang x Lang

Redis

Table of Contents

Introduction

Redis は、 open source であり、高度な keys・value ストアです。 keys がstrings hashes lists sets sorted sets を含むことができるため、しばしば data 構造 server と呼ばれます。

Laravel で Redis を利用する前に、PECL で PhpRedis PHP 拡張機能のインストールと使用をお勧めします。この拡張機能は "user-land" PHP パッケージと比べてインストールが複雑ですが、Redis を頻繁に使用する applications のパフォーマンスが向上する可能性があります。Laravel Sail を利用している場合、この拡張機能はすでに applications の Docker コンテナにインストールされています。

PhpRedis 拡張機能をインストールできない場合は、 Composer を介してpredis/predisパッケージをインストールできます。Predis は、 Redis client で、PHP で全て書かれており、追加の extensions は必要ありません:

composer require predis/predis:^2.0

Configuration

あなたの application の Redis 設定は config/database.php 設定ファイルを通じて設定できます。このファイルの中には、あなたの application が利用する Redis servers を含む redis array が表示されます。

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
    ],

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

    'cache' => [
        'url' => env('REDIS_URL'),
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'username' => env('REDIS_USERNAME'),
        'password' => env('REDIS_PASSWORD'),
        'port' => env('REDIS_PORT', '6379'),
        'database' => env('REDIS_CACHE_DB', '1'),
    ],

],

設定ファイル内で定義された各 Redisserver は、名前、ホスト、ポートを持つことが必須です。ただし、Redis 接続を表す単一の URL を定義する場合を除きます。

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
    ],

    'default' => [
        'url' => 'tcp://127.0.0.1:6379?database=0',
    ],

    'cache' => [
        'url' => 'tls://user:password@127.0.0.1:6380?database=1',
    ],

],

Connection スキームの設定

default では、Redisclients はあなたの Redisservers に接続する際にtcpス key ムを使用します。しかし、TLS / SSL 暗号化を使用するには、Redisservers の設定 array の中でscheme設定 option を指定します。

'default' => [
    'scheme' => 'tls',
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'username' => env('REDIS_USERNAME'),
    'password' => env('REDIS_PASSWORD'),
    'port' => env('REDIS_PORT', '6379'),
    'database' => env('REDIS_DB', '0'),
],

Clusters

あなたの application が Redis サーバーのクラスターを使用している場合、これらのクラスターをあなたの Redis 設定の clusters キー内に定義する必要があります。この設定キーは default では存在しないため、アプリケーションの config/database.php 設定ファイル内で作成する必要があります:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
    ],

    'clusters' => [
        'default' => [
            [
                'url' => env('REDIS_URL'),
                'host' => env('REDIS_HOST', '127.0.0.1'),
                'username' => env('REDIS_USERNAME'),
                'password' => env('REDIS_PASSWORD'),
                'port' => env('REDIS_PORT', '6379'),
                'database' => env('REDIS_DB', '0'),
            ],
        ],
    ],

    // ...
],

default では、options.clusterの設定 value がredisに設定されているため、Laravel はネイティブの Redisclass タリングを使用します。Redisclass タリングは、うまくフェイルオーバーを処理するので、素晴らしい defaultoption です。

Laravel はクライアントサイドのシャーディングもサポートしています。しかし、クライアントサイドのシャーディングは handle フェイルオーバーを行わないため、主に他の primary data ストアから利用可能な一時的なキャッシュされた data に適しています。

もしネイティブの Redis class タリングではなく、client サイドのシャーディングを使用したい場合は、application の config/database.php 設定ファイル内で options.cluster 設定 value を削除することができます:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

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

    // ...
],

Predis

あなたの application が Redis と Predis package を介して対話する場合、REDIS_CLIENT environment 変数の value を predis に設定する必要があります。

'redis' => [

    'client' => env('REDIS_CLIENT', 'predis'),

    // ...
],

default の設定 options に加えて、P connection はそれぞれの Redis server に対して定義されることができる追加の 接続 パラメータ をサポートしています。これらの追加設定 options を利用するには、それらを application の config/database.php 設定ファイル内の Redis server 設定に追加してください:

'default' => [
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'username' => env('REDIS_USERNAME'),
    'password' => env('REDIS_PASSWORD'),
    'port' => env('REDIS_PORT', '6379'),
    'database' => env('REDIS_DB', '0'),
    'read_write_timeout' => 60,
],

PhpRedis

default として、Laravel は PhpRedis 拡張を使用して Redis と通信します。 Laravel が Redis と通信するために使用する client は、redis.client設定 option の value によって決まります。これは通常、REDIS_CLIENT environment variables の value を反映しています。

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    // ...
],

default の設定 options に加えて、Php connection は以下の追加の接続パラメータをサポートしています: namepersistentpersistent_idprefixread_timeoutretry_intervaltimeout、そしてcontext。これらの options を任意でconfig/database.php設定ファイル内の Redis server 設定に追加することができます。

'default' => [
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'username' => env('REDIS_USERNAME'),
    'password' => env('REDIS_PASSWORD'),
    'port' => env('REDIS_PORT', '6379'),
    'database' => env('REDIS_DB', '0'),
    'read_timeout' => 60,
    'context' => [
        // 'auth' => ['username', 'secret'],
        // 'stream' => ['verify_peer' => false],
    ],
],

PhpRedis シリアライゼーションと圧縮

PhpRedis 拡張機能は、さまざまなシリアライザや圧縮アルゴリズムを使用するように設定することも可能です。これらのアルゴリズムは、options array を通じて、あなたの Redis 設定で設定することができます:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
        'serializer' => Redis::SERIALIZER_MSGPACK,
        'compression' => Redis::COMPRESSION_LZ4,
    ],

    // ...
],

現在サポートされているシリアライザには、Redis::SERIALIZER_NONE ( default )、Redis::SERIALIZER_PHPRedis::SERIALIZER_JSONRedis::SERIALIZER_IGBINARY、および Redis::SERIALIZER_MSGPACKが含まれます。

サポートされている圧縮アルゴリズムには、Redis::COMPRESSION_NONE( default )、Redis::COMPRESSION_LZFRedis::COMPRESSION_ZSTD、およびRedis::COMPRESSION_LZ4が含まれます。

Interacting With Redis

Redis facade のさまざまなメソッドを呼び出して、Redis と対話することができます。Redis facade はダイナミックメソッドをサポートしているため、facade 上で任意のRedis command を呼び出すことができ、その command は Redis に直接渡されます。この例では、Redis facade 上でGET method を呼び出して、Redis のget command を呼び出します。

<?php

namespace App\Http\Controllers;

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

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     */
    public function show(string $id): View
    {
        return view('user.profile', [
            'user' => Redis::get('user:profile:'.$id)
        ]);
    }
}

上記の通り、Redisの commands を facade 上で任意に呼び出すことができます。 Laravel は、マジック method を使用して commands を Redisservers に渡します。 Redis command が引数を要求する場合、それらを facade の対応する method に渡すべきです。

use Illuminate\Support\Facades\Redis;

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

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

あるいは、Redisfacade のcommand method を使用して server にコマンドを渡すこともできます。このメソッドでは、最初の引数として command の名前を、2 番目の引数として values の array を受け取ります:

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

複数の Redis コネクションを使用する

あなたのアプリケーションの config/database.php コンフィギュレーションファイルは、複数の Redis コネクション/サーバーを定義することを許可します。特定の Redis connection への connection を Redis ファサードの connection method を使用して取得することができます:

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

default の Redis 接続のインスタンスを取得するためには、追加の引数なしでconnectionmethod`を呼び出すことができます。

$redis = Redis::connection();

Transactions

Redisfacade のtransactionmethod は、Redis のネイティブMULTIおよびEXECcommands の便利なラッパーを提供します。transactionmethod では、引数としてクロージャのみを受け入れます。このクロージャは Redis 接続インスタンスを受け取り、このインスタンスに対して任意の commands を発行することができます。このクロージャ内で発行されたすべての Redis commands は、単一の原子的な transaction で実行されます:

use Redis;
use Illuminate\Support\Facades;

Facades\Redis::transaction(function (Redis $redis) {
    $redis->incr('user_visits', 1);
    $redis->incr('total_visits', 1);
});

WARNING

Redis transaction を定義する際、どのような values も Redis connection から取得できません。忘れないでください、あなたの transaction は single のまま、原子操作として実行され、その操作はすべてのクロージャがコマンドを実行し終えるまで実行されません。

Lua スクリプト

evalmethod は、単一の、アトミックな操作で複数の Redis commands を実行する別の方法を提供します。ただし、evalmethod の利点は、その操作中に Redis キー values と対話し、それを検査できることです。Redis scripts はLua プ log ラミング言語 で書かれています。

eval method は最初は少し怖いかもしれませんが、基本的な例を探って氷を破ることにしましょう。eval method はいくつかの引数を期待します。まず、Luascript( string として)を method に渡すべきです。次に、script が対話する keys の数( integer として)を渡すべきです。三つ目に、それらの keys の名前を渡すべきです。最後に、script 内でアクセスする必要がある他の追加の引数を渡すこともできます。

この例では、カウンターを increment し、その新しい value を確認し、最初のカウンターの value が 5 より大きい場合には 2 つ目のカウンターを increment します。最後に、最初のカウンターの value を返します:

$value = Redis::eval(<<<'LUA'
    local counter = redis.call("incr", KEYS[1])

    if counter > 5 then
        redis.call("incr", KEYS[2])
    end

    return counter
LUA, 2, 'first-counter', 'second-counter');

WARNING

Redis スクリプティングに関する詳しい情報は、Redis のドキュメンテーション をご参照ください。

コマンドのパイプライン化

時々、何十もの Redis コマンドを実行する必要があるかもしれません。それぞれの command ごとにネットワークであなたの Redis サーバーへアクセスする代わりに、pipeline method を使用することができます。pipeline method は 1 つの引数を受け取ります。それは Redis インスタンスを受け取るクロージャーです。すべてのコマンドをこの Redis インスタンスに発行することができ、そしてそれらはすべて同時に Redis サーバーに送信されます。これにより、サーバーへのネットワークアクセスを reduce します。コマンドはそれらが発行された順序で実行され続けます。

use Redis;
use Illuminate\Support\Facades;

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

Pub / Sub

Laravel は、Redis の publish および subscribe commands への便利なインターフェイスを提供します。これらの Redis commands を使うと、特定の "channel" でメッセージを待ち受けることができます。あなたは別の application から、あるいは別のプ log ラミング言語を使って、channel へメッセージを publish することができます。これにより、application と process 間でのコミュニケーションが容易になります。

まず、subscribe method を使用して channel リスナーをセットアップしましょう。subscribe method の呼び出しは長時間実行される process を開始するため、この method 呼び出しをArtisan command内に配置します:

<?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.
     */
    public function handle(): void
    {
        Redis::subscribe(['test-channel'], function (string $message) {
            echo $message;
        });
    }
}

これで、publish method を使用して、 channel にメッセージを publish することができます:

use Illuminate\Support\Facades\Redis;

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

    Redis::publish('test-channel', json_encode([
        'name' => 'Adam Wathan'
    ]));
});

ワイルドカード Subscriptions

psubscribeの method を使用すると、ワイルドカードの channel に subscribe することができます。これは、すべてのチャネルのすべてのメッセージをキャッチするのに役立つかもしれません。 channel の名前は、提供されたクロージャーの第二引数として渡されます:

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

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

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use