1. Home
  2. PHP
  3. Laravel
  4. LaravelでRedisを使う入門編。導入設定と基本的なRedisファサードの使い方(DBキャッシュ)

LaravelでRedisを使う入門編。導入設定と基本的なRedisファサードの使い方(DBキャッシュ)

  • 公開日
  • 更新日
  • カテゴリ:Laravel
  • タグ:PHP,Laravel,cache,Redis
LaravelでRedisを使う入門編。導入設定と基本的なRedisファサードの使い方(DBキャッシュ)

今回は Laravel と Redis を使って、DB キャッシュを行います。

Contents

  1. 開発環境
  2. パッケージの導入
  3. Redis の設定
  4. キャッシュ操作のメソッド
  5. 基本クラス構造
  6. [SET] strings 型データを登録する
  7. [GET] strings 型データを取得する
  8. [GETRANGRE] strings 型データを範囲を指定して取得する
  9. [RPUSH] list 型データを登録する
  10. [LRANGE] 指定した範囲でのリスト型データを取得する
  11. [SADD]set 型のデータを登録する
  12. [SMEMBERS] 狙った KEY の集合を取得する
  13. [ZADD] ソート済みセット型のデータを登録する
  14. [ZRANGE] ソート済みセット型のデータを取得する
  15. [HSET] hash 型データを登録する
  16. [HGETALL] ハッシュ型データから任意の KEY のデータを取得する

開発環境

今回の開発環境は以下の通りです。

  • Linux CentOS 7
  • Redis 4
  • PHP 7.2
  • MySQL 5.7
  • Laravel 5.5

Laravel のバージョンは 5.5 以外にも 5.4, 5.3 であれば同一手順で進めていけます。

Laravel のルートディレクトリを「laravel/」としています。

尚、今回、Redis は構築済みの前提で進めますので、まだの場合は
CentOS に Redis(NoSQL) をインストールして初期設定&デーモン化までを行う
を参考に構築を行ってください。

ちなみに Redis と Laravel は別サーバに立てていて、Redis にはパスワードを設定している状態で構築しています。

パッケージの導入

Laravel で Redis を使うには predis/predis パッケージが必要なので、Composer でインストールします。

# Laravel ルートディレクトリへ移動する
cd /path/to/laravel

# predis/predis パッケージインストールする
composer require predis/predis

# 実行結果
[demo@localhost laravel]# composer require predis/predis
Using version ^1.1 for predis/predis
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing predis/predis (v1.1.1): Downloading (100%)         
predis/predis suggests installing ext-phpiredis (Allows faster serialization and deserialization of the Redis protocol)
Writing lock file
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Package manifest generated successfully.

Redis の設定

Laravel で Redis を使う為の設定を行います。 DB の設定ファイルを以下のように記述します。

laravel/config/database.php
'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),
        'read_write_timeout' => env('REDIS_READ_WRITE_TIMEOUT', 60),
    ],
],

env ファイルに Redis の設定値情報を記述します。

laravel/.env
CACHE_DRIVER=redis
REDIS_HOST=192.168.99.999
REDIS_PASSWORD=your_password
REDIS_PORT=6379
REDIS_DB=0
REDIS_READ_WRITE_TIMEOUT=60

これで、Laravel で Redis を使えるようになりました。

キャッシュ操作のメソッド

それでは実際に Laravel で Redis を使った操作を行っていきます。

Laravel では、Cache ファサードを使って Redis を操作する事が出来ます。これは、Laravel でキャッシュを扱う上で基本となるものですが、今回はそれではなく、Redis ファサードを使って操作を行います。

Cache ファサードは、キャッシュを扱う際にどの方式(ファイルでも DB でも NoSQL でも)を採用しても共通して使えるメソッドが揃っています。

一方、Redis ファサードは Redis 操作のためのクラスであり、Redis コマンドの全てをコールする事が出来ます。

Cache ファサードでの基本的な操作については
Laravel のキャッシュを用いて DB負荷の削減と高速化を行う
を参照ください。

また、Redis ファサードには2種類のメソッドがあり、magic メソッドと command メソッドがあります。

magic メソッド
Redis::set($key, $value);
command メソッド
Redis::command('SET', [$key, $value]);

どちらも同じですが、今回はより汎用性がありわかりやすい command メソッドを使っていきます。

基本クラス構造

ここからはアクション(メソッド)を紹介していくので、その前に基本となるクラス構造を紹介しておきます。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use DB;
use Illuminate\Support\Facades\Redis;

