Redis オブザーバビリティのベストプラクティス¶
Redis とは¶
Redis は、広く利用されているインメモリのキー/バリューデータストアです。Redis はその優れたパフォーマンスと簡単な導入で知られており、以下のような様々な業界で活用されています。
-
データベース:非同期のディスク永続化は可能ですが、従来のディスクベースのデータベースとは異なり、Redis は永続性よりも速度を重視します。Redis は豊富なデータプリミティブと非常に多様なコマンドリストを提供します。
-
メッセージキュー:Redis のブロッキングリストコマンドと低レイテンシは、メッセージブローカーサービスの優れたバックエンドとなります。
- メモリキャッシュ:一般的な「Least Recently Used(LRU)」ポリシーや、Redis 4.0 以降で利用可能な「Least Frequently Used(LFU)」ポリシーを含む、設定可能なキー回収ポリシーにより、Redis はキャッシュサーバーとして最適です。従来のキャッシュとは異なり、Redis は信頼性向上のためにディスクへの永続化も可能です。
Redis は無料のオープンソース製品です。商用サポートや、フルマネージドの Redis サービスも提供されています。
Redis は、Twitter、GitHub、Docker、Pinterest、Datadog、Stack Overflow など、多くの高トラフィックな Web サイトやアプリケーションで採用されています。
主要な Redis メトリクス¶
Redis を監視することで、Redis 自体のリソース問題と、その背後にあるインフラストラクチャで発生する問題の2つの側面を発見できます。
この記事では、以下の各カテゴリにおける最も重要な Redis メトリクスについて詳しく説明します。
-
パフォーマンスメトリクス
-
メモリメトリクス
- 基本アクティビティメトリクス
- 永続性メトリクス
- エラーメトリクス
パフォーマンスメトリクス¶
低エラー率と並んで、良好なパフォーマンスはシステムの健全性を示す最良の指標の一つです。メモリセクションで説明したように、パフォーマンスの低下は多くの場合、メモリ問題に起因します。
| 名称 | 説明 | Metric Type |
|---|---|---|
| latency | Redis サーバーがリクエストに応答する平均時間 | Work: Performance |
| Instantaneous_ops_per_sec | 1秒間に処理されるコマンドの総数 | Work: Throughput |
| hit rate (算出) | keyspace_hits / (keyspace_hits + keyspace_misses) | Work: Success |
アラート指標:latency¶
レイテンシは、クライアントのリクエストと実際のサーバーレスポンスの間の時間を測定したものです。レイテンシの追跡は、Redis のパフォーマンス変化を検出する最も直接的な方法です。Redis はシングルスレッドであるため、レイテンシ分布の外れ値は深刻なボトルネックを引き起こす可能性があります。あるリクエストの応答時間が長くなると、後続のすべてのリクエストの待ち時間が増加します。レイテンシが問題であると特定されたら、パフォーマンス問題を診断および解決するための複数の対策を講じることができます。
観測指標:Instantaneous_ops_per_sec¶
処理されたコマンドのスループットを追跡することは、Redis インスタンスにおける高レイテンシの原因を診断するために不可欠です。高レイテンシは、コマンドキューのバックログ、低速なコマンド、ネットワークリンクの過剰使用など、多くの問題によって引き起こされる可能性があります。1秒間に処理されるコマンド数を測定することで調査できます。コマンド数がほぼ変わらない場合、原因は計算集約型のコマンドではありません。1つ以上の低速なコマンドがレイテンシ問題を引き起こしている場合、1秒間のコマンド数が減少するか、完全に停止するのが確認できます。過去の基準と比較して、1秒間に処理されるコマンド数が減少している場合は、コマンド量が少ないか、システムをブロックする低速なコマンドが存在することを示している可能性があります。コマンド量が少ないのは正常な場合もあれば、上流で問題が発生していることを示している場合もあります。
指標:hit rate¶
Redis をキャッシュとして使用する場合、キャッシュヒット率を監視することで、キャッシュが効果的に使用されているかどうかを把握できます。ヒット率が低いということは、クライアントが存在しなくなったキーを探していることを意味します。Redis はヒット率のメトリクスを直接提供しませんが、以下のように計算できます。
キャッシュヒット率の低下は、データの有効期限切れや、Redis に割り当てられたメモリ不足(キーの追い出しにつながる可能性があります)など、様々な要因によって引き起こされる可能性があります。低ヒット率は、アプリケーションが低速な代替リソースからデータを取得する必要があるため、アプリケーションのレイテンシ増加につながる可能性があります。
メモリメトリクス¶
| 名称 | 説明 | Metric Type |
|---|---|---|
| used_memory | Redis が使用しているメモリ量(バイト単位) | Resource: Utilization |
| mem_fragmentation_ratio | オペレーティングシステムが割り当てたメモリと Redis が要求したメモリの比率 | Resource: Saturation |
| evicted_keys | 最大メモリ制限に達したために削除されたキーの数 | Resource: Saturation |
| blocked_clients | BLPOP、BRPOP、または BRPOPLPUSH を待機中にブロックされているクライアント | Other |
観測指標:used_memory¶
メモリ使用率は、Redis のパフォーマンスにおける重要な要素です。used_memory が利用可能なシステムメモリの合計を超えると、オペレーティングシステムは古い、または未使用のメモリ部分のスワップを開始します。スワップされた各部分はディスクに書き込まれ、パフォーマンスに深刻な影響を与えます。ディスクへの書き込みまたは読み取りは、メモリへの書き込みまたは読み取りよりも5桁(100,000倍!)遅くなります(メモリは0.1 µs、ディスクは10 ms)。
Redis は、指定されたメモリ量に制限するように設定できます。redis.conf ファイルで maxmemory ディレクティブを設定することで、Redis のメモリ使用量を直接制御できます。maxmemory を有効にするには、メモリ解放方法を決定するために、Redis に追い出しポリシーを設定する必要があります。evicted_keys セクションで、maxmemory-policy ディレクティブの設定について詳しく説明します。
アラート指標:mem_fragmentation_ratio¶
mem_fragmentation_ratio メトリクスは、オペレーティングシステムが使用するメモリ(used_memory_rss)と Redis が割り当てたメモリ(used_memory)の比率を提供します。
オペレーティングシステムは、各プロセスに物理メモリを割り当てる役割を担います。OS の仮想メモリマネージャーは、メモリアロケーターによって仲介される実際のマッピングを処理します。これは何を意味するのでしょうか?Redis インスタンスのメモリ使用量が 1GB の場合、メモリアロケーターはまず、データを格納するための連続したメモリセグメントを見つけようとします。連続したセグメントが見つからない場合、アロケーターはプロセスのデータを複数のセグメントに分割する必要があり、メモリオーバーヘッドが増加します。
断片化率の追跡は、Redis インスタンスのパフォーマンスを理解する上で非常に重要です。断片化率が1より大きい場合は、断片化が発生していることを示します。率が1.5を超える場合は、過度の断片化が発生しており、Redis インスタンスが要求した物理メモリの150%を消費していることを意味します。1未満の断片化率は、Redis が必要とするメモリがシステム上で利用可能なメモリよりも多いことを示し、スワップが発生します。ディスクへのスワップは、レイテンシの大幅な増加につながります(使用済みメモリを参照)。理想的には、オペレーティングシステムは物理メモリに連続したセグメントを割り当て、断片化率は1以上になります。
サーバーの断片化率が1.5を超える場合、Redis インスタンスを再起動すると、オペレーティングシステムは以前は断片化のために使用できなかったメモリを回復できます。この場合、アラートを通知として送信するだけで十分な場合があります。
ただし、Redis サーバーの断片化率が1未満の場合は、ページとしてアラートを発行し、使用可能なメモリを迅速に増やすか、メモリ使用量を減らせるようにする必要があるかもしれません。
Redis 4 以降では、Redis が同梱の jemalloc コピーを使用するように設定されている場合、新しいアクティブデフラグメンテーション機能を利用できます。このツールは、断片化が一定レベルに達したときに起動し、値を連続したメモリ領域にコピーして古いコピーを解放するように設定でき、サーバー実行中の断片化を低減します。
アラート指標:evicted_keys(キャッシュのみ)¶
Redis をキャッシュとして使用する場合、最大メモリ制限に達したときに自動的にキーを消去するように設定する必要があるかもしれません。Redis をデータベースまたはキューとして使用する場合は、追い出しの代わりに他の方法を取る方が良いでしょう。その場合は、この指標をスキップできます。
キーの追い出しを追跡することは重要です。なぜなら、Redis は各操作を順次処理するため、大量のキーを追い出すとヒット率が低下し、レイテンシが長くなるからです。TTL を使用している場合、キーの追い出しは望ましくない可能性があります。その場合、この指標が常にゼロより大きいと、インスタンスのレイテンシが増加する可能性があります。TTL を使用しないその他の設定のほとんどは、最終的にメモリを使い果たし、キーの追い出しを開始します。応答時間が許容範囲内であれば、安定した追い出し率は許容できます。
以下のコマンドを使用して、キーの有効期限ポリシーを設定できます。
ここで、policy は以下のいずれかです。
-
noeviction: メモリ制限に達し、ユーザーが別のキーを追加しようとすると、エラーを返します。
-
volatile-lru: 有効期限が設定されたキーの中から、最も最近使用されていないキーを削除します。
- volatile-ttl: 有効期限が設定されたキーの中から、残り生存時間が最も短いキーを削除します。
- volatile-random: 有効期限が設定されたキーの中から、ランダムなキーを削除します。
- allkeys-lru: すべてのキーセットから、最も最近使用されていないキーを削除します。
- allkeys-random: すべてのキーセットから、ランダムなキーを削除します。
- volatile-lfu: Redis 4 で追加。有効期限が設定されたキーの中から、最も頻繁に使用されていないキーを削除します。
- allkeys-lfu: Redis 4 で追加。すべてのキーセットから、最も頻繁に使用されていないキーを削除します。
注意:パフォーマンス上の理由から、LRU、TTL、または Redis 4(LFU 以降)のポリシーを使用する場合、Redis は実際にはキースペース全体をサンプリングしません。Redis はまずキースペースのランダムなサブセットをサンプリングし、そのサンプルに追い出しポリシーを適用します。一般的に、新しい(>= 3)バージョンの Redis は、真の LRU により近い LRU サンプリング戦略を採用しています。LFU ポリシーは、例えば、アイテムのアクセスレベルが低下するまでの経過時間を設定することで調整できます。詳細については、Redis のドキュメントを参照してください。
観測指標:blocked_clients¶
Redis は、リストを操作するためのブロッキングコマンドをいくつか提供しています。BLPOP、BRPOP、BRPOPLPUSH は、それぞれ LPOP、RPOP、RPOPLPUSH コマンドのブロッキングバリアントです。ソースリストが空でない場合、コマンドは期待通りに実行されます。しかし、ソースリストが空の場合、ブロッキングコマンドは、ソースがデータで満たされるか、タイムアウトに達するまで待機します。
データを待機しているブロックされたクライアントの数が増加することは、問題の兆候である可能性があります。レイテンシやその他の問題により、ソースリストへのデータ投入が妨げられている可能性があります。ブロックされたクライアント自体はアラートを引き起こすものではありませんが、この指標が常にゼロ以外の値を示す場合は、調査する必要があります。
基本アクティビティメトリクス¶
注意:このセクションには、「マスター」および「スレーブ」という用語を含むメトリクスが含まれます。特定のメトリクス名を参照する場合を除き、この記事ではこれらを「primary」および「replica」に置き換えます。
| 名称 | 説明 | Metric Type |
|---|---|---|
| connected_clients | Redis に接続されているクライアントの数 | Resource: Utilization |
| connected_slaves | 現在のプライマリインスタンスに接続されているレプリカの数 | Other |
| master_last_io_seconds_ago | レプリカとプライマリインスタンス間の最後のやり取りからの経過時間(秒単位) | Other |
| keyspace | データベース内のキーの総数 | Resource: Utilization |
アラート指標:connected_clients¶
Redis へのアクセスは通常、アプリケーションを介して仲介されるため(ユーザーが直接データベースにアクセスすることは通常ありません)、ほとんどの場合、接続されているクライアントの数には妥当な上限と下限があります。数値が通常の範囲を超えている場合は、問題が発生している可能性があります。低すぎる場合は上流の接続が失われている可能性があり、高すぎる場合は多数の同時クライアント接続によりサーバーのリクエスト処理能力が圧倒されている可能性があります。
いずれにせよ、クライアント接続の最大数は常に有限のリソースです。オペレーティングシステム、Redis の設定、またはネットワークの制限のいずれかによって制限されます。クライアント接続を監視することで、新しいクライアントやセッション管理に十分な利用可能なリソースがあることを確認できます。
アラート指標:connected_slaves¶
データベースが読み取り主体である場合、Redis で利用可能なプライマリレプリカデータベースレプリケーション機能を使用している可能性があります。その場合、接続されているレプリカの数を監視することが重要です。接続されているレプリカの数が予期せず変化した場合、プライマリがダウンしているか、レプリカインスタンスに問題が発生している可能性があります。
注意:上図では、Redis プライマリデータベースは2つの接続されたレプリカを持っていることを示し、最初の子ノードはそれぞれ自身も2つの接続されたレプリカを持っていることを報告します。セカンダリレプリカは Redis プライマリレプリカに直接接続されていないため、プライマリに接続されているレプリカの数には含まれません。
アラート指標:master_last_io_seconds_ago¶
Redis のレプリケーション機能を使用する場合、レプリカインスタンスは定期的にプライマリインスタンスにチェックインします。長時間通信がない場合は、プライマリ Redis サーバー、レプリカサーバー、またはその両方に問題がある可能性があります。また、レプリカが最後の同期以降に変更された可能性のある古いデータを提供するリスクもあります。Redis が同期を実行する方法のため、プライマリレプリカ間の通信の中断を最小限に抑えることが重要です。中断後にレプリカがプライマリデータベースに再接続すると、中断中に失われたコマンドのみの部分同期を試みるために SYNC コマンドを送信します。これが不可能な場合、レプリカは完全な SYNC を要求し、プライマリはデータセットを変更する受信したすべての新しいコマンドをバッファリングしながら、データベースのバックグラウンド保存をディスクにすぐに開始します。バックグラウンド保存が完了すると、データはバッファリングされたコマンドとともにクライアントに送信されます。レプリカが SYNC を実行するたびに、プライマリインスタンスのレイテンシが大幅に増加します。
注目すべき指標:keyspace¶
データベース内のキーの数を追跡することは、一般的に良いアイデアです。インメモリデータストアであるため、キースペースが大きいほど、Redis は最適なパフォーマンスを確保するためにより多くの物理メモリを必要とします。Redis は最大メモリ制限に達するまでキーを追加し続け、その時点で新しいキーが同じレートでキーを追い出すようになります。
Redis をキャッシュとして使用していて、キースペースの飽和(上の図のようないわゆる水平線)と低いヒット率が見られる場合、クライアントは古いデータまたは追い出されたデータを要求している可能性があります。時間の経過に伴う keyspace_misses の数を追跡することで、原因を特定するのに役立ちます。
また、Redis をデータベースまたはキューとして使用する場合、揮発性キーは推奨されない可能性があります。キースペースが増大するにつれて、可能であれば、マシンにメモリを追加するか、ホスト間でデータセットを分割することを検討する必要があります。メモリの追加は、シンプルで効果的なソリューションです。1台のマシンで提供できるリソースを超えるリソースが必要な場合は、データをパーティショニングまたはシャーディングして複数のコンピュータのリソースを組み合わせることができます。パーティショニング計画を立てれば、Redis は追い出しやスワップを行うことなく、より多くのキーを保存できます。ただし、パーティショニング計画の適用は、メモリを追加するよりも困難です。
永続性メトリクス¶
| 名称 | 説明 | Metric Type |
|---|---|---|
| rdb_last_save_time | 最後にディスクに保存された時刻のUnixタイムスタンプ | Other |
| rdb_changes_since_last_save | 最後のダンプ以降にデータベースに加えられた変更の数 | Other |
永続性を有効にすることは、特に Redis のレプリケーション機能を使用する場合に必要になることがあります。レプリカはプライマリインスタンスに加えられた変更を盲目的に複製するため、プライマリインスタンスを(永続性なしで)再起動すると、それに接続されているすべてのレプリカは、現在空になったデータセットを複製することになります。
Redis をキャッシュとして使用している場合や、データ損失がそれほど重要でないユースケースでは、永続性は必要ない場合があります。
監視すべき重要な指標:rdb_last_save_time および rdb_changes_since_last_save¶
通常、データセットの変動性に注意することが最善です。サーバーに障害が発生した場合、ディスクへの書き込み間隔が長すぎると、データ損失が発生する可能性があります。最後の保存時刻から障害発生時刻までの間にデータセットに加えられた変更はすべて失われます。rdb_changes_since_last_save を監視すると、データの変動性をより深く理解できます。その間隔内でデータセットが大きく変化していない場合は、2回の書き込み間の長い間隔は問題になりません。2つの指標を追跡することで、特定の時点で障害が発生した場合にどれだけのデータが失われるかを把握できます。
エラーメトリクス¶
注意:このセクションには、「マスター」および「スレーブ」という用語を含むメトリクスが含まれます。特定のメトリクス名を参照する場合を除き、この記事ではこれらを「primary」および「replica」に置き換えます。
Redis のエラーメトリクスは、異常な状態を警告します。以下の指標は、一般的なエラーを追跡します。
| 名称 | 説明 | Metric Type |
|---|---|---|
| rejected_connections | maxclient 制限に達したために拒否された接続の数 | Resource: Saturation |
| keyspace_misses | 失敗したキー参照の回数 | Resource: Errors / Other |
| master_link_down_since_seconds | プライマリサーバーとレプリカサーバー間のリンクが切断されてからの経過時間(秒単位) | Resource: Errors |
アラート指標:rejected_connections¶
Redis は多くのアクティブな接続を処理でき、デフォルトでは 10,000 のクライアント接続が利用可能です。redis.conf の maxclient ディレクティブを変更することで、最大接続数を別の値に設定できます。Redis インスタンスが現在最大接続数に達している場合、新しい接続試行はすべて切断されます。
システムが maxclient ディレクティブで要求された接続数をサポートできない可能性があることに注意してください。Redis はカーネルと照合して、利用可能なファイル記述子の数を確認します。利用可能なファイル記述子の数が maxclient + 32(Redis は自身の使用のために32個のファイル記述子を予約します)より少ない場合、maxclient ディレクティブは無視され、利用可能なファイル記述子の数が使用されます。
アラート指標:keyspace_misses¶
Redis がキーを参照するたびに、結果は2つしかありません。キーが存在するか、キーが存在しないかです。存在しないキーを参照すると、keyspace_misses カウンターが増加します。このメトリクスが常にゼロ以外の値であるということは、クライアントがデータベース内に存在しないキーを参照しようとしていることを示しています。Redis をキャッシュとして使用していない場合、keyspace_misses はゼロまたはゼロに近いはずです。空のキーに対して呼び出されるブロッキング操作(BLPOP、BRPOP、BRPOPLPUSH)は、keyspace_misses を増加させることに注意してください。
アラート指標:master_link_down_since_seconds¶
この指標は、プライマリノードとそのレプリカ間の接続が失われた場合にのみ利用可能です。理想的には、この値はゼロを超えるべきではありません。プライマリデータベースとレプリカデータベースは、レプリカデータベースが古いデータを提供しないように、継続的に通信を維持する必要があります。接続間の大きな時間間隔は解決されるべきです。再接続後、プライマリ Redis インスタンスはレプリカのデータを更新するためにリソースを投入する必要があり、これによりレイテンシが増加する可能性があることを覚えておいてください。
まとめ¶
この記事では、Redis サーバーの状況を把握するために監視できる、最も有用なメトリクスのいくつかを紹介しました。Redis を使い始めたばかりの場合は、以下のリストのメトリクスを監視することで、データベースインフラストラクチャの健全性とパフォーマンスを把握できます。
-
1秒間に処理されるコマンド数
-
レイテンシ
- メモリ断片化率
- 追い出し
- 拒否されたクライアント
最終的には、ご自身のインフラストラクチャとユースケースに特に関連する他のメトリクスを認識できるようになるでしょう。もちろん、監視する内容は、お持ちのツールと利用可能なメトリクスによって異なります。



