Laravel 9.x Redis

イントロダクション

Redisは、オープンソースの高度なキー/値保存域です。文字列, ハッシュ, リスト, セット, and ソート済みセット.を含めることができるため、データ構造サーバと呼ばれることがあります。

LaravelでRedisを使い始める前に、PECLによりphpredisPHP拡張機能をインストールして使用することを推奨します。この拡張機能は、「ユーザーフレンドリー」なPHPパッケージに比べてインストールは複雑ですが、Redisを多用するアプリケーションのパフォーマンスが向上する可能性があります。Laravel Sailを使用している場合、この拡張機能はアプリケーションのDockerコンテナにはじめからインストールしてあります。

phpredis拡張機能をインストールできない場合は、Composerを介してpredis/predisパッケージをインストールしてください。PredisはすべてPHPで記述されたRedisクライアントであり、追加の拡張機能は必要ありません。

composer require predis/predis

設定

config/database.php設定ファイルによりアプリケーションのRedis設定を設定します。このファイル内に、アプリケーションで使用する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サーバは、Redis接続を表す単一のURLを定義しない限り、名前、ホスト、およびポートを指定する必要があります。

'redis' => [

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

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

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

],

接続スキームの構成

RedisクライアントはRedisサーバへ接続するとき、デフォルトでtcpスキームを使用します。しかし、Redisサーバの設定配列でscheme設定オプションを指定すれば、TLS/SSL暗号化を使用できます。

'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サーバのクラスタを利用する場合は、Redis設定のclustersキー内で使用するクラスタを定義してください。この設定キーはデフォルトでは存在しないため、アプリケーションの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,
            ],
        ],
    ],

],

デフォルトでクラスタは、クライアント側のシャーディングをノード間で実行し、ノードをプールして大量の利用可能なRAMを作成できるようにします。ただし、クライアント側のシャーディングはフェイルオーバーを処理しません。したがって、これは主に、別のプライマリデータストアから利用できる一時的にキャッシュされたデータに適しています。

クライアント側のシャーディングの代わりにネイティブなRedisクラスタリングを使用する場合は、アプリケーションのconfig/database.php設定ファイル内でoptions.cluster設定値をredisに設定してください。

'redis' => [

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

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
    ],

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

],

Predis

アプリケーションがPredisパッケージを介してRedisを操作するようにする場合は、REDIS_CLIENT環境変数の値を確実にpredisへ設定してください。

'redis' => [

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

    // ...
],

デフォルトのhostportdatabasepasswordサーバ設定オプションに加えて、PredisはRedisサーバごとに追加の接続パラメータ定義をサポートしますアプリケーションのconfig/database.php設定ファイルのRedisサーバ設定でそれらを追加してください。

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

Redisファサードのエイリアス

Laravelのconfig/app.php設定ファイルにはaliases配列があり、フレームワークが登録するすべてのクラスエイリアスを定義しています。デフォルトで、Redisのエイリアスは含まれていません。なぜなら、phpredis拡張モジュールが提供するRedisクラス名と衝突してしまうからです。Predisクライアントを使用していて、Redisのエイリアスを追加したい場合は、アプリケーションのconfig/app.php設定ファイル内のaliases配列へ追加してください。

'aliases' => Facade::defaultAliases()->merge([
    'Redis' => Illuminate\Support\Facades\Redis::class,
])->toArray(),

phpredis

デフォルトでは、Laravelはphpredis拡張機能を使用してRedisと通信します。LaravelがRedisとの通信に使用するクライアントは、redis.client設定オプションの値で決まります。これは通常、REDIS_CLIENT環境変数の値を反映します。

'redis' => [

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

    // 残りのRedis設定…
],

デフォルトのschemehostportdatabasepasswordサーバ設定オプションに加えて、phpredisは次の追加の接続パラメータをサポートしています。namepersistentpersistent_idprefixread_timeouttry_intervaltimeoutcontextです。config/database.php設定ファイルのRedisサーバ設定へ、こうしたオプションを追加指定できます。

'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のシリアライズと圧縮

phpredis拡張モジュールは、様々なシリアライズや圧縮アルゴリズムも設定できます。これらのアルゴリズムは、Redis設定のoptions配列で指定します。

'redis' => [

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

    'options' => [
        'serializer' => Redis::SERIALIZER_MSGPACK,
        'compression' => Redis::COMPRESSION_LZ4,
    ],

    // 残りのRedis設定…
],

現在サポートしているシリアライズアルゴリズムは、Redis::SERIALIZER_NONE(デフォルト)、Redis::SERIALIZER_PHPRedis::SERIALIZER_JSONRedis::SERIALIZER_IGBINARYRedis::SERIALIZER_MSGPACKです。

サポートする圧縮アルゴリズムは、Redis::COMPRESSION_NONE(デフォルト)、Redis::COMPRESSION_LZFRedis::COMPRESSION_ZSTDRedis::COMPRESSION_LZ4です。

