Skip to main content

快取是什麼

資料庫查詢或外部 API 呼叫的 CPU 與網路成本較高,處理時間可能長達數秒。 若需重複取得相同資料,可以將結果儲存在快取中,就能加速後續請求的處理。 Laravel 提供統一的 API,可對應 Memcached、Redis、DynamoDB、資料庫等多種快取後端。
預設會使用 database 驅動。你可以改用 Redis 或 Memcached,以獲得更快的快取效能。

快取設定

config/cache.php

快取的設定集中在 config/cache.php。 可透過 CACHE_STORE 環境變數切換預設的驅動。

可用的驅動

將序列化後的快取資料儲存到資料庫資料表。 Laravel 11 以後的新專案已內建對應 migration。
如果尚未包含 migration,可以透過 Artisan 指令建立。
將快取資料儲存在檔案系統中。 無需額外設定,適合小型應用程式。
以記憶體運作的高速快取驅動。 是正式環境中最常使用的選擇。需要 PhpRedis PHP 擴充或 predis/predis 套件。
需要 Memcached PECL 套件。 請於 config/cache.php 設定伺服器。
使用 AWS DynamoDB 作為快取儲存。 請先建立 DynamoDB 資料表,並安裝 AWS SDK。
使用任意的檔案系統磁碟作為 key/value 快取儲存。 如果想直接使用既有的 S3 磁碟做快取,這相當方便。
array 是只在單次請求中有效的記憶體內快取。 null 則會忽略所有操作。這兩者在自動化測試時都相當實用。

快取驅動的階層結構

依用途與速度不同來選用不同驅動。

基本操作

取得 Cache Facade

透過 Cache Facade 操作快取。
若要切換不同的快取儲存,可以使用 store() 方法。

讀取資料:Cache::get()

透過 get() 方法從快取中讀取資料。 若快取不存在則回傳 null。也可以指定預設值。

儲存資料:Cache::put()

透過 put() 方法將資料存入快取。第 3 個參數指定有效期限(秒)。
也可以透過 add() 方法,只有在快取不存在時才儲存。
若要永久保存,可使用 forever()

讀取或儲存:Cache::remember()

這是最常使用的操作。若快取中已有資料則回傳它,若沒有則執行閉包並儲存其結果。
使用 Cache::remember() 可以將「檢查快取 → 若無則取得 → 存入快取」的 3 個步驟,濃縮成 1 行程式碼。非常適合快取資料庫查詢結果或外部 API 回應。

remember() 的流程

也有永久保存版本 rememberForever()
若想知道是快取「命中」還是透過閉包新取得的,可以使用 rememberWithWarmth() 方法。此方法會以陣列回傳快取值以及一個布林值,表示該值是否為「熱資料」(來自快取)。
rememberWithWarmth() 適合用來監控快取的效率。若 $warm 常常是 false,可能需要調整快取有效期限(TTL)以改善。

Stale While Revalidate(彈性快取更新)

Cache::flexible() 以陣列指定快取的「新鮮期間」與「即使變舊仍可使用的期間」。 此模式會在把舊資料回傳給使用者的同時,於背景更新快取。

存在確認:Cache::has()

值的遞增 / 遞減

可以操作整數計數器。

讀取並刪除:Cache::pull()

讀取後即從快取中刪除。適合管理一次性資料。

刪除資料:Cache::forget()

Cache::flush() 會忽略快取「prefix」設定,刪除所有項目。若多個應用程式共用快取請務必留意。
可以透過 Cache::flushLocks() 清除快取中所有原子鎖。

TTL 延長:Cache::touch()

延長既有快取項目的有效期限。

快取記憶化(Memoization)

使用 memo 驅動可將單一請求內的快取存取暫存於記憶體中。 若同一個 key 常被重複存取,可以減少對快取儲存的往返次數。

快取標籤(Tags)

可以透過標籤將相關的快取項目分組,並一併刪除。
快取標籤無法用於 filedynamodbdatabasestorage 驅動。需要 redismemcached 驅動。

帶標籤快取的結構

被貼上多個標籤的快取項目,可以透過任一標籤一起刪除。

儲存與讀取帶標籤的快取

刪除帶標籤的快取

當你想以使用者、文章等單位為群組進行快取失效時,標籤非常實用。 例如:Cache::tags(['user', "user:{$userId}"])->flush() 可以清除該使用者相關的所有快取。

原子操作(Lock)

透過 Cache::lock() 可以實作分散式鎖,防止多程序或並行請求造成的競態情況。
此功能可用於 memcachedredisdynamodbdatabasefilearray 快取驅動。所有伺服器都必須連線至同一個中央快取伺服器。

基本鎖操作

若傳入閉包,處理完成後會自動釋放鎖。

鎖的等待

在取得鎖之前最多等待指定秒數。若超時則會拋出 LockTimeoutException
使用閉包可以更精簡。

防止重複執行:withoutOverlapping()

一種簡單防止同一處理重複執行的方法。

限制並發數:funnel()

限制可同時執行的處理數。

跨程序傳遞鎖

例如在 Web 請求中取得鎖,並在佇列 job 中釋放它。
若要不論目前持有者為誰皆強制釋放鎖,可以使用 forceRelease 方法。

鎖的重新整理

若要延長目前持有鎖的有效期限,可以使用 refresh 方法。若不指定秒數,會使用取得鎖時原本的有效期限。當長時間處理時想定期延長較短的鎖,就不必一開始就設定極長的有效期限。

快取 Helper

透過 cache() 輔助函式,可以更簡潔地執行與 Cache Facade 相同的操作。

實戰範例

快取資料庫查詢結果

1

在控制器中快取查詢結果

2

資料更新時清除快取

快取 Eloquent 模型

快取 API 回應

用快取標籤管理群組

總結

  • 開發、小型專案filedatabase
  • 正式、高流量redis(結合 Laravel Horizon 也便於監控)
  • AWS 環境dynamodbstorage(想沿用 S3 磁碟時)
  • 測試arraynull
  • 快取 key 命名應在整個應用程式中保持唯一(例:users:1:profile
  • 資料更新後透過 Cache::forget()Cache::tags()->flush() 將快取失效
  • 快取 TTL 不宜過短或過長,應依資料更新頻率調整
  • 使用 Cache::remember() 可以簡潔地寫出快取未命中時的處理
  • 正式環境建議使用 Redis,並考慮設定容錯機制
最後修改於 2026年8月2日