Redisを効率的なマルチレイヤーキャッシュとして構成する

信頼性の高いマルチレイヤーキャッシュのために、Redisのキャッシュメモリ制限、削除ポリシー、TTL、永続化の選択肢を設定します。

Redisを効率的なマルチレイヤーキャッシュとして構成する

Redisは動作データをメモリに保持するため高速ですが、管理されていないキャッシュはホストを満たし、書き込みに失敗する原因となります。アプリと低速なデータベースの間でRedisをマルチレイヤーキャッシュとして使用する場合、重要な決定事項はメモリ制限、削除ポリシー、TTLの規律、そしてキャッシュデータを永続化するかどうかです。

このガイドでは、プライマリデータストレージではなく、キャッシュワークロードのためのRedis設定に焦点を当てます。

Redisキャッシュレイヤーの理解

多くのアプリケーション設計では、Redisはより小さなインプロセスキャッシュの背後にある共有キャッシュです。アプリはミリ秒単位で少数のホットな値をローカルに保持し、Redisは秒または分単位でより大きな再利用可能なオブジェクトのセットを保存します。これにより、Redisはトラフィックが急増したときにデータベースを保護するレイヤーとなります。

効率的な設定は、以下の2つのコア領域にかかっています。

  1. メモリ管理: Redisが消費できるメモリにハードリミットを設定すること。
  2. 削除ポリシー: メモリ制限に達したときに、Redisがどのキーを削除するかを決定する方法。

1. 安定性のためのメモリ制限の設定

Redisが利用可能なシステムメモリをすべて消費するのを防ぐことは、ホストの安定性にとって最も重要です。maxmemoryディレクティブは、データセットに割り当てられるメモリの絶対的な上限を設定します(オーバーヘッドを除く)。この制限に達すると、Redisは設定されたポリシーに基づいてキーの削除を開始します。

設定ディレクティブ: maxmemory

この設定は本番環境では非常に重要です。一般的なベストプラクティスは、オペレーティングシステムのタスクやRedisのオーバーヘッド(内部データ構造、レプリケーションバッファなど)のためにある程度の余裕を残すことです。

設定例 (redis.conf):

# 最大メモリ使用量を4ギガバイトに設定
maxmemory 4gb

ヒント: 設定管理を容易にするために、常に人間が読みやすい接尾辞(例:100mb2gb)を使用してください。

メモリポリシーの適用

maxmemoryが設定され、maxmemory-policynoevictionのままの場合、制限に達すると、より多くのメモリを必要とするコマンドが失敗する可能性があります。キャッシュの場合は、通常のキャッシュ書き込みを拒否する代わりに、Redisが古いキャッシュエントリを破棄できる削除ポリシーを選択してください。

2. 適切な削除ポリシーの選択 (maxmemory-policy)

このディレクティブは、メモリ制限を超えたときにRedisがどのキーを削除するかを選択するために使用するアルゴリズムを定義します。適切なポリシーの選択は、アプリケーションデータのアクセスパターンに大きく依存します。

揮発性ポリシーと非揮発性ポリシー

ポリシーは一般に、キーに設定されたTime-To-Live(TTL)の有効期限を考慮するかどうかに基づいて分類されます。

  • 揮発性: 有効期限が設定されたキーのみを考慮します(EXPIREまたはSETEX)。
  • すべてのキー: TTLに関係なく、すべてのキーを考慮します。

ほとんどのアイテムに明示的な有効期限がある純粋なキャッシュレイヤーでは、揮発性ポリシーが優れています。外部のアプリケーションロジックに依存して古さを管理する場合は、非揮発性ポリシーを好むかもしれません。

主要な削除アルゴリズムの説明

A. 最も最近使用されていない(LRU)

これは、一般的なキャッシュで最も一般的であり、多くの場合デフォルトのポリシーです。最も長い間アクセスされていないキーを削除します。アクセスパターンが時間的局所性の原則(最近アクセスされたデータはすぐに再びアクセスされる可能性が高い)に従う場合に最適に機能します。

設定:

maxmemory-policy allkeys-lru

B. 最も頻繁に使用されていない(LFU)

LFUはキーがアクセスされた頻度を追跡します。推定アクセス頻度が低いキーを削除します。これは、ワークロードに安定した人気のあるキーのセットがあり、それらが時折のスキャンや1回限りの読み取りを生き残る必要がある場合に適しています。

設定:

maxmemory-policy allkeys-lfu

C. TTLベースの削除

TTLベースの削除は、キーに意味のある有効期限があり、有効期限が近いキーを削除しても安全な場合に便利です。

設定:

maxmemory-policy volatile-ttl

このポリシーは、有効期限が設定されたキーのみを考慮します。多くのキーにTTLがない場合、Redisは削除可能なキーを使い果たし、書き込みを拒否する可能性があります。

D. ランダム削除

ランダム削除はシンプルで、使い捨てのキャッシュデータには許容できる場合もありますが、キャッシュに明確なアクセスパターンがある場合に最初の選択肢となることはほとんどありません。

maxmemory-policy allkeys-random

3. TTLを一貫して設定する

削除ポリシーは圧力解放バルブであり、唯一のキャッシュ無効化戦略ではありません。ほとんどのキャッシュキーには、データのビジネス価値に一致する有効期限が必要です。

例えば、製品詳細ページでは、レンダリングされたフラグメントを5分間キャッシュする場合があります。

redis-cli SET product:123:html "$HTML" EX 300

ユーザー権限のルックアップは、古いデータのリスクが高いため、はるかに短いTTLが必要になる場合があります。

redis-cli SET user:42:permissions "$JSON" EX 30

allkeys-*ポリシーを使用しておらず、どのキーが削除されても問題ない場合を除き、使い捨てのキャッシュキーと同じRedisデータベースに永続的なキーを混在させないでください。一部のデータを絶対に削除してはならない場合は、別のRedisインスタンスまたは異なるポリシーのデータベースに保持してください。

4. キャッシュの永続化が役立つかどうかを判断する

純粋なキャッシュの場合、Redisの永続化はオプションです。RDBとAOFを無効にすると、ディスクI/Oと再起動の複雑さが軽減されますが、Redisが再起動するたびにすべてのキャッシュキーが失われます。

save ""
appendonly no

これは、アプリケーションがデータベースからキャッシュを再構築できる場合に許容されます。キャッシュのウォームアップにコストがかかる場合や、コールドキャッシュがデータベースに過負荷をかける場合は、RDBスナップショットまたはAOFを有効にしたままにして、負荷がかかった状態での再起動動作をテストしてください。

5. キャッシュの健全性を監視する

Redisメトリクスを使用して、キャッシュが機能していることを確認します。

redis-cli INFO memory
redis-cli INFO stats
redis-cli INFO keyspace

特に以下のフィールドに注目してください。

メトリクス 説明
used_memory_human Redisが現在消費しているメモリ。
maxmemory_human 設定されたメモリ上限。
evicted_keys Redisが圧力下で削除を行っているかどうか。
keyspace_hitskeyspace_misses キャッシュが有用な読み取りを提供しているかどうか。
expired_keys TTLクリーンアップがアクティブかどうか。

evicted_keysが急増し、ヒット率が低下した場合は、メモリを増やすか、価値の低いキーのTTLを短縮するか、ノイズの多いワークロードを別のキャッシュに分割してください。

キャッシュ設定例

これは、使い捨てのキャッシュエントリ専用のRedisインスタンスの妥当な出発点です。

maxmemory 4gb
maxmemory-policy allkeys-lfu
save ""
appendonly no

すべてのキーに慎重に選択されたTTLがあるキャッシュの場合:

maxmemory 4gb
maxmemory-policy volatile-ttl

CONFIG GET maxmemory maxmemory-policyを使用して、アクティブな設定を確認します。

redis-cli CONFIG GET maxmemory maxmemory-policy

まとめ

Redisキャッシュの設定を容量制御の問題として扱ってください。maxmemoryを設定し、アクセスパターンに一致する削除ポリシーを選択し、キャッシュキーに明示的なTTLを設定し、永続化がディスクI/Oに見合うかどうかを判断してください。その後、ヒット率、削除数、メモリ増加を監視して、キャッシュがデータベースを保護し、次のボトルネックにならないようにしてください。