Redisはインメモリデータベースであり、サーバープロセスが終了するとメモリ内のデータも消失してしまいます。この問題を解決するため、Redisにはデータをディスクに保存する永続化機能が備わっています。
RDB(Redis Database)
RDBはRedis Databaseの略で、指定した時間間隔でメモリ上のデータセットのスナップショットをディスクに書き込む仕組みです。リカバリ時はこのスナップショットファイルを直接メモリに読み込みます。
Redisは永続化処理を行うために子プロセスをフォークします。データはまず一時ファイルに書き込まれ、永続化プロセスが完了した後に、前回の永続化ファイルを置き換えます。このプロセス中、メインプロセスはIO操作を行わないため、非常に高いパフォーマンスが保証されます。大規模なデータ復旧が必要で、データの完全性に対する要求がそれほど高くない場合、RDBはAOFよりも効率的です。ただし、最後の永続化以降のデータは失われる可能性があります。
RDBの設定とテスト
RDBで保存されるファイルのデフォルト名はdump.rdbです。設定ファイルで変更できます。まず設定ファイルを編集し、60秒以内に3回キーが変更された場合にRDB操作がトリガーされるように設定します。
# 設定ファイル例
save 60 3 # 60秒以内に3回の変更があった場合に保存
dir /var/lib/redis # RDBファイルの保存パス
設定を保存した後、Redisサービスを再起動し、既存のRDBファイルを削除する必要があります。
RDBファイルの生成テスト
まずRDBファイルを削除し、次に3つの値を設定します:
127.0.0.1:6388> set key1 value1
OK
127.0.0.1:6388> set key2 value2
OK
127.0.0.1:6388> set key3 value3
OK
60秒以内に3回キーを変更すると、RDB操作がトリガーされ、dump.rdbファイルが生成されます。
トリガー条件
RDBがトリガーされる条件は以下の通りです:
- 設定したsaveルールが満たされた場合
- flushallコマンドが実行された場合
- Redisを終了した場合
RDBファイルからの復旧
RDBファイルをRedisの起動ディレクトリに配置するだけで、Redis起動時に自動的にdump.rdbをチェックし、データを復旧します。保存場所は以下のコマンドで確認できます:
127.0.0.1:6388> config get dir
1) "dir"
2) "/var/lib/redis"
RDBの長所と短所
長所:
- 大規模なデータ復旧に適している
- データの完全性に対する要求が高くない場合に有効
短所:
- 一定の時間間隔での操作が必要なため、Redisが予期せずクラッシュした場合、最後の変更データが失われる可能性がある
- フォークプロセス時に一定のメモリ空間を占有する
AOF(Append Only File)
AOFはAppend Only Fileの略で、すべての書き込み操作をログとして記録します。読み取り操作は記録されません。Redisの起動時にこのファイルを読み込み、書き込みコマンドを先頭から順に実行することでデータを復元します。
AOFの設定
AOFはデフォルトで無効になっており、保存されるファイル名はappendonly.aofです。有効にするには、設定ファイルでappendonlyをyesに設定します。
appendonly yes
appendfilename "appendonly.aof"
設定後、Redisを再起動するとappendonly.aofファイルが生成されます。
AOFへのデータ書き込みテスト
まずクライアントでいくつかのキーを設定します:
127.0.0.1:6388> flushdb
OK
127.0.0.1:6388> set user taro
OK
127.0.0.1:6388> set age 30
OK
127.0.0.1:6388> set city tokyo
OK
AOFファイルの内容を確認すると、実行されたコマンドが記録されていることがわかります:
*2
$6
SELECT
$1
0
*3
$3
set
$4
user
$4
taro
*3
$3
set
$3
age
$2
30
*3
$3
set
$4
city
$5
tokyo
AOFファイルの破損テストと修復
AOFファイルを意図的に破損させ、Redisを再起動すると、起動に失敗します。RedisはAOFファイルにエラーがあると起動できないためです。
このような場合、Redisが提供する修復ツールredis-check-aofを使用します:
redis-check-aof --fix /var/lib/redis/appendonly.aof
修復後、Redisを再起動すると正常に起動します。AOFの修復メカニズムは、基本的にエラーのあるデータを削除するものです。
AOFの追加設定
# appendfsync always # 毎回の変更で同期、パフォーマンスに影響
appendfsync everysec # 毎秒同期、デフォルト設定。1秒のデータ損失可能性あり
# appendfsync no # 同期しない、OSに依存。最速だがデータ損失リスクあり
# AOFファイルの自動書き換え設定
auto-aof-rewrite-percentage 100 # 前回リライトから100%増加したらリライト
auto-aof-rewrite-min-size 64mb # 最低64MB以上でリライトを検討
AOFの長所と短所
長所:
- 毎回同期する場合、データの完全性が高い
- 毎秒同期する場合、最大1秒のデータ損失
- 同期しない場合、最高のパフォーマンス
短所:
- RDBと比較してファイルサイズが大きく、修復速度も遅い
- RDBより動作効率が低いため、Redisのデフォルト設定はRDB永続化
永続化方式の組み合わせとパフォーマンス提案
1. RDB永続化は指定した時間間隔でデータのスナップショットを保存します。
2. AOF永続化はサーバーへの書き込み操作を毎回記録し、サーバー再起動時にこれらのコマンドを再実行してデータを復元します。
3. キャッシュとしてのみ使用する場合、永続化を完全に無効にすることも可能です。
4. 両方の永続化方式を同時に有効にすることもできます。
両方を有効にした場合、Redis再起動時には通常AOFファイルが優先して読み込まれます。なぜならAOFファイルの方が一般的にRDBファイルより完全なデータセットを保存しているためです。ただし、作者はRDBのみを使用することを推奨していません。RDBはデータベースのバックアップに適しており、AOFは常に変化するためバックアップが難しいからです。
パフォーマンスに関する提案:
- RDBファイルはバックアップ用途のみとし、スレーブでのみRDB永続化を行い、15分に1回のバックアップで十分です。
- AOFを有効にする場合、最悪の状況でも2秒以内のデータ損失で済みますが、継続的なIOとAOFリライト時のブロックが不可避です。
- AOFを有効にしない場合、マスター-スレーブレプリケーションで高可用性を実現でき、IO負荷を軽減できます。ただし、マスターとスレーブが同時に停電した場合、数分間のデータが失われる可能性があります。