箱のプログラミング日記。

えんじにあ奮闘記

Redis is configured to save RDB snapshots, but is currently not able to persist on disk.の対処法

f:id:y_hakoiri:20191102121704j:plain

起こったこと

redisに一括でデータを挿入するスクリプトを走らせたところ、急に以下のエラーが発生した

Redis::CommandError:MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.

ディスクに容量がなくてスナップショットを保存できないよ〜みたいなことを言っているらしい。

redisのデータ永続化

redisはインメモリデータベースにより高速処理を可能にしているが、インメモリということはメモリが解放される(起動が停止される)とデータが消失されてしまう。

データの永続化をしたい場合、スナップショットを作成しておき、起動された時にそのスナップショットを読み込むことで以前のデータを復元しているらしい。

今回もデータ挿入にあたりスナップショットを作りたいのにメモリ不足でそれが作れないことでエラーになっている模様。

スナップショットの保存先を確認

ではそのスナップショットはどこに保存されているのかというと

/etc/redis.conf

# The filename where to dump the DB
dbfilename dump.rdb

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /var/lib/redis

ダンプファイルとしてdump.rdbを作成するよ、ディレクトリは/var/lib/redisだよと書いてある。

該当のディレクトリを見てみると

$ sudo ls /var/lib/redis
dump.rdb

dumpファイルがあった。

おそらく前回スクリプトを走らせた時に途中でネットワークが切れて失敗してしまったので、その時のdumpファイルが中途半端に残った状態になってしまい、新しいdumpを作れずエラーになっていた模様。

解決策:dumpファイルを削除

今回はdumpファイルが不要だったので一旦削除しました。

$ sudo rm /var/lib/redis/dump.rdb

で、無事解決できました。

dumpを残しておきたい場合はバックアップとして一旦別ファイルにcpとかしておくと良さそう。

スナップショットの保存設定を確認

デフォルトではredisが終了するタイミングと予め設定ファイルで書かれているタイミングでスナップショットが更新される。

/etc/redis.confを見てみると

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000
  • 1キー変更で900秒後(15分後)に保存
  • 10キー変更で300秒後(5分後)に保存
  • 10000キー変更で60秒後(1分後)に保存

この設定だとデータ1つに何か変更があってもその後15分間はスナップショットが更新されないということなので、その間にサーバーが落ちたらバックアップ取れていないのはしんどいなと思いつつ、今回はテスト用の環境なので一旦スルー

(ここの設定をsave 1 1とかにすればキーの変更があったら毎秒スナップショットも更新してくれるのだろうけど、その辺のパフォーマンスがどうなるかはちょっとわかりません。。^^;)

スナップショットを手動で更新

ちなみにスナップショットは手動での更新もできるようで

127.0.0.1:6379> lastsave
(integer) 1604823931
127.0.0.1:6379> save
OK
127.0.0.1:6379> lastsave
(integer) 1604824101

redis-cliにログインしてsaveコマンドで更新できる模様。(lastsaveでの最終更新時刻の表示はunix時刻)

ただしスナップショットのsaveをしている間はredis自体のデータの書き換えがブロックされてしまうようなので

127.0.0.1:6379> bgsave
Background saving started

バックグラウンドで処理するのが良いらしい。

参考

MISCONF Redis is configured to save RDB snapshots - Qiita

Redisで発生したメモリ不足エラーの調査メモ | ソシャゲの作り方

Redisのデータ永続化