Laravel - Digging Deeper - Cache (官方文件原子化翻譯文件)

# 前言

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



# Configuration

# Driver Prerequisites

# Database

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Schema::create('cache', function ($table) {
    $table->string('key')->unique();
    $table->text('value');
    $table->integer('expiration');
    });
  • Answer:
    當使用的 Cache driver 為 database 時, 需建立 cache table
以下的 Laravel example CLI 的意思是?
  • Example:
    php artisan cache:table
  • Answer:
    當使用的 Cache driver 為 database 時, 需建立 cache table

# Memcached

Laravel 中, 當使用 Memcached 時, 需要安裝套件嗎?

需要 PECL 的 package, 可參考 Stackoverflow, ServerPilot

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    'memcached' => [
    'servers' => [
    [
    'host' => env('MEMCACHED_HOST', '127.0.0.1'),
    // 'host' => '/var/run/memcached/memcached.sock',
    'port' => env('MEMCACHED_PORT', 11211),
    'weight' => 100,
    ],
    ],
    ],
  • Answer:
    當使用 memcached 為 cache driver 時, 可在 config/cache.php 自定義 host, post, weight
    也可以使用 sock

# Redis

Laravel 中, 若要使用 redis, 可安裝哪兩種套件
  • PhpRedis PHP extension via PECL
  • predis/predis via Composer


# Cache Usage

# Obtaining A Cache Instance

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

    namespace App\Http\Controllers;

    use Illuminate\Support\Facades\Cache;

    class UserController extends Controller
    {
    public function index()
    {
    $value = Cache::get('key');

    //
    }
    }
  • Answer:
    使用 Cache::get() 取得 cache 中該 key 的 value

# Accessing Multiple Cache Stores

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = Cache::store('file')->get('foo');

    Cache::store('redis')->put('bar', 'baz', 600); // 10 Minutes
  • Answer:
    Laravel 支援多種 stores, 像是 apc, redis, database, array, memcached, 等等..
    使用 store() 可以指定接下來要使用的 store, 若無指定則使用 default store
    存到 redis cache, key 為 bar, value 為 baz, 有效時間為 600 seconds

Retrieving Items From The Cache

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = Cache::get('key');

    $value = Cache::get('key', 'default');
  • Answer:
    從 default cache 中取得指定 key 的 value, 若無此 key 則回傳 null
    從 default cache 中取得指定 key 的 value, 若無此 key 則回傳 value 'default'
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = Cache::get('key', function () {
    return DB::table(...)->get();
    });
  • Answer:
    從 default cache 中取得指定 key 的 value, 若無此 key 則執行 closure, 並回傳其 return value

# Checking For Item Existence

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    if (Cache::has('key')) {
    //
    }
  • Answer:
    判斷 default cache 中, 該 'key' 是否存在

# Incrementing / Decrementing Values

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::increment('key');
    Cache::increment('key', $amount);
    Cache::decrement('key');
    Cache::decrement('key', $amount);
  • Answer:
    increase 或 decrease 指定 'key' 的 value, arg2 為要 increase / decrease 的量

# Retrieve & Store

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = Cache::remember('users', $seconds, function () {
    return DB::table('users')->get();
    });
  • Answer:
    嘗試從 default cache 中取得 key 'users' 的 value, 若 key 'users' 不存在, 則執行 closure, 取得 closure 的回傳值, 同時將其存到 cache 中, 有效時間為 $seconds
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = Cache::rememberForever('users', function () {
    return DB::table('users')->get();
    });
  • Answer:
    嘗試從 default cache 中取得 key 'users' 的 value, 若 key 'users' 不存在, 則執行 closure, 取得 closure 的回傳值, 同時將其存到 cache 中, 沒有失效期限

# Retrieve & Delete

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = Cache::pull('key');
  • Answer:
    嘗試從 default cache 中取得 key 'key' 的 value, 並將此 key / value 從 cache 中清除, 若 key 'users' 不存在, 則回傳 null

