「Redisが起動しない。ログには『Bad file format』の文字。現場はパニックだ。」
もし君が大規模なシステムのテクニカルリードなら、一度はこの種の悪夢に直面したことがあるはずだ。Redisはメモリ内データストアだが、永続化(AOF/RDB)という「現実界への接点」を持った瞬間に、ディスクI/Oの物理的な限界やOSのクラッシュという泥臭い問題に巻き込まれる。
今日は、その絶望的な状況を打破する最後の切り札、`redis-check-aof` について話をしよう。単なるマニュアルの引き写しではない。このツールが「何を救い、何を切り捨てるのか」という本質を、アーキテクトの視点で叩き込む。
—
1. AOFが「壊れる」とはどういうことか
RedisのAOF(Append Only File)は、実行されたコマンドを逐次テキスト(またはバイナリ混じり)で追記していくログファイルだ。構造はシンプルだが、それゆえに「書き込み途中のクラッシュ」に弱い。
- ディスクフル: 書き込み中に容量が尽き、コマンドが途中で途切れる。
- カーネルパニック/停電: OSのバッファからディスクへのフラッシュが不完全な状態で終了する。
Redisは起動時、このAOFを先頭からリプレイしてメモリ上の状態を復元する。しかし、末尾が中途半端に壊れていると、Redisは「データの整合性が保証できない」と判断し、安全のために起動を拒否する。
ここで登場するのが `redis-check-aof` だ。
—
2. `redis-check-aof` による外科手術
このツールの本質は「修復」ではない。「整合性が取れなくなった末尾の切断(Truncation)」だ。
診断の実行
まずは被害状況を確認する。いきなり修復(fix)をかけるような真似はするな。まずは dry-run だ。
AOFファイルの整合性をチェック
redis-check-aof appendonly.aof
もしファイルが破損していれば、以下のような冷徹な診断結果が返ってくる。
0x 20d: Expected \r\n, got: 6162
AOF analyzed: size=554, fragments=1, main_lines=15, total_fstring=0, …
AOF is not valid. Error at offset 525
執刀:`–fix` オプション
Redisを起動させるためには、この破損箇所(Offset 525以降)を切り捨てるしかない。
データの切り詰めを実行
redis-check-aof –fix appendonly.aof
【注意】 このコマンドを実行した瞬間、破損箇所から後ろのデータは永久に失われる。だが、これを行わなければRedisは1バイトのデータもロードできない。アーキテクトとして、「1%の損失を受け入れて99%を救う」という決断をこのコマンドに込めるのだ。
—
3. Redis 7.0以降の「マルチパートAOF」という変革
モダンなRedis(7.0以降)を扱っているなら、これまでの知識だけでは足りない。Redis 7.0からは「Multi-part AOF」が導入された。
従来は1つの巨大なファイルだったが、現在は以下の3つに分かれている。
1. Base File: `appendonly.aof.1.base.rdb`(スナップショット)
2. Incremental Files: `appendonly.aof.1.incr.aof`(増分ログ)
3. Manifest File: `appendonly.aof.manifest`(管理ファイル)
`redis-check-aof` は、これらのマニフェストファイルを解釈して一貫性をチェックする。もし手動でファイルをリネームしたり移動したりしてマニフェストとの不整合を起こせば、ツールは異常を検知する。
プロのアドバイス:
トラブルシューティングの際、個別の `.aof` ファイルを直接いじるのは避けろ。必ず `redis-check-aof` を通じて、ディレクトリ全体の整合性を見ることが鉄則だ。
—
4. 堅牢な設計へのフィードバック
`redis-check-aof` のお世話になるということは、設計に改善の余地があるということだ。リードエンジニアとして、以下の3点をレビューせよ。
① `appendfsync` 戦略の再考
- `always`: 毎クエリ `fsync` する。壊れにくいが、スループットは最悪だ。
- `everysec`: デフォルト。1秒以内のデータ紛失を許容するバランス型。実務上の最適解。
- `no`: OSに任せる。最速だが、クラッシュ時の破損リスクが最大になる。
② ハイブリッド永続化(RDB Preamble)の活用
AOFの先頭をRDB形式にする `aof-use-rdb-preamble yes` を設定しているか? これにより、AOFのリライトが高速化され、起動時のリカバリ時間も劇的に短縮される。`redis-check-aof` もこの形式に対応している。
③ 自動復旧(aof-load-truncated)の設定
Redisの設定(`redis.conf`)には `aof-load-truncated` という項目がある。
- `yes` (デフォルト): 起動時、末尾が壊れていたらログを出して、自動的に切り詰めて起動する。
- `no`: 起動を停止する。
「えっ、自動で直してくれるならいいじゃないか」と思うかもしれない。だが、厳格なデータ整合性が求められる金融系や決済系のシステムでは、あえて `no` に設定し、人間が `redis-check-aof` で被害状況を確認してから手動復旧させるのが、プロの矜持というものだ。
—
5. パフォーマンスと運用の注意点
`redis-check-aof` は、AOFファイル全体をスキャンする。数GB、数十GBという巨大なAOFファイルを運用している場合、このチェック自体に時間がかかる。
- ディスクI/Oの競合: 稼働中のサーバーで巨大なAOFをチェックすると、ディスク帯域を食いつぶす。必ずバックアップ(コピー)に対して実行するか、スタンバイ機で行え。
- バックアップはAOFだけでいいのか?: AOFはあくまで「操作ログ」だ。週に一度、あるいは一日に一度のRDB(スナップショット)バックアップを併用せよ。AOFが修復不可能なレベルで壊れたとき、君を救うのは古いRDBだ。
—
結論
`redis-check-aof` は、消防斧のようなものだ。出番がないに越したことはないが、いざという時にこれを使えないエンジニアは、火災現場で立ち尽くすしかない。
1. まずは `dry-run` で破損箇所を特定せよ。
2. `–fix` は「データの切断」であると理解せよ。
3. Redis 7.0+ のマルチパート構成を意識せよ。
4. そして、このツールの出番を減らすために `appendfsync` とバックアップ戦略を研ぎ澄ませ。
次に君のチームの若手が「Redisが起動しません!」と泣きついてきたら、冷静にこのツールを差し出し、データの整合性について説いてやるがいい。それがアーキテクトとしての君の仕事だ。
コメント