class SampleRedisController extends Controller
{
  protected $table;
  protected $id;

  public function __construct()
  {
    $this->table = 'users';
  }

  /**
   * ここにアクションを記述していく
   */
  public function hoge()
  {
    
  }
}

Redis コマンドを使うので Redis ファサードと、データベースからデータを取得するので DB ファサードを use しています。

以下で紹介するアクションは全て、このクラス構造の中に記述されています。

[SET] strings 型データを登録する

まずは、Redis の基本型となる strings 型でのデータ収容を行います。 Redis コマンドは「SET 」になります。

/**
 * strings型データを登録する
 */
public function set()
{
  $this->id = 6;

  // DBからデータ取得
  $data = json_encode(DB::table($this->table)->select('id', 'name', 'email')->where('id', $this->id)->first());

  // Redisへリスト型として保存する
  Redis::command('SET', [$this->id, $data]);
}

command メソッドの場合は、第一引数に Redis コマンドを渡し、第二引数に KEY と Value を配列でセットします。

セットしたら実際に Redis 側を確認してみます。

"SET" "6" "{\"id\":6,\"name\":\"user06\",\"email\":\"test06@test.com\"}"

データがストアされました。

[GET] strings 型データを取得する

SET でストアしたデータを GET で取得します。

/**
 * strings型データを取得する
 */
public function get()
{
  $this->id = 6;

  $data = json_decode(Redis::command('GET', [$this->id]));
}

文字列型データを取得するので、Resis コマンドである「GET 」と、取得したい KEY を渡します。

stdClass Object
(
    [id] => 6
    [name] => user06
    [email] => test06@test.com
)

ストアした時と同じ形式で取得できました。

[GETRANGRE] strings 型データを範囲を指定して取得する

文字列型は KEY-VALUE の形で収容されるので様々な使い方ができます。例えば今回のようにユーザ情報のようなものだとマッチはしませんが、GETRANGRE で狙った範囲だけを取得する事もできます。

/**
 * strings型データを範囲を指定して取得する
 */
public function getrange()
{
  $data = Redis::command('GETRANGE', [1, 8, 22]);
}

上記の場合、KEY:1 のデータに対して 8 文字目から 22 文字を取得しています。

"name":"user01"

[RPUSH] list 型データを登録する

次に、リスト型でのデータストアを行います。

/**
 * リスト型データを登録する(末尾)
 */
public function rpush()
{
  $this->id = 6;

  // DBからデータ取得
  $data = json_encode(DB::table($this->table)->select('id', 'name', 'email')->where('id', $this->id)->first());

  // Redisへリスト型として保存する
  Redis::command('RPUSH', ['user', $data]);
}

RPUSH で list データの末尾にデータを追加しています。

セットしたら実際に Redis 側を確認してみます。

"RPUSH" "user" "{\"id\":6,\"name\":\"user06\",\"email\":\"test06@test.com\"}"

LIST 型でデータがストアされました。

[LRANGE] 指定した範囲でのリスト型データを取得する

次に、リスト型データに対して、指定した範囲でデータを取得してみます。

/**
 * 指定した範囲でのリスト型データを取得する
 */
public function lrange()
{
  $data = Redis::command('LRANGE', ['user',2,6]);

  $users = array();
  foreach ($data as $d) {
    $users[] = json_decode($d);
  }
}

Redis コマンドの LRANGE で、user キーのリスト 2~ 6 番目のデータを取得しています。

Array
(
    [0] => stdClass Object
        (
            [id] => 2
            [name] => user02
            [email] => user02@test.com
        )

    [1] => stdClass Object
        (
            [id] => 3
            [name] => user03
            [email] => test03@test.com
        )

    [2] => stdClass Object
        (
            [id] => 4
            [name] => user04
            [email] => test04@test.com
        )

    [3] => stdClass Object
        (
            [id] => 5
            [name] => user05
            [email] => test05@test.com
        )

    [4] => stdClass Object
        (
            [id] => 7
            [name] => user07
            [email] => test07@test.com
        )

)

リスト型は特に何もしなければ追加した順でストアされるので、見ての通り value の id自体は順不同です。

[SADD]set 型のデータを登録する

次はセット型です。 set 型は集合を扱うのに便利なデータ型です。

/**
 * セット型のデータを登録する
 */