Redisの操作

Redisファサードでさまざまなメソッドを呼び出すことで、Redisを操作できます。Redisファサードは動的メソッドをサポートしています。つまり、ファサードでRedisコマンドを呼び出すと、コマンドが直接Redisに渡されます。この例では、Redisファサードでgetメソッドを呼び出すことにより、RedisのGETコマンドを呼び出しています。

<?php

namespace App\Http\Controllers;

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

class UserController extends Controller
{
    /**
     * 指定ユーザーのプロファイル表示
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        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);

または、Redisファサードのcommandメソッドを使用してサーバにコマンドを渡すこともできます。このメソッドは、コマンドの名前を最初の引数、値の配列を2番目の引数に取ります。

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

複数のRedis接続の使用

アプリケーションのconfig/database.php設定ファイルでは、複数のRedis接続/サーバが定義できます。Redisファサードのconnectionメソッドを使用して、特定のRedis接続への接続を取得できます。

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

デフォルトのRedis接続のインスタンスを取得するには、引数なしでconnectionメソッドを呼び出してください。

$redis = Redis::connection();

トランザクション

Redisファサードのtransactionメソッドは、RedisのネイティブMULTIおよびEXECコマンドの便利なラッパーを提供します。transactionメソッドは、唯一の引数にクロージャを取ります。このクロージャはRedis接続インスタンスを受け取り、このインスタンスで必要なコマンドを発行できます。クロージャ内で発行したすべてのRedisコマンドは、単一のアトミックトランザクションとして実行します。

use Illuminate\Support\Facades\Redis;

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

Warning!! Redisトランザクションを定義する場合、Redis接続から値を取得できません。トランザクションは単一のアトミック操作として実行し、クロージャ全体がコマンドの実行を完了するまで、操作は実行されないことに注意してください。

Luaスクリプト

evalメソッドは、単一のアトミック操作で複数のRedisコマンドを実行する別のメソッドです。ただし、evalメソッドには、その操作中にRedisキー/値を対話し調べられる利点があります。Redisスクリプトは、Luaプログラミング言語で記述します。

evalメソッドは最初は少し怖いかもしれませんが、壁を超えるために基本的な例を見てみましょう。evalメソッドは引数をいくつか取ります。まず、Luaスクリプトを(文字列として)メソッドへ渡す必要があります。次に、スクリプトが操作するキーの数を(整数として)渡す必要があります。第三に、それらのキーの名前を渡す必要があります。最後に、スクリプト内でアクセスする必要があるその他の追加の引数を渡します。

この例では、カウンターを増分し、その新しい値を検査し、最初のカウンターの値が5より大きい場合は、2番目のカウンターを増分します。最後に、最初のカウンターの値を返します。

$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コマンドを実行する必要が起きることもあるでしょう。毎コマンドごとにRedisサーバへネットワークトリップする代わりに、pipelineメソッドを使用できます。pipelineメソッドは、Redisインスタンスを受け取るクロージャを1つ引数に取ります。このRedisインスタンスですべてのコマンドを発行すると、サーバへのネットワークトリップを減らすため、すべてのコマンドを一度にRedisサーバへ送信します。コマンドは、発行した順序で実行されます。

use Illuminate\Support\Facades\Redis;

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

Pub/Sub

Laravelは、Redisのpublishおよびsubscribeコマンドへの便利なインターフェイスを提供しています。これらのRedisコマンドを使用すると、特定の「チャンネル」でメッセージをリッスンできます。別のアプリケーションから、または別のプログラミング言語を使用してメッセージをチャンネルに公開し、アプリケーションとプロセス間の簡単な通信を可能にすることができます。

まず、subscribeメソッドを使用してチャンネルリスナを設定しましょう。subscribeメソッドを呼び出すとプロセスは長時間実行され続けるため、このメソッド呼び出しはArtisanコマンド内に配置します。

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class RedisSubscribe extends Command
{
    /**
     * consoleコマンドの名前と使用方法
     *
     * @var string
     */
    protected $signature = 'redis:subscribe';

    /**
     * コンソールコマンドの説明
     *
     * @var string
     */
    protected $description = 'Subscribe to a Redis channel';

    /**
     * consoleコマンドの実行
     *
     * @return mixed
     */
    public function handle()
    {
        Redis::subscribe(['test-channel'], function ($message) {
            echo $message;
        });
    }
}

これで、publishメソッドを使用してチャンネルへメッセージを発行できます。

use Illuminate\Support\Facades\Redis;

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

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

ワイルドカードサブスクリプション

psubscribeメソッドを使用すると、ワイルドカードチャンネルをサブスクライブできます。これは、すべてのチャンネルのすべてのメッセージをキャッチするのに役立ちます。チャンネル名は、引数に渡たすクロージャの2番目の引数へ渡されます。

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

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

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる