Redisバックアップとリストアの極意:RDBとAOFの深淵を覗く
テックリードの私だ。コードレビューや設計レビューで、Redisの永続化設定について「とりあえずデフォルトで」とか「よく分からないからRDBとAOFのどっちも全開にしている」といった甘い設計を見かけるたびに、私は赤べこのように首を縦に振るのをやめている。
Redisは「インメモリDBだから速い」という免罪符のもと、その裏側にあるデータ消失リスクやI/Oの呪縛から目を背けられがちだ。しかし、実務の現場で大規模なトラフィックを捌くシステムにおいて、バックアップとリストアのメカニズムを理解していないのは、時限爆弾を抱えて高速道路を逆走するようなものだ。
今回は、Redisの永続化の核心であるRDBスナップショットとAOF(Append Only File)の仕組み、そして障害時に一秒でも早くサービスを復旧させるための実践的な知見を、容赦なく叩き込む。
—
1. 永続化の二大巨頭:RDB vs AOF の本質を見極めろ
Redisのデータを安全にディスクへ残す手段は、歴史的にこの2つに集約される。それぞれの「本質」と「トレードオフ」を物理レベルで理解してほしい。
RDB (Redis Database) スナップショット
ある一瞬のメモリ上のデータを、そのままバイナリ形式(`.rdb`)でディスクにゴリッと書き出す方式だ。
- メリット: ファイルサイズがコンパクト。起動時のロード速度が圧倒的に速い。
- デメリット: スナップショット生成間隔(例: 5分に1回)の間に障害が起きた場合、その間のデータは確実に消滅する。
AOF (Append Only File)
Redisが受け取った書き込みコマンド(`SET`, `HSET`など)を、テキスト(プロトコル形式)でファイルにひたすら追記していく方式だ。
- メリット: データ損失のリスクを極小化できる(最大でも直近1秒程度、あるいは毎リクエスト)。
- デメリット: ファイルサイズが肥大化しやすい。起動時にすべてのコマンドを再実行(Replay)するため、リストアに時間がかかる。
> 【チーフアーキテクトの現場判断】
> 「どちらか一方を選ぶ」という時代遅れの議論はやめよう。現代の堅牢な設計では、RDBで全体のベーススナップショットを抑えつつ、AOFで差分の取りこぼしを防ぐ「ハイブリッドモード(Redis 4.0以降)」がデファクトスタンダードだ。
—
2. スナップショット生成の裏側:`SAVE` と `BGSAVE` の罠
バックアップを手動、あるいは設定ファイルで制御する際、最もやってはいけないのが本番環境での `SAVE` コマンドの使用だ。
`SAVE` —— すべてを停止させる悪魔のコマンド
`SAVE` は、Redisのメインスレッドを完全にブロックしてRDBファイルを生成する。
シングルスレッドで動作するRedisにおいて、数GBもあるメモリ空間をディスクに吐き出している間、すべてのクライアントリクエストは完全にフリーズする。秒間数万件をさばくAPIサーバーでこれを実行しようものなら、瞬く間にコネクションプールの枯渇とタイムアウトの嵐を引き起こすだろう。本番環境で `SAVE` を叩いた瞬間、あなたは戦犯となる。
`BGSAVE` —— forkのコストとCopy-on-Writeの現実
本番環境で使うべきは `BGSAVE` だ。これは、OSの `fork()` システムコールを呼び出し、子プロセスにバックアップの書き出しを非同期で行わせる。
[Client] —> Redis Main Process (メモリ上)
│
├── fork() ──> Child Process (バックアップ書き出し専任)
│ │
▼ ▼
通常通りリクエスト処理 Diskへ .rdb を書き出し
しかし、ここでエンジニアなら知っておくべきOSレベルの罠がある。`fork()` は瞬間的とはいえ、メモリのページテーブルを複製する。
もしRedisの使用メモリが20GBに達している場合、`fork()` の瞬間にメモリ不足(OOM Killerの標的)や、ページテーブルコピーのオーバーヘッドによる数ミリ秒〜数百ミリ秒のレイテンシスパイクが発生し得る。
さらに、バックアップ中にメインプロセスがデータを書き換えると、Copy-on-Write (CoW) により物理メモリの消費量が一時的に倍増するリスクがある。メモリ使用率は常に上限の50%〜60%程度に抑えておくのが、シニアエンジニアの正しいリソース管理だ。
—
3. 実践:坚牢なAOF設計と設定値のチューニング
AOFを有効にする際、`appendfsync`(ディスクへの同期タイミング)のパラメータ選定がシステムの運命を分ける。
redis.conf の要塞設定
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
- `appendfsync everysec` (推奨):
1秒に1回、OSのバッファからディスクへフラッシュする。パフォーマンスと耐久性の美しい妥協点。万が一の障害時でも、失われるのは最大1秒分のデータだ。
- `appendfsync always`:
すべての書き込みごとにディスク同期(`fsync`)を強制する。データロストはゼロだが、ディスクI/Oの性能限界に引き摺り回され、Redisの速度はSSDの速度に縛られることになる。ベンチマークでよほど余裕があると証明されていない限り、使うべきではない。
- `appendfsync no`:
OSのフラッシュ方針に丸投げする。危険すぎるため、揮発しても良いキャッシュ用途以外では論外だ。
また、AOFは追記型であるため、放置すれば無限に肥大化する。`auto-aof-rewrite-percentage` を設定し、ファイルサイズが前回の2倍かつ64MBを超えたら、自動的にバックグラウンドで冗長なコマンドを削ぎ落とした最小限のAOFファイルに再構築(Rewrite)させることが必須だ。
—
4. 障害からの生還:データ復旧(リストア)の手順
さあ、最悪の事態だ。サーバーが吹き飛んだ、あるいは誤ってデータを消してしまった。冷静に以下の手順でリストアを遂行する。
Step 1: Redisプロセスの停止
まずはゾンビプロセスや中途半端に起動しているインスタンスを完全にシャットダウンする。
sudo systemctl stop redis
または
redis-cli shutdown
Step 2: バックアップファイル(RDB/AOF)の配置
安全なストレージ(S3や別サーバーのバックアップ置き場)から、正しい時点の `dump.rdb` と `appendonly.aof` を、Redisのデータディレクトリ(例: `/var/lib/redis`)に配備する。
ファイルのパーミッションが `redis:redis` になっていることを確認しろ。ここをrootのまま起動してハマる若手が後を絶たない。
sudo chown redis:redis /var/lib/redis/dump.rdb
sudo chown redis:redis /var/lib/redis/appendonly.aof
Step 3: 破損ファイルのチェック(重要)
もしAOFファイルがクラッシュで中途半端に途切れている場合、そのまま起動するとRedisは起動エラーを吐くか、最悪の場合起動ループに陥る。
Redis同梱の検証ツールでファイルを健全化しておけ。
AOFファイルの整合性チェックと修復
redis-check-aof –fix /var/lib/redis/appendonly.aof
ログに “Successfully truncated AOF” と表示されれば、壊れた末尾の数バイトが綺麗に切り落とされている。
Step 4: Redisの起動と整合性確認
準備が整ったらサービスを起動する。
sudo systemctl start redis
ログ(`/var/log/redis/redis-server.log`)を監視し、RDBのロードとAOFのReplayが正常に完了したことを確認する。
ログのリアルタイム監視
tail -f /var/log/redis/redis-server.log
出力例:
1:M 01 Jan 2026 10:00:00.123 DB loaded from disk: 0.45 seconds
1:M 01 Jan 2026 10:00:00.567 DB loaded from append only file: 1.12 seconds
1:M 01 Jan 2026 10:00:00.568 The Server is now ready to accept connections on port 6379
最後に、`redis-cli` で `INFO persistence` や `DBSIZE` を叩き、想定通りのキー数が復元されているかを自分の目で確かめろ。
—
チーフアーキテクトからの最終提言
Redisのバックアップは、「ファイルを置けば終わり」の静的なものではない。
`fork()` のメモリ負荷、ディスクのI/O帯域、AOF Rewriteのタイミング、そして定期的な「リストア演習」の実施。これらすべてをシステム設計に組み込んで初めて、プロフェッショナルなインフラ・アプリケーション設計と言える。
「動いているから大丈夫」ではなく、「いつ壊れても、手順通りに◯分以内に復旧できる」という状態をコードとインフラで担保すること。それが、我々エンジニアが守るべきプロの美学だ。
コメント