Laravel - Database - Redis (官方文件原子化翻譯筆記)

# 前言

學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。

# Introduction

Laravel 文件上推薦使用 PhpRedis 或 predis?

PhpRedis



# Configuration

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    'redis' => [

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

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

    ],
  • Answer:
    <?php
    'redis' => [

    // 使用的 redis client, 預設 phpredis
    'client' => env('REDIS_CLIENT', 'phpredis'),

    'default' => [
    // host, 預設 127.0.0.1
    'host' => env('REDIS_HOST', '127.0.0.1'),
    // password, 預設 null
    'password' => env('REDIS_PASSWORD', null),
    // port, 預設 6379
    'port' => env('REDIS_PORT', 6379),
    // database, 預設 0
    '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),
    ],

    ],
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    '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',
    ],

    ],
  • Answer:
    預設會需要定義 host, password, port, database, 可用 url 方式定義全部

# Configuring The Connection Scheme

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    'redis' => [

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

    'default' => [
    // 這行意思是?
    'scheme' => 'tls',
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', 6379),
    'database' => env('REDIS_DB', 0),
    ],

    ],
  • Answer:
    預設使用 tcp 方式, 可自訂為 TLS

# Clusters

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    'redis' => [

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

    // 這行意思是?
    'clusters' => [
    'default' => [
    [
    'host' => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', 6379),
    'database' => 0,
    ],
    ],
    ],

    ],

  • Answer:
    如果使用 Redis Cluster 的話, 需定義於 ‘clusters’ 參數之下
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    // 在 config/database.php
    'redis' => [

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

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

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

    ],
    // 在 .env
    REDIS_CLUSTER=redis
  • Answer:
    Laravel 預設 cluster redis 會使用 client-side sharding, 若希望使用 native redis cluster, 可將 options.cluster 的 value 設為 redis

# Predis

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    // 在 config/database.php
    'redis' => [

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

    // Rest of Redis configuration...
    ],
  • Answer:
    指定 redis client, 預設是 phpredis, 若要使用 predis, 需特別指定 env
當使用 Laravel predis 時, 除了以下的預設 setting, 還可以設定額外的 setting 嗎?
  • Example:
    <?php
    'default' => [
    'host' => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', 6379),
    'database' => 0,
    'read_write_timeout' => 60,
    ],
  • Answer:
    可, 官方文件
Laravel 中, 為何在 config/app.php 當中, alias array 中, redis 是被 disable 的?
  • Example:
    <?php
    'Queue' => Illuminate\Support\Facades\Queue::class,
    'Redirect' => Illuminate\Support\Facades\Redirect::class,
    // 'Redis' => Illuminate\Support\Facades\Redis::class,
    'Request' => Illuminate\Support\Facades\Request::class,
    'Response' => Illuminate\Support\Facades\Response::class,
  • Answer:
    因為 Redis alias 會跟 phpredis extension 提供的 class name 衝突, 因此如果使用 phpredis 時是 disable 的, 但如果使用 predis 時, 可以 uncomment

# PhpRedis

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    'redis' => [

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

    // Rest of Redis configuration...
    ],
    // .env
    REDIS_CLIENT=phpredis
  • Answer:
    Laravel 預設使用 Phpredis extension 來跟 Redis 溝通
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    // phpredis
    'default' => [
    'host' => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', 6379),
    'database' => 0,
    'read_timeout' => 60,
    'context' => [
    // 'auth' => ['username', 'secret'],
    // 'stream' => ['verify_peer' => false],
    ],
    ],
  • Answer:
    phpredis 也有提供一些額外的 parameter 可以設定


# Interacting With Redis

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    class UserController extends Controller
    {
    public function show($id)
    {
    return view('user.profile', [
    'user' => Redis::get('user:profile:'.$id)
    ]);
    }
    }
  • Answer:
    使用 redis 的 get command, 取得指定的 key 的 value
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    use Illuminate\Support\Facades\Redis;

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

    $values = Redis::lrange('names', 5, 10);
  • Answer:
    set key / value 為 name / Taylor
    取得 range between 5, 10 的 value, 0 代表第一個位置, 1 代表第二個位置, -1 代表倒數第一個位置, -2 代表倒數第二個位置, 若是超出範圍, 則代表最後一個位置, 比如 總共只有 10 個 item, range 10 會等於第十個位置, range -100 會等於第一個位置

# Pipelining Commands

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $values = Redis::command('lrange', ['name', 5, 10]);
  • Answer:
    使用 command method, 直接 pass command name 給 redis server, 同 Redis::lrange()

# Using Multiple Redis Connections

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $redis = Redis::connection();
    $redis = Redis::connection('connection-name');
  • Answer:
    取得 redis 預設 connection
    取得 redis 指定名為 'connection-name' 的 connection

# Transactions

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    use Illuminate\Support\Facades\Redis;

    Redis::transaction(function ($redis) {
    $redis->incr('user_visits', 1);
    $redis->incr('total_visits', 1);
    });
  • Answer:
    使用 redis 的 transaction feature, 所有的 command 會一次性執行, 所以無法在 transaction 的過程中取值

# Lua Script

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $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');
  • Answer:
    使用 eval 執行 redis script, 既有 transaction 的 atomic 特性, 又可以在過程中可以與 redis 互動
    arg1 為 lua script, arg2 為 key 的數量, arg3 為 key1, arg4 為 key2, 在往後可以帶入任何會在 script 內用到的變數

# Pipelining Commands

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    use Illuminate\Support\Facades\Redis;

    Redis::pipeline(function ($pipe) {
    for ($i = 0; $i < 1000; $i++) {
    $pipe->set("key:$i", $i);
    }
    });
  • Answer:
    當需要執行複數的 redis command 時, 可以使用 pipeline method, 只經由一次的 connection 將多個 command 送到 redis server, closure 內的 command 會按照順序執行
    如果沒使用 pipeline, 多個 command 會建立多次 connection


# Pub / Sub

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Console\Commands;

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

    class RedisSubscribe extends Command
    {
    protected $signature = 'redis:subscribe';

    protected $description = 'Subscribe to a Redis channel';

    public function handle()
    {
    Redis::subscribe(['test-channel'], function ($message) {
    echo $message;
    });
    }
    }

    // in Route
    use Illuminate\Support\Facades\Redis;

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

    Redis::publish('test-channel', json_encode([
    'name' => 'Adam Wathan'
    ]));
    });
  • Answer:
    使用 redis pub/sub feature, 可使用 Laravel subscribe 一個 channel, 而用其他的應用 publish 到這個 channel

# Wildcard Subscriptions

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Redis::psubscribe(['*'], function ($message, $channel) {
    echo $message;
    });

    Redis::psubscribe(['users.*'], function ($message, $channel) {
    echo $message;
    });
  • Answer:
    使用 psubscribe method, 可以 subscribe wildcard channels
Tree 資料結構簡介 Tree 實作 in PHP

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×