自分で設計した Amazon ElastiCache for Redis クラスターのメモリ使用量を確認し、高いメモリ使用量を制御するためのベストプラクティスを実装したいと考えています。
簡単な説明
ElastiCache for Redis の自分で設計したクラスターでメモリ使用率が高くなる原因は次のとおりです。
- 最近追加されたキー:****キーと値のペアが増えると、メモリ使用量が増加します。また、すでに存在するキーに追加の要素があると、メモリ使用量が増加します。ノード上の最近のデータ変更を確認するには、SetTypeCmds メトリクスを確認します。詳細については、Redis ウェブサイトの INFO ページにある commandstats コマンドを参照してください。
- バッファ使用量の増加:クライアントはネットワーク経由で Redis に接続されます。Pub/Sub クライアントを含むクライアントの、キャッシュからの読み取り速度が十分でない場合、Redis は応答データをクライアント出力バッファーに保存します。詳細については、「Redis Pub/Sub」および「出力バッファーの制限」および「Redis Web サイト」を参照してください。ネットワーク帯域幅にボトルネックがある場合や、クラスターの負荷が継続的に高い場合は、バッファー使用量が累積する可能性があります。その結果、メモリが枯渇し、パフォーマンスが低下します。デフォルトでは、ElastiCache for Redis は出力バッファーの増加を制限せず、各クライアントには独自のバッファーがあります。バッファの使用状況を確認するには、client list コマンドを使用します。詳細については、Redis Web サイトの「クライアントリスト」を参照してください。
- **多数の新規接続:**新規接続の数が多いと、メモリ使用量が増える可能性があります。すべての新規接続により、メモリを消費するファイル記述子が作成され、その合計メモリ消費によってデータエビクションや OOM エラーが発生する可能性があります。新しい接続の数を確認するには、NewConnections メトリクスを確認します。
- スワップ使用率が高い: 空きメモリがあるときにキャッシュノードでスワップが使用されるのは正常な動作です。ただし、スワップの使用量が多すぎると、パフォーマンスが低下する可能性があります。メモリ負荷が高いノードでは、スワップ使用率が高くなります。その結果、空きメモリが少なくなります。ホスト上のスワップを監視するには、SwapUsage メトリクスを使用します。
- **メモリの断片化率が高い:**メモリの断片化が高い場合は、オペレーティングシステムのメモリ管理が非効率であることを示しています。キーを削除しても、Redis がメモリを解放しない場合があります。フラグメンテーション率をモニタリングするには、MemoryFragmentationRatio メトリクスを使用します。フラグメンテーションの問題がある場合は、アクティブメモリデフラグの activedefrag パラメータをオンにしてください。
- **ビッグキー:**ビッグキーはデータサイズが大きいか、要素の数が多いです。キーが大きいと、メモリ使用量が多くなる可能性があります。データセット内のビッグキーを検出するには、redis-cli --bigkeys コマンドまたは redis-cli --memkeys コマンドを使用してください。詳細については、Redis Web サイトの「ビッグキーのスキャン」 と「キーのスキャン」を参照してください。
解決策
メモリ使用量の確認
ElastiCache for Redis の自分で設計したクラスターでメモリ使用率を確認するには、次の Redis メトリクスを確認します。
**注:**これらのメトリクスは、クラスター内の各ノードについて Amazon CloudWatch に公開されます。
- **BytesUsedForCache:**これは、Redis がすべての目的に割り当てたバイトの総数です。この値は、クラスターのメモリ使用率を決定するために使用されます。このメトリクスを取得するには、Redis ノードで INFO コマンドを実行します。詳細については、Redis ウェブサイトの INFO を参照してください。
- **FreeableMemory:**これは、ホストで使用可能な空きメモリの量を示すホストレベルのメトリクスです。キャッシュデータまたはオーバーヘッドが原因でメモリ使用量が増加すると、FreeableMemory は減少します。FreeableMemory の減少は、ホストのメモリが不足していることを示しています。FreeableMemory が少なすぎると、スワップが発生することがあります。
- **DataBaseMemoryUsagePercentage:**これは、クラスターノードが使用しているメモリの割合です。このメトリクスがしきい値の 100% に達すると、Redis は Redis 最大メモリエビクションポリシーを開始します。詳細については、Redis Web サイトの「キーエビクション」を参照してください。このメトリクスを取得するには、Redis ノードで INFO コマンドを実行します。詳細については、Redis ウェブサイトの INFO を参照してください。
**注:**デフォルトでは、ElastiCache は maxmemory の 25% をフェイルオーバーやバックアップなどの非データ使用に予約します。データ以外で使用するための十分なリザーブドメモリを指定しないと、スワッピングが増加する可能性があります。詳細については、「リザーブドメモリの管理」を参照してください。
高いメモリ使用量を制御するためのベストプラクティス
- キーに TTL を使用: 不要なキーが保存されないようにし、有効期限が切れたキーを削除するには、有効期限のキーに TTL を指定します。詳細については、Redis ウェブサイトの「TTL」を参照してください。キーエビクションの数が多い場合、ノードはメモリ圧で稼働します。同じ時間枠でキーが期限切れにならないようにするには、TTL を使用するときにランダム性を追加します。
- エビクションポリシーを使用する: キャッシュメモリがいっぱいになると、Redis は maxmemory-policy に基づいてキーを削除して空き容量を増やします。デフォルトのmaxmemory-policy は volatile_lru に設定されています。ワークロードに適したエビクションポリシーを選択するのがベストプラクティスです。
- リザーブドメモリの割り当て: フェイルオーバーまたはバックアップ中の問題を回避するには、データ使用量以外の reserved_memory_percentage パラメーターを 25% 以上に設定するのがベストプラクティスです。フェイルオーバーまたはバックアップを実行するのに十分なリザーブドメモリがない場合、スワップとパフォーマンスの問題が発生します。
- 接続プーリングを使用する: コネクションプーリングにより、Redis クライアントが試みる多数の新しい接続を制御できます。詳細については、「Redis クライアントおよび ElastiCache for Redis 自己設計クラスターのベストプラクティスを実装する方法」を参照してください。
- サーバー側のアイドルタイムアウトを設定します。 クライアントが ElastiCache for Redis にリクエストを送信するかどうかにかかわらず、オープン接続はメモリを消費し、使用量は時間とともに増加します。アイドル接続による不要なメモリ使用量を最小限に抑えるには、パラメータグループを使用してサーバー側のタイムアウトを設定し、指定した時間が経過したらアイドル接続を閉じます。接続が早期に閉じられないようにするには、サーバー側のアイドルタイムアウト値を、クライアントライブラリ内のクライアント側のタイムアウトよりも高く設定します。
- 出力バッファサイズ制限の調整: 出力バッファ制限を調整して、バッファスペースの使用量を制御します。ElastiCache for Redis パラメータグループには、クライアント出力バッファの使用率が高くなるのを避けるため、client-output-buffer-limit で始まるパラメータが含まれています。これらのパラメータには推奨制限はありません。必ずワークロードのベンチマークを行い、出力バッファ制限に適切な値を選択してください。
- ハッシュマッピングを使用: ハッシュマッピングは、キーの数が多いデータ構造に役立ちます。また、ハッシュテーブルと比較してメモリ使用量を減らすには、ziplist エンコーディングを使用してください。詳細については、Redis Web サイトの「メモリの最適化」を参照してください。注:ハッシュマッピングは複雑なコマンドであり、Redis エンジンの使用量が急増する可能性があります。
- クラスターをスケーリングする: 予想されるワークロードでメモリ負荷が高まった場合は、クラスターをスケーリングしてメモリ負荷を軽減します。
- メモリ使用量のアラームを設定します。 あらかじめ設定されたしきい値に達したメモリ使用量のアラームを起動するには、CloudWatch アラームを使用します。CloudWatch アラームを作成するときは、BytesUsedForCache または DatabaseMemoryUsagePercentage メトリクスに使用されたバイト数を使用してください。