# Storing Items In The Cache

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::put('key', 'value', $seconds = 10);
  • Answer:
    在 default cache 中存入 key / value, 有效期限為 10 秒, 如果 $seconds 未定義, 將會無限期儲存
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::put('key', 'value', now()->addMinutes(10));
  • Answer:
    在 default cache 中存入 key / value, 有效期限為從現在往後算起的十分鐘後, 若 arg3 未指定, 將會無限期儲存

# Store If Not Present

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::add('key', 'value', $seconds);
  • Answer:
    如果 key 在 default cache 中不存在, 則新增 key / value / 有效時間, 如果真的有新增, 會回傳 true, 否則 false

# Storing Items Forever

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::forever('key', 'value');
  • Answer:
    在 default cache 內新增一筆 key / value, 有效時間為永久, 但如果 Memcached driver, 當達到 size limit, 可能會刪除 forever 檔案

# Removing Items From The Cache

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::forget('key');
  • Answer:
    從 default cache 內移除 key 為 'key' 這筆資料
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::put('key', 'value', 0);

    Cache::put('key', 'value', -5);
  • Answer:
    當指定有效期限為 負數 時, 也有刪除的效果
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::flush();
  • Answer:
    刪除整個 default cache 的資料, 不會因為 prefix 而有所區隔, 會刪除整個 cache 內的資料

# The Cache Helper

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = cache('key');
  • Answer:
    使用 cache function 取得 default cache 中指定的 key 的 value
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    cache(['key' => 'value'], $seconds);

    cache(['key' => 'value'], now()->addMinutes(10));
  • Answer:
    使用 cache function, 當提供完整的參數: key / value / 有效時間, 會將此參數儲存到 default cache
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    cache()->remember('users', $seconds, function () {
    return DB::table('users')->get();
    });
  • Answer:
    使用 cache function, 當沒有帶入 args 時, 會回傳一個 Illuminate\Contracts\Cache\Factory instance
    試圖取出 key 為 users 的 value, 若不存在, 執行 closure, 並將 closure 回傳值存到 default cache 當中, 有效期限為 $seconds


# Cache Tags

Laravel Cache 中, Cache Tags 不支援哪幾種 driver?

file, dynamodb, database


# Storing Tagged Cache Items

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::tags(['people', 'artists'])->put('John', $john, $seconds);

    Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);
  • Answer:
    在 default cache 中存入 key John, value $john, 有效期限 seconds, 並 tag 這筆資料 ['people', 'artists']

# Accessing Tagged Cache Items

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $john = Cache::tags(['people', 'artists'])->get('John');

    $anne = Cache::tags(['people', 'authors'])->get('Anne');
  • Answer:
    從 default cache 中取得 key John, tags ['people', 'artists'] 的資料

# Removing Tagged Cache Items

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::tags(['people', 'artists'])->put('John', $john, $seconds);

    Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);

    Cache::tags(['people', 'authors'])->flush();
  • Answer:
    移除有著 tags people, authors 的 cache items, 所以 John 跟 Anne 都會被移除
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::tags(['people', 'artists'])->put('John', $john, $seconds);

    Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);

    Cache::tags('authors')->flush();
  • Answer:
    移除有著 tags authors 的 cache items, 所以 Anne 會被移除, John 不會

# Atomic Locks

# Driver Prerequisites

# Database

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Schema::create('cache_locks', function ($table) {
    $table->string('key')->primary();
    $table->string('owner');
    $table->integer('expiration');
    });
  • Answer:
    當欲使用 Cache Lock, 且 driver 為 database 時, 需要新增 cache lock 用的 table

