Redis - データ永続化

概要

Redisはインメモリで高速なデータ参照が優れていますが、メモリ上のデータはサーバがシャットダウンされると消えてしまいます。
データベース情報を保存しておきたいケースは多々ありますので、当然データを永続的に保存する仕組みも存在します。
今回はデータ永続化の設定とその動作について記載します。

・Redisバージョン
redis-6.2.7-1.el9.x86_64
(AlmaLinux 9.4にdnfでインストールしたバージョン)

データ永続化設定

Redisではデフォルトでデータ永続化を行う設定が有効になっていますので、特に設定変更を行わなくてもメモリ上のデータがディスクへ保存されます。マニュアルなどではRedis Database(以下RDBと表記)、スナップショット等と記載されています。

具体的な設定箇所はconfファイルのSNAPSHOTTINGセクションに記載されています。(コメントアウトされていますがデフォルト設定で有効になっています。)

# cat /etc/redis/redis.conf
# save 3600 1
# save 300 100
# save 60 10000

上記設定のそれぞれの意味はマニュアルでは以下のように記載されています。

#   * After 3600 seconds (an hour) if at least 1 key changed
#   * After 300 seconds (5 minutes) if at least 100 keys changed
#   * After 60 seconds if at least 10000 keys changed

(DeepL翻訳)
少なくとも1つのキーが変更された場合、3600秒後(1時間後)
少なくとも100個のキーが変更された場合、300秒後(5分)
少なくとも10000個のキーが変更された場合、60秒後

スナップショットが保存される場所はデフォルトでは以下となっています。保存する場所、保存ファイル名もconfファイルで変更可能です。

# ls -l /var/lib/redis/dump.rdb
-rw-r--r--. 1 redis redis 717138 10月 15 19:48 /var/lib/redis/dump.rdb

RDBの他にAOF(Append Only File)という方法も存在します。
PostgreSQLのWALログ、MySQLのRedoログのようなもので、すべての書き込み操作をログに記録する方法です。
こちらはデフォルトで無効になっているので、confファイルで有効にする必要があります。スナップショットとAOFを合わせて使用することも可能です。

動作確認

RDB方式のスナップショットを取得する間隔の設定は上記で記載した通り、経過時間とその間に更新されたキーの数で指定しますが、日本語訳した文章はいまいちタイミングがわかりにくいです。

「少なくとも100個のキーが変更された場合、300秒後(5分)」

この日本語訳を日本語に意訳すると、「300秒間に100個キーが変更された場合、300秒後にスナップショットが更新される」と読み取れます。
Native英語speakerではないのでDeepL翻訳を使用しましたがモヤモヤ感が拭えないので実際に動作を確認してみました。

デフォルトのsave設定を一つずつ明示的に有効にして確認していきます。

60秒間に10000回更新時の動作:
# systemctl restart redis; \
> sleep 5; \
> grep ^save /etc/redis/redis.conf; \
> ll /var/lib/redis/dump.rdb; \
> date; \
> echo 2000{,,,,} | xargs -n1 -P5 ./save_key_val.sh; \
> date; \
> sleep 62; \
> date; \
> ll /var/lib/redis/dump.rdb
save 60 10000
-rw-r--r--. 1 redis redis 2623981 10月 21 18:44 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 18:44:34 JST
2024年 10月 21日 月曜日 18:44:50 JST
2024年 10月 21日 月曜日 18:45:52 JST
-rw-r--r--. 1 redis redis 2812730 10月 21 18:45 /var/lib/redis/dump.rdb

実施前にredisサービスを再起動してdump.rdbを更新させます。その後10000回データ更新を行いdump.rdbの更新時刻を確認しています。最初のdate結果がデータ投入開始時刻、2つ目がデータ投入完了時刻、3つ目が指定時間経過後(上記では60秒後)のdump.rdbの更新時刻を表示しています。save_key_val.shは指定回数キーと値をRedisに登録するスクリプトです。
上記のように1分後にスナップショットの更新時刻が更新されています。

300秒間に100回更新時の動作:
# systemctl restart redis; \
> sleep 5; \
> grep ^save /etc/redis/redis.conf; \
> ll /var/lib/redis/dump.rdb; \
> date; \
> echo 100 | xargs -n1 ./save_key_val.sh; \
> date; \
> sleep 302; \
> date; \
> ll /var/lib/redis/dump.rdb
save 300 100
-rw-r--r--. 1 redis redis 3005501 10月 21 18:58 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 18:58:16 JST
2024年 10月 21日 月曜日 18:58:18 JST
2024年 10月 21日 月曜日 19:03:20 JST
-rw-r--r--. 1 redis redis 3007402 10月 21 19:03 /var/lib/redis/dump.rdb