public function sadd()
{
  $data =[
    "ja" => ["おはよう", "こんにちは", "こんばんは"],
    "en" => ["good morning", "hello", "good evening"]
  ];

  foreach ($data as $key => $value) {
    Redis::command('SADD', [$key, $value]);
  }
}

KEY それぞれ「ja 」「en 」に対しての value 値を配列で収納し、引数「SADD 」共に渡します。

Redis 側を確認してみます。

127.0.0.1:6379> SMEMBERS en
1) "good evening"
2) "hello"
3) "good morning"

セット型としてデータをストアできました。

[SMEMBERS] 狙った KEY の集合を取得する

先ほど追加したセット型のデータから指定した KEY の集合を取得してみます。

/**
 * セット型のデータから指定したKEYの集合を取得する
 */
public function smembers()
{
  $data = Redis::command('SMEMBERS', ['en']);
}

Redis コマンド「SMEMBERS 」と、キーの指定「en 」を渡しています。

Array
(
    [0] => good evening
    [1] => hello
    [2] => good morning
)

キー「en 」の集合を取得できました。

[ZADD] ソート済みセット型のデータを登録する

スコアでソートストアが行えるソート済みセット型でのデータ登録を行います。

/**
 * ソート済みセット型のデータを登録する
 */
public function zadd()
{
  $data = [
    ["score", 100, "user01"],
    ["score", 220, "user03"],
    ["score", 490, "user06"],
    ["score", 160, "user04"],
    ["score", 370, "user10"],
  ];

  foreach ($data as $value) {
    Redis::command('ZADD', $value);
  }
}

キー「score 」に対して、スコア(数値)と value 値(userXX)をセットしています。

] "ZADD" "score" "100" "user01"
] "ZADD" "score" "220" "user03"
] "ZADD" "score" "490" "user06"
] "ZADD" "score" "160" "user04"
] "ZADD" "score" "370" "user10"

登録できていますね。

[ZRANGE] ソート済みセット型のデータを取得する

続いて、セットしたデータを取得します。 ZRANGE でスコア範囲を指定して取得します。

/**
 * ソート済みセット型のデータを取得する
 */
public function zrange()
{
  $data = Redis::command('ZRANGE', ["score", 0, -1, "WITHSCORES"]);
}

第二引数で渡している配列ですが、左から「KEY 」「スコア範囲(start)」「スコア範囲(end)」「スコアも取得」です。(上記の場合は、全て取得するようになっています。)

Array
(
    [user01] => 100
    [user04] => 160
    [user03] => 220
    [user10] => 370
    [user06] => 490
)

スコアを基に並べ替えられているところが、ソート済みセット型の良いところです。

[HSET] hash 型データを登録する

最後に、ハッシュ型としてデータをストアします。

/**
 * ハッシュ型データを登録する
 */
public function hset()
{
  $data = [
    ["user01", "id", 1],
    ["user01", "name", "mitsuha"],
    ["user01", "email", "mitsuha@ritolab.com"],
    ["user02", "id", 2],
    ["user02", "name", "rito"],
    ["user03", "email", "rito@ritolab.com"]
  ];

  foreach ($data as $value) {
    Redis::command('HSET', $value);
  }
}

データは、「親 KEY,子 KEY,VALUE 値」を1組として配列でセットします。

Redis 側を確認してみます。

] "HSET" "user01" "id" "1"
] "HSET" "user01" "name" "mitsuha"
] "HSET" "user01" "email" "mitsuha@ritolab.com"
] "HSET" "user02" "id" "2"
] "HSET" "user02" "name" "rito"
] "HSET" "user03" "email" "rito@ritolab.com"

ハッシュ型でデータがストアされました。

[HGETALL] ハッシュ型データから任意の KEY のデータを取得する

では、登録したハッシュ型データから任意の KEY のデータを取得してみます。

/**
 * ハッシュ型データから任意のKEYのデータを取得する
 */
public function hgetall()
{
  $data = Redis::command('HGETALL', ["user01"]);
}

Redis コマンドの HGETALL と、取得したいキーである「user01 」を渡しています。

Array
(
    [id] => 1
    [name] => mitsuha
    [email] => mitsuha@ritolab.com
)

指定したキーでデータを取得できました。

まとめ

作業は以上で完了です。

引数の渡し方などで参考になりそうなものや基本的なコマンドを選んで紹介しましたが、ここで紹介した Redis コマンドはまだまだ一部です。

とはいえ、Laravel ではこうして Redis ファサードを使う事でコマンドを全て自在に扱えるので便利です。是非試してみてください。

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級