キャッシュとは
データベースへの問い合わせや外部APIの呼び出しは、CPUやネットワークのコストが高く、処理に数秒かかることがあります。 同じデータを何度も取得する場合、結果をキャッシュに保存しておくことで、次回以降のリクエストを高速に処理できます。 Laravelは Memcached、Redis、DynamoDB、データベースなど、さまざまなキャッシュバックエンドに対応した統一されたAPIを提供しています。デフォルトでは
database ドライバが設定されています。Redis や Memcached に切り替えることで、さらに高速なキャッシュを実現できます。キャッシュの設定
config/cache.php
キャッシュの設定はconfig/cache.php に集約されています。
CACHE_STORE 環境変数でデフォルトのドライバを切り替えます。
利用可能なドライバ
database(デフォルト)
database(デフォルト)
シリアライズされたキャッシュデータをデータベーステーブルに保存します。
Laravel 11以降の新規プロジェクトには最初からマイグレーションが含まれています。マイグレーションが含まれていない場合は Artisan コマンドで作成します。
file
file
キャッシュデータをファイルシステムに保存します。
追加のセットアップは不要で、小規模なアプリケーションに向いています。
redis
redis
インメモリで動作する高速なキャッシュドライバです。
本番環境で最もよく使われます。PhpRedis PHP 拡張または
predis/predis パッケージが必要です。memcached
memcached
Memcached PECL パッケージが必要です。
config/cache.php でサーバーを設定します。dynamodb
dynamodb
AWS DynamoDB をキャッシュストアとして使います。
事前に DynamoDB テーブルを作成し、AWS SDK をインストールします。
storage
storage
任意のファイルシステムディスクをキー/バリューのキャッシュストアとして使います。
既存のS3ディスクをそのままキャッシュに使いたい場合に便利です。
array / null(テスト用)
array / null(テスト用)
array はリクエスト内でのみ有効なインメモリキャッシュです。
null はすべての操作を無視します。どちらも自動テストで便利です。キャッシュドライバーの階層構造
用途や速度に応じてドライバを使い分けます。基本的な操作
Cache ファサードの取得
Cache ファサードを使ってキャッシュを操作します。
store() メソッドを使います。
データの取得: Cache::get()
get() メソッドでキャッシュからデータを取得します。
キャッシュが存在しない場合は null を返します。デフォルト値を指定することもできます。
データの保存: Cache::put()
put() メソッドでデータをキャッシュに保存します。第3引数に有効期限(秒)を指定します。
add() メソッドもあります。
forever() を使います。
取得または保存: Cache::remember()
最もよく使われる操作です。キャッシュにデータが存在すればそれを返し、なければクロージャを実行してその結果を保存します。
remember() のフロー
永続保存バージョンのrememberForever() もあります。
rememberWithWarmth() メソッドを使用します。このメソッドはキャッシュ値とそれが新鮮(キャッシュから取得)かどうかを示す真偽値を配列で返します。
Stale While Revalidate(柔軟なキャッシュ更新)
Cache::flexible() はキャッシュが「新鮮な期間」と「古くなっても使える期間」を配列で指定します。
古くなったデータをユーザーに返しながら、バックグラウンドでキャッシュを更新するパターンです。
存在確認: Cache::has()
値のインクリメント / デクリメント
整数値のカウンターを操作できます。取得と削除: Cache::pull()
取得後にキャッシュから削除します。ワンタイムデータの管理に便利です。
データの削除: Cache::forget()
Cache::flushLocks() を使うとキャッシュ内のすべてのアトミックロックをクリアできます。
TTL の延長: Cache::touch()
既存のキャッシュアイテムの有効期限を延長します。
キャッシュメモ化
memo ドライバを使うと、同一リクエスト内でのキャッシュアクセスをメモリにキャッシュします。
同じキーへの繰り返しアクセスが多い場合に、キャッシュストアへのラウンドトリップを削減できます。
キャッシュタグ
関連するキャッシュアイテムをタグでグループ化し、まとめて削除できます。タグ付きキャッシュの構造
複数のタグを付けたキャッシュアイテムは、いずれかのタグでまとめて削除できます。タグ付きキャッシュの保存と取得
タグ付きキャッシュの削除
アトミック操作(ロック)
Cache::lock() を使うと分散ロックを実装でき、複数のプロセスや並列リクエストからの競合状態を防ぎます。
この機能は
memcached、redis、dynamodb、database、file、array キャッシュドライバで利用できます。すべてのサーバーが同じ中央キャッシュサーバーと通信している必要があります。基本的なロック
ロック待機
ロックが取得できるまで最大で指定秒数待機します。タイムアウトするとLockTimeoutException が投げられます。
重複実行の防止: withoutOverlapping()
同一処理の多重実行を防ぐシンプルな方法です。
同時実行数の制限: funnel()
同時に実行できる処理数を制限します。
プロセス間でのロック引き渡し
Webリクエストでロックを取得し、キュージョブで解放するケースです。forceRelease メソッドを使います。
ロックのリフレッシュ
現在保持しているロックの有効期限を延長するにはrefresh メソッドを使います。秒数を指定しない場合はロック取得時の元の有効期限が使われます。長時間処理で短いロックを定期的に延長したい場合に便利で、最初から非常に長い有効期限を設定する必要がなくなります。
キャッシュヘルパー
cache() ヘルパー関数を使うと、Cache ファサードと同じ操作をよりシンプルに書けます。
実践例
データベースクエリ結果のキャッシュ
1
コントローラでクエリ結果をキャッシュする
2
データが更新されたらキャッシュを削除する
Eloquent モデルのキャッシュ
APIレスポンスのキャッシュ
キャッシュタグを使ったグループ管理
まとめ
ドライバの選び方
ドライバの選び方
- 開発・小規模:
fileまたはdatabase - 本番・高トラフィック:
redis(Laravel Horizon と組み合わせると監視も容易) - AWS 環境:
dynamodbまたはstorage(S3ディスクを流用する場合) - テスト:
arrayまたはnull