Vegas Engineering by FORBIS 記事一覧
← 記事一覧へ戻る
Architecture ・ 第16回

Redis/Valkeyを、5つの役割で使い分ける — インメモリ活用の設計

キャッシュ、分散ロック、大容量受け渡し、ルーティング解決、在庫台帳。同じ技術を役割ごとに最適化して使う。

Vegas 開発チーム ・ 2026-07-03 ・ 読了 7分

WHYひとつの技術を、5つの顔で使う

サーバーレス基盤で数多くの関数が並走すると、「共有できる高速な記憶」の必要性が随所で立ち上がる。参照を速くしたい、同時実行を1つに絞りたい、大きなデータを軽く受け渡したい、その時刻の正しい設定を引きたい、在庫を1件も狂わせず更新したい。これらは一見バラバラの要件だが、いずれもインメモリKVS(Redis/Valkey)の得意分野に落ちる。私たちは同じ技術を、役割ごとに設計を最適化して使い分けている。

鍵になるのは、Valkeyが「単なるキャッシュ」ではなく、Luaによる原子的操作とSorted Set等のリッチなデータ構造を備えた小さな計算基盤である点だ。用途を絞れば、シンプルな構造で強力な保証が得られる。

ROLES5つの役割と、それぞれの型

Redis / Valkey キャッシュ 分散ロック 大容量受け渡し ルーティング解決 在庫台帳
図1:ひとつのValkeyを、5つの役割へ展開する。用途ごとに最適なデータ構造と操作を選ぶ。

ISOLATE役割ごとにクラスタを分離する

用途を1つの物理クラスタに同居させると、片方の負荷やメモリ逼迫、障害が他方へ波及する。基幹用・在庫用・販促用・ルーティング用など、特性の異なるワークロードは接続先を分離するのが基本方針だ。在庫台帳のような整合最優先の系と、揮発しても再生成できるキャッシュ系を切り離すことで、影響半径を小さく保てる。

基幹クラスタ キャッシュ / ロック 在庫クラスタ 在庫台帳(Lua) 販促クラスタ 大容量受け渡し ルーティング用 Sorted Set解決
図2:用途別にクラスタを分ける。負荷と障害の影響を互いに切り離す。

CODEルーティング解決の一例

時刻バージョニングでは、リクエスト時刻に対して「その時点で有効な最新版」を1件だけ引きたい。バージョンIDをスコア(有効開始時刻)付きでSorted Setに積んでおけば、範囲降順の先頭1件で解決できる。

routing_resolve.luaLua
-- KEYS[1]: バージョン集合キー / ARGV[1]: 参照時刻(epoch)
-- 参照時刻以前で最新のバージョンIDを1件返す
local ver = redis.call(
  "ZREVRANGEBYSCORE",
  KEYS[1], ARGV[1], "-inf",
  "LIMIT", 0, 1
)
if #ver == 0 then return nil end   -- 有効版なし
return ver[1]

TRADEOFF速さと引き換えに払うもの

インメモリKVSは低レイテンシとLuaによる原子性が魅力だが、代償もある。第一に揮発性——メモリ上の状態は失われうるため、恒久データはRDB等へwrite-behindで書き戻す設計が要る。第二にメモリ容量とキー設計——載る量には限界があり、TTLとキー命名の規律を欠くと肥大化する。第三にクラスタ分離の運用コスト——影響半径を絞る代わりに、監視・接続管理・容量計画が用途分だけ増える。第四にキャッシュ整合——更新時の無効化を怠ると古い値を返す。速さのために正しさの一部を自分で担保する、という交換であることを忘れてはいけない。

TAKEAWAY

Valkeyは「速いキャッシュ」ではなく、Luaとリッチな構造を備えた小さな共有計算基盤だ。キャッシュ・ロック・受け渡し・ルーティング・在庫台帳という役割ごとに設計を最適化し、用途別にクラスタを分離する。得るのは低レイテンシと原子性、払うのは揮発性・容量・運用・整合の管理コスト。この交換を意識して初めて、同じ技術を5つの顔で安全に使える。