Redis入門:インメモリデータストアの仕組みと活用シーン

データベース・分散システム

Redisとは

Redisは、インメモリで動作するキーバリュー型のデータストアです。データをディスクではなく主にメモリ上に保持することで、ミリ秒未満の応答速度を実現しており、キャッシュ、セッションストア、メッセージブローカーなど幅広い用途で利用されています。オープンソースとして開発されており、シンプルなキーバリューだけでなく、リスト、ハッシュ、セット、ソート済みセットといった多様なデータ構造をネイティブにサポートしている点が特徴です。

主なデータ構造

  • String:最も基本的な型。カウンターやフラグ、単純なキャッシュ値の格納に利用。
  • Hash:フィールドと値の組を1つのキーにまとめて格納。オブジェクトの表現に向いている。
  • List:順序付きの配列。キューやタイムラインの実装に利用される。
  • Set / Sorted Set:重複のない集合。Sorted Setはスコア順のランキングやリーダーボードに適している。
  • Stream:ログのような追記型データ構造。イベント処理やメッセージングに利用される。

永続化の仕組み

Redisはインメモリが基本ですが、再起動時のデータ消失を防ぐために2種類の永続化方式を提供しています。

  • RDB(スナップショット):一定間隔でメモリ全体をディスクに書き出す方式。復旧は速いが、直近の更新が失われる可能性がある。
  • AOF(Append Only File):書き込みコマンドを逐次ログに追記する方式。データ欠損が少ないが、ファイルサイズが大きくなりやすい。

用途に応じて両者を併用することも可能です。

典型的な活用シーン

  1. キャッシュ:DBへのクエリ結果を一時的に保持し、レスポンス速度を向上させる。TTL(有効期限)を設定して自動的に古いデータを破棄できる。
  2. セッションストア:Webアプリケーションのログインセッションなど、複数サーバー間で共有したい状態を保持する。
  3. レートリミット:INCRとTTLを組み合わせて、一定期間内のリクエスト回数を制御する。
  4. Pub/Subとメッセージキュー:軽量なリアルタイム通知や、Streamを使ったジョブキューの実装。
  5. ランキング・リーダーボード:Sorted Setを使ってスコア順のランキングを効率的に管理する。

運用上の注意点

Redisはシングルスレッドでコマンドを処理するため、計算量の大きいコマンド(例:大きなコレクションに対するKEYSコマンドなど)は他の処理をブロックしてしまう可能性があります。本番運用では、SCANコマンドの利用や、メモリ使用量の監視、eviction policy(maxmemory-policy)の設定など、メモリ逼迫時の挙動を事前に設計しておくことが重要です。また、可用性を高めるためにReplication(レプリカ構成)やRedis Sentinel、Redis Clusterによる水平分散も検討されます。

気をつけるべきこと(よくある落とし穴)

  • 「永続化=安全」という誤解:RDBは前回スナップショット以降の更新を失うリスクがあり、AOFもappendfsyncの設定次第で最大1秒分のデータをロストしうる。Redisを唯一のデータソース(system of record)として扱う場合は、バックアップ運用とレプリケーションを併用し、RPO(許容データ損失時間)を明確にしておく。
  • セキュリティ設定の見落とし:デフォルトでは認証なし・平文通信になりやすい。bindでリッスンアドレスを絞る、requirepass/ACLでの認証、TLSの有効化、外部公開ポートの遮断を必ず確認する。protected-modeを無効化したまま公開してしまう事故は特に多い。
  • ビッグキー・ビッグバリュー問題:1つのキーやコレクションが巨大化すると、読み書きだけでなく削除(DEL)やRDB保存時にも大きな遅延を生む。事前にサイズの上限方針を決め、redis-cli --bigkeysなどで定期的に監視する。
  • トランザクションの過信:MULTI/EXECはコマンドをアトミックにまとめて実行するが、途中でコマンドが失敗してもロールバックはされない。複雑な条件付き更新にはLuaスクリプトやRedis Functionsの利用を検討する。
  • fork時のレイテンシスパイク:RDBスナップショットやAOF書き換え(rewrite)はfork()で子プロセスを生成するため、メモリ使用量が大きいインスタンスではforkに時間がかかり、瞬間的な遅延やメモリ倍増(Copy-on-Write)が発生しうる。メモリに余裕を持たせた設計が必要。
  • Clusterモードの制約:Redis Clusterでは複数キーにまたがる操作(トランザクション、一部のマルチキーコマンド)にハッシュタグ({...})による同一スロット配置が必要。設計時にキー設計とスロット分散のバランスを考慮する。
  • コネクション管理:クライアント側のコネクションプール設定やtimeout/tcp-keepaliveを適切に設定しないと、接続過多やゾンビ接続でmaxclients上限に達することがある。
  • バージョン間の互換性・EOL:Redis 7系以降のライセンス変更(RSALv2/SSPLへの移行、Valkeyへのフォーク発生など)もあり、利用中のバージョンとライセンス、サポート状況は定期的に確認しておく。

まとめ

Redisは「速さ」を軸に据えたデータストアであり、単純なキャッシュから分散システムの構成要素まで幅広く応用できます。データ構造ごとの特性を理解し、永続化戦略やメモリ管理を適切に設計することで、アプリケーション全体のパフォーマンスとスケーラビリティを大きく改善できます。一方で、永続化の誤解やセキュリティ設定の見落とし、ビッグキー問題などは実運用で頻発するトラブルの原因になるため、導入時点で注意点を踏まえた設計をしておくことが重要です。