こんにちは、鈴木です。
Redis におけるデータの永続化についてです。
RDB と AOF
Redis におけるデータの永続化には 2 つの方式があります。
一つは RDB ファイル(RDB = Redis DataBase だと思います)に書き出す方式で、あるタイミングのスナップショット(フルダンプ)です。
もう一つは更新系のクエリが逐次追記される AOF (Append Only File) です。
RDB と AOF は両方を有効にすることができ、その場合は RDB と AOF の両方が出力されますが、Redis 起動時には AOF からデータが復元されます。
RDB を保存する
RDB ファイルを保存するには、save ディレクティブで保存するタイミングを指定します。
1 |
save <seconds> <changes> |
上記は「<changes> 回変更されたら、その後 <seconds> 秒以内に保存する」という意味になります。例えば、
1 2 |
# 3 回変更されたら、その後 60 秒以内に保存する save 60 3 |
とすると、「3 回変更されたら、その 60 秒以内に保存」されます。
save ディレクティブは以下のように複数記述することもできます。
1 2 3 |
save 900 1 # 1 回変更されたら、その後 900 秒以内に保存する save 300 10 # 10 回変更されたら、その後 300 秒以内に保存する save 60 10000 # 10000 回変更されたら、その後 60 秒以内に保存する |
RDB を保存したくない場合は、
1 2 |
# RDB を保存しない save "" |
とします。
他にも RDB 関係のディレクティブには以下のものがあります。
1 2 3 4 5 6 7 8 |
# RDB のファイル名 dbfilename dump.rdb # RDB ファイルの保存先ディレクトリ dir /var/lib/redis/6379 # RDB ファイルの圧縮 (RDB 中の文字列を LZF 圧縮) rdbcompression yes |
AOF を保存する
AOF を保存するには、appendonly ディレクティブに yes を指定します。
1 2 |
# AOF を保存する appendonly yes |
また、appendfsync ディレクティブで、AOF に書き出す時にディスクにフラッシュするタイミングを指定することができます。
1 2 3 |
appendfsync everysec # 毎秒フラッシュする # appendfsync always # 常にフラッシュする # appendfsync no # Redis 側では明示的にフラッシュしない (OS に任せる) |
その他のディレクティブとしては、以下のものがあります。
1 2 3 4 5 6 7 |
# AOF のサイズが 100% 以上増加した場合, AOF をリライトする # (リライトすると冗長な内容が削除されるのでファイルがコンパクトになる) auto-aof-rewrite-percentage 100 # しかし, ファイルサイズが 64MB 以下の場合はリライトは行わない # (ファイルが小さい場合にリライトしてもメリットが少ないため) auto-aof-rewrite-min-size 64mb |
AOF は同期書き込みをサポートするが、パフォーマンスは著しく低下する
appendfsync に always を指定すれば AOF へ同期的に書き込まれるので、Redis がクラッシュしてもデータが損失することはありません。
しかし、同期的に書き込む場合とそうでない場合を比較すると 2 桁くらい(100 倍くらい)はパフォーマンスが低下します。
パフォーマンスと永続性のトレードオフを考えると、everysec が落とし所となる場合が多いでしょう。
RDB と AOF の両方を有効にする意味はあるのか?
RDB はデータベースの内容を全てファイルに出力するので、追記するだけの AOF よりも生成に時間がかかります。
一方の AOF は RDB よりもファイルサイズが大きくなるため、バックアップ目的であれば RDB の方が良さそうです。
以上を踏まえると、RDB と AOF の両方を有効にする意味はあると考えます。
AOF を記録しながら、バックアップは RDB ファイルを保存する、という使い分けです。