「たかがディレクトリ設定、デフォルトの `/var/lib/redis` やカレントディレクトリのままでいいだろう」――もしあなたがそう考えているなら、そのシステムは近い将来、確実にサイレントな突然死を迎える。
Redisの `dir` 設定は、単に「RDB(スナップショット)やAOF(Append Only File)をどこに置くか」を決めるだけのパラメータではない。それは、RedisのI/Oパフォーマンス、データ耐久性、そしてサービス継続性を左右する「ストレージアーキテクチャの起点」である。
今回は、数々の修羅場をくぐり抜けてきたチーフアーキテクトの視点から、Redisの `dir` 設定における極限の設計思想と、本番環境で絶対に踏んではならない地雷、そしてそれを回避する堅牢な構築パターンを徹底的に解説する。
—
1. `dir` 設定の基本動作と、誰もが一度は踏むパーミッションの罠
まずは基本を整理するが、ここにも落とし穴がある。
`dir` 設定は、Redisが永続化データ(RDBファイルおよびAOFファイル)を出力する絶対パスを指定する。
redis.conf
データの保存先ディレクトリ(末尾のシラバス/は不要)
dir /var/lib/redis
この設定に対し、RDBファイル名(`dbfilename`)やAOFファイル名(`appendfilename`)が結合され、最終的な出力先が決定される。
実務で頻発するパーミッションエラー
新規構築時や、マウントポイントを変更した際に最も多いトラブルが、Redisプロセス実行ユーザーの権限不足だ。
Redisはデフォルトで `redis` ユーザー(あるいはセキュリティを考慮した非特権ユーザー)で実行される。もし `/data/redis` を手動で作成し、所有者を `root` のままにしていた場合、Redisは起動時にエラーを吐くか、起動できても最初の `BGSAVE`(バックグラウンド保存)のタイミングでクラッシュする。
典型的なエラーログ
[12345] 01 Jan 12:00:00.000 # Failed opening .rdb for saving: Permission denied
[12345] 01 Jan 12:00:00.000 # Failed saving the DB: Permission denied
解決策:
ディレクトリの作成と同時に、Redis実行ユーザーへの所有権譲渡と適切なパーミッション付与を徹底せよ。コンテナ環境(Docker/Kubernetes)であれば、ボリュームマウント時の `securityContext` や `chown` の設定をコード化しておく必要がある。
所有者をredisユーザーに変更
sudo chown -R redis:redis /data/redis
必要最小限の権限(700)を付与
sudo chmod 700 /data/redis
—
2. 極限の設計パターン:本番環境におけるストレージ戦略
本番環境でRedisを運用する場合、`dir` に指定するストレージメディアの選定とパーティション設計には、ロジカルな戦略が求められる。
【アンチパターン】システムルート(`/`)やログディレクトリと同居させる
最も避けるべきは、OSが動くルートパーティションや、アプリケーションのログが出力される `/var/log` と同じ物理ディスク(または同じボリューム)に `dir` を設定することだ。
- I/Oの干渉: AOFの毎秒同期(`appendfsync everysec`)が有効な場合、OSやアプリケーションのログ書き込みによるディスクI/Oスパイクが、Redisのメインスレッドをブロックする(AOF write stall)。
- Disk Fullによる突然死: ログファイルが肥大化してディスク容量が100%になった瞬間、Redisへの書き込みコマンドはすべて拒否される(`MISCONF Redis is configured to save RDB snapshots…` エラー)。
【ベストプラクティス】専用の高速ストレージを独立マウントする
Redisの永続化ディレクトリには、「OSや他プロセスと競合しない、専用の物理ボリューム(NVMe SSD、またはプロビジョンドIOPSが保証されたクラウドストレージ)」を割り当て、独立したマウントポイント(例: `/data/redis`)に割り当てるのが鉄則だ。
[物理/仮想ディスク (NVMe SSD)]
│
└─── [独立したファイルシステム (ext4 / XFS)]
│
└─── [マウントポイント: /data/redis] <-- ここを Redis の `dir` に指定する
このように分離することで、仮にアプリケーションログがディスクを圧迫してもRedisは影響を受けず、またRedisの激しいI/OがOSの動作を阻害することもない。
---
3. パフォーマンスと堅牢性を両立する「ディスク容量設計」の数式
「メモリが32GBだから、ディスクも32GBあれば足りるだろう」――。この甘い見積もりは、最初の `BGSAVE` または `BGREWRITEAOF`(AOF再構築)の実行時にシステムを破壊する。
RedisがRDBを保存する際、あるいはAOFをリライトする際、「一時ファイル」を作成し、書き込みが完全に完了した時点で古いファイルとアトミックに差し替える(`rename`)という挙動をとる。
つまり、書き込みのピーク時には、古いファイルと新しいファイルが同時にディスク上に存在する瞬間がある。
必要な空き容量の見積もり式
安全な運用を担保するための最低限のディスク容量($Disk_{required}$)は、以下の数式で定義される。
$$Disk_{required} \ge (Memory_{used} \times 2) + \text{バッファ安全マージン (20-30\%)}$$
実際には、CoW(Copy-on-Write)によるメモリのオーバーヘッドも考慮する必要があるが、ディスク容量に関しては「メモリ実容量の最低3倍」、AOFを有効にしている場合は「AOFファイルが肥大化した状態(AOF重なり)を考慮して4〜5倍」のディスクスペースを確保しておくのが、プロフェッショナルの設計基準だ。
—
4. サービスを止めずに `dir` を変更する「オンライン・マイグレーション」
運用中、ディスクの摩耗や容量不足により、Redisを停止させることなく永続化ディレクトリを別のマウントポイント(例: より大容量のボリューム)へ移行しなければならない局面がある。
Redisは、稼働したまま `dir` を動的に変更し、データを移行する術を提供している。
動的移行の実行ステップ
以下に、稼働中のRedisのデータディレクトリを `/var/lib/redis` から `/mnt/new-fast-ssd/redis` へ無停止で移行する手順を示す。
1. 移行先のディレクトリを作成し、適切な権限を付与する
sudo mkdir -p /mnt/new-fast-ssd/redis
sudo chown redis:redis /mnt/new-fast-ssd/redis
sudo chmod 700 /mnt/new-fast-ssd/redis
次に、`redis-cli` から動的に設定を変更する。
2. Redisに接続
redis-cli
3. 現在の dir 設定を確認
127.0.0.1:6379> CONFIG GET dir
1) “dir”
2) “/var/lib/redis”
4. dir 設定を新しいパスに動的変更
127.0.0.1:6379> CONFIG SET dir /mnt/new-fast-ssd/redis
OK
5. 即座に BGSAVE を実行し、新しいディレクトリに最新のRDBを書き出させる
127.0.0.1:6379> BGSAVE
Background saving started
6. 保存が完了したか確認(Last Save Time の更新やログで判断)
127.0.0.1:6379> LASTSAVE
(integer) 1704071234 # タイムスタンプが更新されていればOK
極めて重要なステップ:
`CONFIG SET` はメモリ上の設定を変更したに過ぎない。Redisが再起動した際にもこの設定を維持するため、必ず `CONFIG REWRITE` を実行して `redis.conf` を書き換えること。
7. 設定ファイル(redis.conf)に現在のメモリ上設定を永続化
127.0.0.1:6379> CONFIG REWRITE
OK
これで、次回起動時も新しい高速SSDのディレクトリが読み込まれる。旧ディレクトリ(`/var/lib/redis`)に残った古いファイルは、安全が確認された後に手動で削除すればよい。
—
5. チーフアーキテクトが贈る「dir設計」の極限チェックリスト
あなたの設計書、あるいはレビュー対象のコードに以下の不備がないか、最後に確認してほしい。
- [ ] 専用ボリューム化: Redisの `dir` は、OSや他アプリケーションのI/Oと完全に分離された独立ボリュームを指しているか?
- [ ] 書き込み権限の保証: `redis` ユーザー(または実行コンテナユーザー)に対して `chmod 700` かつ `chown` が適切に設定されているか?
- [ ] 容量バッファの確保: 永続化ディレクトリがあるディスクの空き容量は、最大メモリ使用量の「最低3倍以上」を維持できるよう監視(アラート閾値70%など)が設計されているか?
- [ ] I/Oスケジューラとの相性: SSD/NVMeを使用している場合、OS側のI/Oスケジューラが `none` または `noop` に設定され、ハードウェアの性能を限界まで引き出せているか?
- [ ] 自動構成管理の徹底: `CONFIG REWRITE` の実行手順、あるいは Ansible/Terraform/Helm チャートにおける `dir` 設定の不整合を防ぐ仕組みがコード化されているか?
結論
`dir` 設定とは、Redisという「超高速なインメモリ・データベース」が、唯一「物理的な現実世界(ストレージ)」と交わる接点である。
インメモリの速度に目を奪われ、この接点の設計を疎かにする者は、本番運用の冷酷なディスクI/Oボトルネックによって手痛い洗礼を受けることになる。堅牢なストレージ戦略を組み込み、いかなるスパイクにも揺るがない、真にタフなRedisシステムを構築してほしい。
コメント