Redisデータ永続化の種類とサービス稼動時の切り替え注意点


前提

以下は Redis 2.8 以降を前提としています

Redisのデータ永続化の種類

Redisではデータの管理手法として3種類あります。

・メモリでデータを管理する方式(揮発性ベース)
・特定のタイミングでデータをディスクに保存する方式(RDBベース)
・随時データをディスクに保存する方式(AOFベース)

'RDB'や'AOF'とすることでRedisを再起動してもはファイルからメモリにデータを読み込みなおすためデータの永続化がはかれる。というものです。

パフォーマンス劣化などの弊害もあるため、提供するサービスの内容とメリデメを見て選択することになります。

揮発性ベース

データをすべてメモリ内で保有して処理します。
Redisの再起動でデータがすべてロストしてしまうので、これが許容できるケースで利用します。

説明
メリット ・最高パフォーマンス
デメリット ・再起動でデータは全ロスト

設定例  :

    save ""

RDBベース

指定したタイミングでデータをファイルに保存します。(非同期スナップショット)
Redisの再起動において軽微なデータロストが発生するので、それが許容できるケースで利用します。
Redisの'save'ディレクティブで保存タイミングを設定します。

説明
メリット ・高パフォーマンス
デメリット ・再起動で保存前の更新データがロストする

設定例  : save [□□秒以内に保存] [〇〇回更新後]

    dir /var/run/redis              # RDB/AOFの格納ディレクトリを指定する
    dbfilename 6379.rdb             # RDBのファイル名を指定する
    rdbcompression yes              # RDBの圧縮要否を指定する
    save 900 1                      #      1回の更新後 900 秒以内に同期する
    save 300 10                     #     10回の更新後 300 秒以内に同期する
    save 60 10000                   # 10,000回の更新後  60 秒以内に同期する

AOFベース

常にデータをファイルに保存します。(デフォルトは秒単位の保存なので"ほぼ"同期保存となります)
データロストが許容できないケースで利用します。
RDBベースと並行稼動できますが、正直メリットは感じられません。

説明
メリット ・データ毀損が(ほぼ)無い
デメリット ・低パフォーマンス(50〜100倍程度のレスポンス遅延)
・リソース大量消費(データ保存時に格納サイズの倍以上のメモリが必要)

設定例  :

    dir /var/run/redis              # RDB/AOFの格納ディレクトリを指定する
    appendonly yes                  # AOFの利用要否を指定する
    appendfilename 6379.aof         # デフォルトは appendonly.aof となる
    appendfsync everysec            # デフォルトで秒単位に同期する(中速で動作する)
    # appendfsync always            # 常に同期する(低速だが安全に動作する
    # appendfsync no                # OSに任せる(高速に動作する)
    auto-aof-rewrite-min-size 32mb  # AOFのファイルサイズが32MByte以下はリビルド(最適化)の対象外とする
    auto-aof-rewrite-percentage 100 # AOFのファイルサイズが倍増(100%)した場合にリビルド(最適化)する

サービス稼動中の永続化方式変更時の注意点

稼働中のモード変更では、'CONFIG'コマンドによるサービス中のモード変更と設定ファイル(redis.conf)の変更をあわせてしておかないと運用時と再起動時の永続化モードの差異によって運用時のデータがロストしてしまう可能性があります。

データロスト事例

(1)AOFからRDBに切り替えるケース

'AOF'稼動中のRedisをパフォーマンスを高めるため'CONFIG SET'コマンドで'RDB'に切り替えた。
あわせて設定ファイルも'RDB'に変更する予定だったが忘れた。
数日後のサーバ再起動で、設定ファイルが'AOF'ままだったので、'RDB'切り替え前の
古い'AOF'ファイルで起動されてしまい'RDB'で運用していた期間のデータが消えた。

(2)RDBからAOFに切り替えるケース

'RDB'稼動中のRedisを、可用性を高めるため設定ファイルを'AOF'に切り替えた。
あわせて'CONFIG SET'コマンドで'AOF'に切り替える予定だったが忘れてしまった。
数日後のサーバ再起動で、期待どおりに'AOF'起動されたが'AOF'ファイルが存在せず、データなしで起動されてしまい'RDB'で運用されていた再起動前のデータがすべてロストしてしまった。
※ Redisは'RDB'と'AOF'の並行動作時、'AOF' > 'RDB' の優先順でデータを読み込みなおす

(3)RDBからAOFに切り替えるケース

'RDB'稼動中のRedisの可用性を高めるため'CONFIG SET'コマンドで'AOF'に切り替えた。
あわせて設定ファイルも'AOF'に更新する予定だったが忘れた。(='AOF'で運用が継続された)
数日後のサーバ(Redis)再起動で誤った'RDB'設定で起動してしまい、古い'RDB'ファイルで起動された。
('AOF'に切り替え後のデータがすべてロストした)

最後に

Redisは利用する機能の特質上、どんどん更新情報が登録されていくものなので、サービス再開後の切り戻しは厳しい(できない!)ってことを念頭において、より上流工程で永続化方式を決定しておくべきですね。
仕方なく途中で変更する場合は、手順でしくらないよう注意したいと思います。