Redisのデータ永続化

インメモリDBとデータの永続化

前回のRedisの紹介では、Redisの特長や導入手順、基本的な使い方についてご紹介しました。本稿では、インメモリデータベースのデータ永続化についてご紹介します。

Redisはインメモリデータベースであるため、サーバプロセスが終了するとメモリ上のデータも消えてしまいます。そこで、Redisはサーバプロセス終了後もデータを保持するための2種類の機能が用意されています。

RDB

Redisでは特定の時点のスナップショットをRDBファイルとして保存することができます。RDBはデータベースのダンプファイルに相当します。SAVEコマンドおよびBGSAVEコマンドで現時点のスナップショットを保存できます。また、設定により、一定の書き込み数と時間の経過により自動的にデータを保存することもできます。デフォルトの設定は以下のようになっており、条件を満たした場合にデータが自動保存されます。なお、「save “”」と設定することで自動保存を無効化することも可能です。

  • 900秒後に1個以上のキーが変更
  • 300秒後に10個以上のキーが変更
  • 60秒後に10000個以上のキーが変更
save 900 1
save 300 10
save 60 10000

RDBファイルはRedisの起動時に自動的に読み込まれ、前回終了時のデータが復元されます。

AOF (Append Only File)

多くの場合は前述のRDBファイルの自動保存でも十分ですが、サーバプロセスの障害や電源断などが発生した場合、直近の数分程度のデータを失う可能性があります。

この問題を回避するのがAOF (Append Only File)となります。

AOFはデータベースのWAL/REDOログに似た書き込みログで、すべての書き込みコマンドが追記で記録されます。AOFはデフォルトでは1秒ごとにfsyncによりディスクに同期される(appendfsync everysec)ので、データを失う可能性のある期間は1秒以内に抑えられます。なお、1回の書き込みごとにfsyncを呼び出すようにする(appendfsync always)こともできますが、非常に遅くなります。

AOFはデフォルトでは無効です。以下の設定で有効にすることができます。また、RDBと同時に使用することもでき、AOFとRDBを両方有効にすることが推奨されています。

appendonly yes

AOFファイルはRedisの起動時に自動的に読み込まれます。AOFファイルとRDBファイルの両方が存在する場合はAOFファイルが優先されます。なお、AOFファイルが存在しない状態でAOFを有効にして再起動すると空のAOFファイルを作成するため、すべてのデータが初期化されてしまうのでご注意ください。

バックアップ

RDB

前述の通り、SAVEコマンドもしくはBGSAVEコマンドで現時点のデータのスナップショットをRDBファイルに保存することができます。SAVEコマンドは他のクライアントからのアクセスをすべてブロックしてしまうため、通常はバックグラウンドでデータを保存するBGSAVEコマンドを使用します。BGSAVEコマンドが完了したかどうかはLASTSAVEコマンドで確認できます。RDBファイルはRedisサーバプロセス終了時にも保存されます。

127.0.0.1:6379> save #保存が完了するまで他の操作はすべてブロックされる
OK
127.0.0.1:6379> lastsave #最終保存時刻(Unix時間)を確認
(integer) 1559267764
127.0.0.1:6379> bgsave #バックグラウンドで保存(すぐに処理が返ってくる)
Background saving started
127.0.0.1:6379> lastsave #最終保存時刻が更新されていることを確認
(integer) 1559267778

RHEL 7 / CentOS 7のRemiリポジトリのRedisパッケージでは、デフォルトで以下の場所にRDBファイルが保存されます。

/var/lib/redis/dump.rdb

このファイルを別の安全な場所に保存します。なお、RDBファイルはアトミックに作成されるので、中途半端な状態のファイルを保存してしまう心配はありません。

# cp /var/lib/redis/dump.rdb /path/to/redis-dump-YYYYMMDD.rdb

redis-check-rdbコマンドでRDBファイルの正常性を確認することができます。

# redis-check-rdb /tmp/redis-backup-20190531.rdb
[offset 0] Checking RDB file /tmp/redis-backup-20190531.rdb
[offset 26] AUX FIELD redis-ver = '5.0.5'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1559268270'
[offset 67] AUX FIELD used-mem = '1860912'
[offset 83] AUX FIELD aof-preamble = '0'
[offset 85] Selecting DB ID 0
[offset 14677] Checksum OK
[offset 14677] \o/ RDB looks OK! \o/
[info] 6 keys read
[info] 0 expires
[info] 0 already expired

AOF

RDBのみ有効にした状態からAOFを有効にするには以下のようにします。なお、redis.confのみ修正して再起動すると、前述の通りすべてのデータが初期化されてしまうのでご注意ください。

# redis-cli config set appendonly yes
OK
# vi /etc/redis.conf
appendonly no
↓ 修正
appendonly yes

