Redis
 Computer >> コンピューター >  >> プログラミング >> Redis

Redisレプリカのキー数が減って見える本当の理由――データは失われていない

はじめに

Redisで有効期限付きのキー(「揮発性(volatile)」キー)を運用していると、新しくレプリカを追加した瞬間に戸惑うことがあります。レプリカ側で確認できるキー数が、プライマリDBよりも大幅に少なく表示されるのです。特に、揮発性キーを大量に保有している環境では、この現象が頻繁に観察されます。

「レプリカからキーが消えてしまったのでは?」「データを失ったのでは?」――結論から言えば、その心配はありません。データは失われていません。ただし、なぜレプリカのキー数が少なく報告されるのかを理解しておくことは、トラブルシューティングや監視設計の面でも役立ちます。この挙動には、次の2つのRedisの実装詳細が関係しています。

  • Redisが揮発性キーを期限切れにする仕組み
  • Redisが新しいレプリカへデータセットを転送する仕組み

Redisは揮発性キーをどのように期限切れにするのか?

Redisでは、揮発性キーは有効期限が到来したその瞬間にメモリから削除されるわけではありません。実際には、以下の2つの方法のいずれかによって削除されます。

  1. アクセス時の削除:クライアントがあるキーに対して読み取り・書き込み操作を行うと、Redisサーバーはまずそのキーが存在し、有効期限(TTL)が設定されているかを確認します。キーが存在し、かつ有効期限がすでに過去であれば、コマンドを処理する前にそのキーを即座にメモリから排除します。

  2. バックグラウンドでのサンプリング削除:アクセスされない揮発性キーがメモリに永久に残り続けないよう、Redisはシンプルな受動的(passive)アルゴリズムを採用しています。10ミリ秒ごとにランダムな揮発性キーを100個サンプリングし、有効期限が過ぎているものを即座に削除します。ここで25個以上のキーが削除された場合には、さらに100個のキーを対象に同じ処理を繰り返します。

2つ目の方式がポイントです。この仕組みにより、「すでに論理的には期限切れだが、まだ物理的にはメモリに残っている」揮発性キーが相当数存在しうることになります※1。こうしたキーは実際に削除されるまで、INFOコマンドの出力におけるkeysexpiresの各カウントに含まれ続けます。

Redisは新しいレプリカへデータセットをどう送るのか?

レプリカがRedisサーバーに接続すると、プライマリサーバーは自身のデータセット全体のRDBスナップショットを作成し、それをレプリカへ送信します。ここで重要なのが、RedisがRDBスナップショットを生成する際の挙動です。RDBスナップショットには、有効期限がすでに過去となっているキーは一切含まれません。たとえそれらのキーがまだメモリ上に残っていたとしても同様です。

では、なぜレプリカのキー数はプライマリより少なくなるのか?

以上を踏まえると答えはシンプルです。レプリカをRedisインスタンスに接続すると、レプリカが受け取るデータセットには、プライマリDB上で「期限切れ済みだがまだメモリに残っている」揮発性キーが含まれないためです。結果として、レプリカ側の初期キー数はプライマリの表示値より少なくなります。

これは、RDBバックアップからRedisサーバーを復元した際にキー数が減って見える現象と、まったく同じ理由によるものです。

運用上の補足

なお、レプリケーション同期完了後も、プライマリとレプリカそれぞれで期限切れキーの削除処理が独立して動作するため、時間の経過とともに両者のキー数は自然と収束していきます。監視を設計する際は、同期直後の一時的なキー数の差異をアラート条件に含めないなど、この挙動をあらかじめ考慮しておくと安心です。

※RDBの挙動の特定にご協力いただいた@mattstaに感謝いたします。


※1:実際には、Redisが常時削除候補のキーを探し続けているため、この数値は通常もっと小さくなります。

  1. Redisキーの基本と管理コマンド一覧|DEL・EXPIRE・TTLなどの使い方を解説

    Redisにおけるキー(Key)は、データベースに格納された値を識別・保存・取得するための一意な識別子として機能します。キーはredis-cliから各種Redisコマンドを実行することで自由に管理でき、値の追加・削除だけでなく、有効期限の設定や名前の変更なども行えます。 本記事では、Redisのキー操作に使われる代表的なコマンドを一覧形式で解説します。日々の開発や運用でキーを扱う際のリファレンスとしてご活用ください。 基本構文 Redisのキーコマンドは、以下の形式で記述します。 redis host:port> <コマンド名> <キー名> 実行例 Redisキ

  2. RedisのKEYSコマンド徹底解説 – パターンに一致するキーを取得する方法

    このチュートリアルでは、redis-cliで使えるKEYSコマンドを使って、Redisデータストアに保存されている1つ以上のキーを取得する方法を解説します。 KEYSコマンドは、指定したパターンに一致するキーをすべて返すコマンドです。パターンはglobスタイル(グロブ形式)で指定します。 globスタイルのパターン一覧 * (アスタリスク): スペースを含む任意の0文字以上に一致します。例えば foo* は fooccc、foo、fooq などにマッチします。 ? (クエスチョンマーク): スペースを含む任意の1文字に一致します。例えば f?o は fao、fbo、fco などにマッチします