# Managing Locks

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $lock = Cache::lock('foo', 10);

    if ($lock->get()) {
    // Lock acquired for 10 seconds...

    $lock->release();
    }
  • Answer:
    使用 Cache Lock, 將 key foo lock 10 秒後釋放, 這 10 秒內可以執行一些邏輯, 比如 transaction, 以避免 race condition
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::lock('foo')->get(function () {
    // Lock acquired indefinitely and automatically released...
    });
  • Answer:
    取得 default cache 中的 foo 並 lock 該 key, 然後執行 closure, 執行完後自動 release 該 lock
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    use Illuminate\Contracts\Cache\LockTimeoutException;

    $lock = Cache::lock('foo', 10);

    try {
    $lock->block(5);

    // Lock acquired after waiting maximum of 5 seconds...
    } catch (LockTimeoutException $e) {
    // Unable to acquire lock...
    } finally {
    optional($lock)->release();
    }
  • Answer:
    嘗試取得 default cache 內的 key foo 並 lock 10 秒, 如果 key 不可得, 會持續嘗試 5 秒, 若 5 秒過了仍然無法取得該 key, 會 throw LockTimeoutException, 如果有取得 lock, 執行完定義的邏輯後, 會 release 該 lock
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Cache::lock('foo', 10)->block(5, function () {
    // Lock acquired after waiting maximum of 5 seconds...
    });
  • Answer:
    嘗試取得 default cache 中的 key foo 並 lock 10 秒, 如果 key 正被 lock 中, 會持續嘗試 5 秒取得 key, 若 5 秒仍沒取得, 會 throw LockTimeoutException, 若取得則會執行 closure, closure 執行完後會 release 該 key

# Managing Locks Across Processes

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $podcast = Podcast::find($id);

    $lock = Cache::lock('processing', 120);

    if ($result = $lock->get()) {
    ProcessPodcast::dispatch($podcast, $lock->owner());
    }

    // job hander 當中
    Cache::restoreLock('processing', $this->owner)->release();
    Cache::lock('processing')->forceRelease();
  • Answer:
    取得 key 為 processing 的 lock 之後, 鎖住 120 秒, 然後將 $lock->owner() pass 到一個 job 當中, 之後可以在該 job 當中透過 lock owner release 該 lock, 或強制 release 該 lock
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Extensions;

    use Illuminate\Contracts\Cache\Store;

    class MongoStore implements Store
    {
    public function get($key) {}
    public function many(array $keys) {}
    public function put($key, $value, $seconds) {}
    public function putMany(array $values, $seconds) {}
    public function increment($key, $value = 1) {}
    public function decrement($key, $value = 1) {}
    public function forever($key, $value) {}
    public function forget($key) {}
    public function flush() {}
    public function getPrefix() {}
    }
  • Answer:
    透過 implement Illuminate\Contracts\Cache\Store, 可自定義一個 Cache Store, 可參考 MemcachedStore 的 source code
Laravel 中, 當我使用一個 extended Store 時, 可將自定義的 cache driver class 放在哪?

可放在 app\Extensions 資料夾中, 不過這只是官方建議, 實際上放哪都行


# Registering The Driver

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

    namespace App\Providers;

    use App\Extensions\MongoStore;
    use Illuminate\Support\Facades\Cache;
    use Illuminate\Support\ServiceProvider;

    class CacheServiceProvider extends ServiceProvider
    {
    public function register()
    {
    $this->app->booting(function () {
    Cache::extend('mongo', function ($app) {
    return Cache::repository(new MongoStore);
    });
    });
    }

    public function boot()
    {
    //
    }
    }
  • Answer:
    在 AppServiceProvider 的 register() 中, 註冊自定義的 cache store, extend() 的 arg1 為 store name, arg2 為 closure, 必須 return 一個 Illuminate\Cache\Repository instance
    註冊成功後就可以到 config/cache.php 修改 driver name

Events

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $listen = [
    'Illuminate\Cache\Events\CacheHit' => [
    'App\Listeners\LogCacheHit',
    ],

    'Illuminate\Cache\Events\CacheMissed' => [
    'App\Listeners\LogCacheMissed',
    ],

    'Illuminate\Cache\Events\KeyForgotten' => [
    'App\Listeners\LogKeyForgotten',
    ],

    'Illuminate\Cache\Events\KeyWritten' => [
    'App\Listeners\LogKeyWritten',
    ],
    ];
  • Answer:
    各種預設的 Cache Events
    CacheHit: 當嘗試取得 cache 而有成功取得
    CacheMissed: 當嘗試取得 Cache 而沒取得, 透過 closure 取得的不算有取得, 所以一樣算 missed
    KeyForgotten: 使用 cache:forget()
    keyWritten: 成功寫入 cache
Recursion (遞迴) - 不同類型的遞迴 架設一個 NFS Server

留言

Your browser is out-of-date!

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

×