デフォルトでは以下の場所にAOFファイルが保存されます。

/var/lib/redis/appendonly.aof

AOFは追記型のため、RDBに比べてファイルサイズが大きくなります。そのためバックアップの取得にはRDBが適しています。BGREWRITEAOFコマンドでAOFを再構成し、ファイルサイズを縮小できます。再構成は自動でも行われます。

# ls -l /var/lib/redis/
合計 64152
-rw-r--r--. 1 redis redis 65614804 5月 31 11:32 appendonly.aof
-rw-r--r--. 1 redis redis 21887 5月 31 11:33 dump.rdb
# redis-cli bgrewriteaof
Background append only file rewriting started
# ls -l /var/lib/redis/
合計 48
-rw-r--r--. 1 redis redis 21887 5月 31 11:37 appendonly.aof
-rw-r--r--. 1 redis redis 21887 5月 31 11:33 dump.rdb

redis-check-aofコマンドでAOFファイルの正常性を確認することができます。

# redis-check-aof /var/lib/redis/appendonly.aof
The AOF appears to start with an RDB preamble.
Checking the RDB preamble to start:
[offset 0] Checking RDB file /var/lib/redis/appendonly.aof
[offset 26] AUX FIELD redis-ver = '5.0.5'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1559269522'
[offset 67] AUX FIELD used-mem = '1859808'
[offset 83] AUX FIELD aof-preamble = '1'
[offset 85] Selecting DB ID 0
[offset 14677] Checksum OK
[offset 14677] \o/ RDB looks OK! \o/
[info] 6 keys read
[info] 0 expires
[info] 0 already expired
RDB preamble is OK, proceeding with AOF tail...
AOF analyzed: size=65614804, ok_up_to=65614804, diff=0
AOF is valid

リストア

RDB

AOFは無効で、RDBのみ使用している場合は以下のようにしてリストアします。

1. Redisを停止

# systemctl stop redis

2. RDBファイルを書き戻す

# mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak
# cp /path/to/redis-dump-YYYYMMDD.rdb /var/lib/redis/dump.rdb
# chown redis:redis /var/lib/redis/dump.rdb

3. Redisを起動

# systemctl start redis

AOF

AOFファイルからリストアする場合は次のようにします。

1. Redisを停止

# systemctl stop redis

2. AOFファイルを書き戻す

# mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak (RDBも有効の場合)
# mv /var/lib/redis/appendonly.aof /var/lib/redis/appendonly.aof.bak 
# cp /path/to/redis-appendonly-YYYYMMDD.aof /var/lib/redis/appendonly.aof
# chown redis:redis /var/lib/redis/appendonly.aof

3. Redisを起動

# systemctl start redis

RDB (AOF有効時)

AOFを有効にしている場合にRDBファイルからリストアする場合は注意が必要です。前述の通り、AOFファイルがない場合は起動時に空のAOFファイルを作成し、そちらを参照するため、RDBファイルを配置しても無視されてデータが初期化されてしまいます。そのため、以下の手順のように、AOFを一時的に無効化してRDBファイルからリストアした後AOFを再作成し、AOFの設定を有効化する必要があります。

1. Redisを停止

# systemctl stop redis

2. RDBファイルを書き戻す

# mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak
# mv /var/lib/redis/appendonly.aof /var/lib/redis/appendonly.aof.bak
# cp /path/to/redis-dump-YYYYMMDD.rdb /var/lib/redis/dump.rdb
# chown redis:redis /var/lib/redis/dump.rdb

3. AOFを無効化してRedisを起動

# vi /etc/redis.conf
appendonly yes → appendonly no

# systemctl start redis

4. AOFファイルを書き出す

# redis-cli bgrewriteaof
Background append only file rewriting started
# redis-cli info | grep aof_rewrite_in_progress
aof_rewrite_in_progress:0
# ls -l /var/lib/redis/
合計 80
-rw-r--r--. 1 redis redis 14677 5月 31 15:21 appendonly.aof
-rw-r--r--. 1 redis redis 21887 5月 31 11:37 appendonly.aof.bak
-rw-r--r--. 1 redis redis 14677 5月 31 15:19 dump.rdb
-rw-r--r--. 1 redis redis 21887 5月 31 14:33 dump.rdb.bak

5. AOFを有効化してRedisを再起動

# systemctl stop redis
# vi /etc/redis.conf
appendonly no → appendonly yes
# systemctl start redis

おわりに

Redisはインメモリデータベースですが、データの永続化が可能となっています。Redisのバックアップ・リストアも非常に簡単で、AOFにより耐障害性の向上も図ることができます。しかしながら、RDBとAOFを両方使用する場合の操作については注意が必要なところがあります。