3600秒間に1回更新時の動作:
# systemctl restart redis; \
> sleep 5; \
> grep ^save /etc/redis/redis.conf; \
> ll /var/lib/redis/dump.rdb; \
> date; \
> echo 1 | xargs -n1 ./save_key_val.sh; \
> date; \
> sleep 3605; \
> date; \
> ll /var/lib/redis/dump.rdb
save 3600 1
-rw-r--r--. 1 redis redis 3007401 10月 21 19:08 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 19:08:50 JST
2024年 10月 21日 月曜日 19:08:50 JST
2024年 10月 21日 月曜日 20:08:55 JST
-rw-r--r--. 1 redis redis 3007421 10月 21 20:08 /var/lib/redis/dump.rdb

それぞれ設定した通りに指定時間内に指定回数更新された場合、指定時間経過後スナップショットを取得する動作をしていることがわかります。
実際の運用ではsaveの設定はどれか1つではなくデフォルトであるように

# save 3600 1
# save 300 100
# save 60 10000

の3つを同時に設定することになるかと思いますので3つ明示的に設定した状態でも試してみます。

60秒間に10000回更新した場合:
# systemctl restart redis; \
> sleep 5; \
> grep ^save /etc/redis/redis.conf; \
> ll /var/lib/redis/dump.rdb; \
> date; \
> echo 2000{,,,,} | xargs -n1 -P5 ./save_key_val.sh; \
> date; \
> sleep 62; \
> date; \
> ll /var/lib/redis/dump.rdb
save 3600 1
save 300 100
save 60 10000
-rw-r--r--. 1 redis redis 3007420 10月 21 20:13 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 20:13:50 JST
2024年 10月 21日 月曜日 20:14:07 JST
2024年 10月 21日 月曜日 20:15:09 JST
-rw-r--r--. 1 redis redis 3196340 10月 21 20:14 /var/lib/redis/dump.rdb

300秒間に100回更新した場合:
# systemctl restart redis; \
> sleep 5; \
> grep ^save /etc/redis/redis.conf; \
> ll /var/lib/redis/dump.rdb; \
> date; \
> echo 100 | xargs -n1 ./save_key_val.sh; \
> date; \
> sleep 302; \
> date; \
> ll /var/lib/redis/dump.rdb
save 3600 1
save 300 100
save 60 10000
-rw-r--r--. 1 redis redis 3196337 10月 21 20:16 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 20:16:11 JST
2024年 10月 21日 月曜日 20:16:12 JST
2024年 10月 21日 月曜日 20:21:14 JST
-rw-r--r--. 1 redis redis 3198238 10月 21 20:21 /var/lib/redis/dump.rdb

3600秒間に1回更新した場合:
# systemctl restart redis; \
> sleep 5; \
> grep ^save /etc/redis/redis.conf; \
> ll /var/lib/redis/dump.rdb; \
> date; \
> echo 1 | xargs -n1 ./save_key_val.sh; \
> date; \
> sleep 3602; \
> date; \
> ll /var/lib/redis/dump.rdb
save 3600 1
save 300 100
save 60 10000
-rw-r--r--. 1 redis redis 3198237 10月 21 20:23 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 20:23:22 JST
2024年 10月 21日 月曜日 20:23:22 JST
2024年 10月 21日 月曜日 21:23:24 JST
-rw-r--r--. 1 redis redis 3198257 10月 21 21:23 /var/lib/redis/dump.rdb

この時裏で確認していたdump.rdbのタイムスタンプの状態は以下のようになっていました。1時間経過で更新されていることがわかります。

2024年 10月 21日 月曜日 21:23:05 JST
-rw-r--r--. 1 redis redis 3.1M 10月 21 20:23 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 21:23:10 JST
-rw-r--r--. 1 redis redis 3.1M 10月 21 20:23 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 21:23:15 JST
-rw-r--r--. 1 redis redis 3.1M 10月 21 20:23 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 21:23:20 JST
-rw-r--r--. 1 redis redis 3.1M 10月 21 21:23 /var/lib/redis/dump.rdb
2024年 10月 21日 月曜日 21:23:25 JST
-rw-r--r--. 1 redis redis 3.1M 10月 21 21:23 /var/lib/redis/dump.rdb

上記の結果から、「300秒間に100個キーが変更された場合、300秒後にスナップショットが更新される」ということが確認できました。「300秒後」というのはファイルの最終更新日時からの時間となっているようです。

英語のドキュメントを日本語訳してもどのような動作になるのかいまいち理解できませんでしたが、実際に動作させてみて動きが理解できました。定期的にファイルを書き出すような処理は他のプロダクトでも時々見かけます。具体的にどのタイミングになるかはドキュメントにはっきり書いておらずsource codeを解読しなければ解らないようなこともありますが、Redisでは試してみて想定通り(ドキュメント記載の通り)の動作となっていることが分かったので一安心です。source codeを解読は骨が折れるので。

参考サイト

Redis persistence

The self documented redis.conf for Redis 6.2.

お問い合わせ

弊社では様々なサービスを取り扱っております。
詳細はサービス一覧からご覧ください。

お気軽にお問い合わせください。応対時間 9:30-17:30 [ 土・日・祝日除く ]

お問い合わせ
  • X