概要 — 何をする画面か
サービス ▸ セッション(Redis) は、登録済み Redis ノードのセッション/キャッシュストアの健全性を1画面で監視します。サービス ▸ データベース の物語を Redis に写したもので、次の2つの軸で読み解きます。
- 収容上限+現在の状態 — メモリ飽和率のリングゲージ(
used_memory÷ 収容上限)、クライアント接続数(connected / maxclients)、ブロック中のクライアント。 - スループット — 1秒あたりの処理コマンド数(
instantaneous_ops_per_sec)、直近ウィンドウのヒット率(Δhits / Δ(hits+misses))、ネットワーク I/O(受信/送信 kbps)。
折りたたみ式の詳細パネルには、メモリ管理の時系列(収容上限のオーバーレイ+追い出しエピソードのピン)とキースペース/セッション分析が加わります。
この画面は Redis に直接接続することはありません。 内部網の代表コレクター(
scripts/infr_redis_vts_collector.cjs、毎分実行される pm2 cron)が各ノードでredis-cli INFOを実行し、スナップショットを中央 MySQL のテーブルinfr_redis_metricに投入します。アプリはそれを読むだけです。アプリは Redis の認証情報を保持せず、常駐デーモンも動かしません(接続リークとハードコードされた認証情報という罠を避けるためです)。
こんなときに使う
- セッションストアの収容量 — Redis のメモリが上限に近づき、圧迫時にセッションが追い出され(失われ)る兆候を見つけます。
- キャッシュ効率の診断 — ヒット率・断片化・slowlog から、キャッシュが役目を果たしているかを判断します。
- 接続の飽和 —
connected_clientsがmaxclientsに近づく、あるいはrejected_connectionsが増えるとき、新規接続が拒否される前に手を打ちます。 - 永続化/レプリケーションの障害 — RDB の bgsave 失敗、AOF リライト、レプリカのリンク断をバッジで確認します。
- セッションの寿命 — 期限切れ(正常な寿命)と追い出し(メモリ圧迫)を区別し、セッションの回転量を読み取ります。
画面構成
上部 KPI
| KPI | 意味 |
|---|---|
| ノード | 直近(30分)ウィンドウにサンプルがある Redis ノードカード |
| 正常 / 劣化 / 停止 | up / degraded / down ノードの件数 |
| 合計 ops/秒 | 全ノードの instantaneous_ops_per_sec の合計 |
| 総キー数 | 全ノードの keyspace_keys の合計 |
ノードカード(2つの軸)
各ノードが1枚のカードです。ヘッダーにはインスタンス名/別名、Redis のバージョン、ロール(master/replica)が並び、本体が2つの軸を担います。
① 収容量・空き(左のリングゲージ) — 中央の値は used_pct(使用量 ÷ 収容上限)です。指標ストリップ:
| 指標 | フィールド | 備考 |
|---|---|---|
| クライアント | connected_clients / maxclients |
接続数と上限。上限に近づくと新規接続が拒否されます |
| ブロック中 | blocked_clients |
BLPOP・BRPOP・WAIT を待っているクライアント(0 が健全) |
② スループット(右) — スパークライン+ストリップ:
| 指標 | フィールド | 備考 |
|---|---|---|
| ops/秒 | instantaneous_ops_per_sec |
1秒あたりに処理されたコマンド数 |
| ヒット率 | Δhits / Δ(hits+misses) | 直近ウィンドウのキャッシュヒット率(サンプルが少ないときは起動以来の値にフォールバック) |
| ネットワーク I/O | instantaneous_input_kbps + output_kbps |
1秒あたりのネットワーク受信/送信 |
効率スコア(カード下部)
- ヒット率の評価 — 優秀 ≥99% · 良好 ≥95% · 普通 ≥80%。
- **メモリ効率(断片化)**の評価 — 優秀 0.95–1.4 · 良好 ~1.6 · 普通 ~2.5。
断片化スコア(
frag_score)は、used_memoryが 64 MB 以上のときだけ算出されます。小さなインスタンスでは固定のアロケーターオーバーヘッドが比率を支配して誤警報を生むため、このしきい値を下回る場合はスコアリングとステータスの両方から除外されます。
セッション寿命の流れストリップ
カード下部の全幅ストリップが、期限あり → 流れ → 累計の期限切れ を描画します。左は現在 TTL を持つキー(keyspace_expires、まもなく自然に期限切れになるもの)、右は起動以来に期限切れとなったキー(expired_keys、セッションの回転量)です。塗りが ≈100% に近ければ、純粋なセッションストアであることを意味します。
詳細(展開)
2つのブロックが折りたたみで開きます(高さの変化に応じて masonry レイアウトが組み直されます)。
- メモリ管理 —
usedと収容量の時系列+収容上限 100% の切断線オーバーレイ+追い出しエピソードの crit ピン。カードには収容上限(cap)、推定空き(est_free)、総 RAM、DB 予約分、OS 予約分、ピーク、RSS、断片化、累計の追い出し/期限切れ、追い出しポリシーが並びます。 - キースペース・セッション — 総キー数、TTL を持つキー数、論理 DB(db0/db1…)の分布バー、強調表示されたセッション DB、平均 TTL、RDB/AOF/レプリカの永続化バッジ。
教育用ポップオーバー(edu)
指標の横のアイコンにマウスを乗せると、原因と対処を説明する専用のポップオーバーが開きます(より深い概念は Redis チューニング解説 を参照):
| ポップオーバー | 内容 |
|---|---|
| SLOWLOG | 低速コマンドが溜まる7つの原因(O(N) コマンド · ビッグキー · メモリ圧迫 · fork の停滞 · Lua · パイプライン · 大量 DEL) |
| ヒット率 | keyspace ヒット率の根拠+改善方法(ワーキングセットを常駐させる · TTL を調整する · スタンピードを緩和する) |
| 断片化 | RSS / used の健全帯(1.0–1.5)· activedefrag · スワップ(<1.0)の警告 |
| 論理 DB | Redis の番号付き DB(0–15)の概念 · 用途別の分割 · Cluster への移植性 |
| 期限切れ・追い出し | 期限切れ(正常な寿命)と追い出し(メモリ圧迫)の違い · 読み方 |
使い方
- ポーリング — 読み込み後、ページは 30秒ごとに
/service/session/liveをポーリングして KPI とカードを更新します(サーバー側はダッシュボードを20秒キャッシュします)。 - カードの並び替え — カードをドラッグして優先順に並べ替えます(SortableJS。順序は localStorage に保存されます)。
- 詳細の展開 — カードの [展開] でメモリ管理とキースペースのブロックを開きます。
- edu で学ぶ — 指標のアイコンにマウスを乗せると、原因/対処のポップオーバーが表示されます。
- 全画面 — ヘッダーの LIVE 表示の隣にある全画面ボタンで上部ナビを隠し、ダッシュボードモードに切り替えます(ESC で解除)。
カードが1枚もない場合は、Redis ノードがまだ登録・収集されていません。管理 ▸ コレクター で
redis_vtsコレクターにredis_hostノードを登録し、代表ホスト上に pm2 でコレクターを配置してください。
データソース
読み取り専用モデル infr_redis_metric
アプリはこのテーブルを 読み取り専用の Legacy スタイルのモデル(App\Models\Infr\InfrRedisMetric、$timestamps=false)としてマッピングします。マイグレーションは意図的に用意していません — コレクターが CREATE TABLE IF NOT EXISTS で自己プロビジョニングするため、アプリ側の Schema::create は衝突してしまいます。
ビルダー App\Services\Redis\RedisMetricService::dashboard() の規律:
- 直近 30分ウィンドウ(
WINDOW_MIN)を1回のバッチクエリで取得し、node_aliasでグループ化します(ノードごとに1枚のカード)。ウィンドウ内にサンプルがない場合(収集が止まった場合)は、少なくとも直近180行を取得してノードをstaleとして提示します。 - 時系列はカードあたり直近 60ポイントに切り詰められます(
SERIES_MAX)。累積カウンター(evicted/expired)は隣接サンプルの差分でレートに変換され、リセット時(値が減少したとき)はレートがnullになります。 - ダッシュボードの結果は 20秒キャッシュされます(
infr:redism:dash:v1)。
-- 概念図(実際は Eloquent)。直近ウィンドウをまとめて取得し、PHP 側でグループ化します。
SELECT * FROM infr_redis_metric
WHERE sampled_at >= (NOW() - INTERVAL 30 MINUTE)
ORDER BY sampled_at;
コレクター — scripts/infr_redis_vts_collector.cjs
内部網の単一の代表ホストが pm2 cron で動作し、1回の実行で複数ノードの Redis(redis-cli -h {ip} INFO)と nginx vts をスイープして中央 MySQL に直接投入し、そのまま終了します(常駐しない → 実行のたびに新しいプロセスとなり、リークが起きません)。設定はファイル先頭の CONFIG ブロックにのみ存在します(環境変数なし、認証情報のハードコードなし)。
# 代表ホストに配置する(毎分スイープ、常駐しない)
npm i mysql2 # 唯一の npm 依存(投入用)。redis-cli は OS のパッケージで導入します。
pm2 start infr_redis_vts_collector.cjs --name infr-collector \
--no-autorestart --cron-restart "* * * * *"
pm2 save
インスタンスの結合(別名 / int の外部キー)
書き込み時、コレクターは infr_instance でノード別名→id を引き、instance_id(int) を直接書き込みます。アプリは主に metric.instance_id = infr_instance.id(整数比較 — 照合順序に依存せず、主キーのインデックスが効きます)で結合します。未登録、あるいは後から登録されたインスタンスは node_alias(小文字化)→ infr_instance.alias にフォールバックし、infr:link-metrics のバックフィル(リーダーゲート付き、5分ごと)が後から instance_id を埋めます。
収容上限(cap)の算出
リングゲージとメモリチャートの 100% の基準は、次の順序で解決されます。
| cap の種別 | 条件 | 上限 | 推定空き(est_free) |
|---|---|---|---|
maxmemory |
maxmemory > 0 |
maxmemory の設定値(ハード上限) | maxmemory − used |
budget |
maxmemory 未設定 | 総 RAM − DB バッファプール − OS 予約分 | budget − used |
- 総 RAM =
total_system_memory(収集値)。取得できない場合はinfr_instance.mem_mbにフォールバックします。 - OS 予約分 = 総 RAM ×
redis_reserve_pct(既定 20%)。 - DB バッファプール = 同じノードの最新の
access=databaseコレクターのinfr_db_metric.raw.bp_size(1ノードに複数 DB があれば合算)。これを差し引くと、Redis が現実的に使える予算が上限として得られます。 - 予算には下限が設けられ、現在の
usedを下回ることはありません(負の値や逆転を防ぎます)。
ステータス判定としきい値
statusOf() は各ノードを up / degraded / down に分類します。
| ステータス | 条件 |
|---|---|
down |
収集に失敗(ok=0)、または stale(最後のサンプルが redis_stale_min より古い) |
degraded |
以下の理由のいずれか1つ以上に該当 |
up |
理由なし |
degraded の理由としきい値(管理 ▸ 運用ポリシー、infr_setting group=ops):
| 理由 | 条件 | しきい値キー | 既定値 |
|---|---|---|---|
| メモリ飽和 | used_pct ≥ |
redis_mem_pct |
85 |
| 断片化 | frag_score ≥ |
redis_frag_ratio |
1.6 |
| ブロック中のクライアント | blocked_clients ≥ |
redis_blocked |
1 |
| レプリカのリンク断 | master_link_status = down |
— | — |
| RDB 保存の失敗 | rdb_last_bgsave_status = err |
— | — |
ヒット率はステータスの軸ではありません。 セッションストアは新規ログイン・期限切れ・ログアウトのたびにミスするため、40〜60% のヒット率が正常です(例:まったく健全なセッションノードで 44.75%)。以前は
redis_hit_rate_min(既定 50)を下回るヒット率が誤った赤色のdegradedを生んでいましたが、現在ヒット率はカードの KPI・評価ゲージ・edu ポップオーバーに表示されるだけで、ノードを赤くすることはありません。本当のキャッシュの問題(メモリ飽和、追い出し、断片化)は、ワークロードに関係なくmem_saturation/fragmentationが捕捉します。
アクセス権限
- 閲覧(この画面) —
user_level ≥ 1(demo=1)。サービスの役割領域は最小レベル1で、この画面は読み取り専用です(書き込み・削除の操作はありません)。 - コレクターの登録・編集 — 管理 ▸ コレクター で
redis_vtsコレクターにredis_hostノードとパスワードを登録するにはuser_level ≥ 5(staff/admin)が必要です。 - しきい値の変更 — 管理 ▸ 運用ポリシー には
user_level ≥ 5が必要です。
この画面には破壊的な操作がないため、独自の監査ログは記録しません(コレクターとポリシーの変更は、それぞれの管理画面で監査されます)。
トラブルシューティング・FAQ
カードが1枚も表示されない(「収集された Redis ノードがありません」)
infr_redis_metric に直近のサンプルがありません。(1) 管理 ▸ コレクター で redis_vts コレクターに redis_host ノードを登録したか、(2) 代表ホストで infr_redis_vts_collector.cjs が pm2 の下で動いているか、(3) 代表ホストから redis-cli で各ノードの Redis ポートに到達できるかを確認してください。
ノードが「停止(stale)」と表示される
最後のサンプルが redis_stale_min(既定5分)より古い状態です。代表コレクターの pm2 プロセスが停止したか、その cron が止まった可能性が高いです。pm2 list / pm2 logs infr-collector で確認してください。
リングゲージの上限がおかしい/空き容量が大きすぎるように見える
maxmemory のないノードは予算を上限として使います(総 RAM − DB バッファプール − OS 予約分 20%)。ハード上限が必要なら Redis に maxmemory を設定してください — その値がそのまま上限になります。
キースペース/セッションのブロックが空になっている
DB ごとの詳細(raw.keyspace)とセッション DB の指標は、拡張されたコレクターが投入します。古いコレクターの場合は再配置すれば(total_system_memory、keyspace_keys、DB ごとの raw 列が冪等に追加されます)表示されます。未収集の場合、このセクションは何も出さずに隠れます。
ヒット率が低い — 問題でしょうか?
セッションのワークロードであれば問題ありません(上記の警告を参照)。純粋なキャッシュでヒット率が低い場合は、ワーキングセットが常駐していないか TTL が短すぎる可能性があります — Redis チューニング解説 のヒット率の項目を参照してください。
断片化スコアが表示されない
used_memory が 64 MB 未満のとき、断片化率は固定のオーバーヘッドに支配されて意味を持たないため、スコアリングとステータスから除外されます。
関連項目
- データベース(サービス ▸ データベース) — 同じ物語(収容量 · スループット · スキーマ)を MySQL 向けに実装した姉妹画面
- Redis チューニング解説 — slowlog、ヒット率、断片化、キースペース、追い出しのより詳しい解説
- コレクター(管理 ▸ コレクター) —
redis_vtsコレクターとそのノードを登録します - 運用ポリシー(管理 ▸ 運用ポリシー) — Redis のステータスしきい値と予約率を設定します
- サービス概要(サービス ▸ 概要) — セッションカードを優先度ボードにピン留めします
