Redis の内部を探ってみる (aof)

Redis の内部を探ってみる (save) の続き、今回は appendonlyfile について見てみよう。
と思ってたらRedis Persistence (redis.io) に全部書いてあるじゃない...

更新系コマンドについて、レスポンスを返す前にずっとログファイルに追記して、最起動時にはそれを順番にリプレイするんですね。
save はある瞬間の dump でしかないので、電源障害などの時に最後の save 以降のデータを失うが appendonlyfile を有効にすることで回避できる、その分レスポンスタイムは悪くなる。
ファイルへの書き込みの sync タイミングを

  • 常に sync
  • 1秒おきに sync (default)
  • 明示的な sync を行わない

から選べる。(上側がより遅い)
同じキーの更新を続けると無駄にファイルが肥大化する(counterのincrementとか)ので save と同様の仕組みで fork してその時点の dump からの追記へと作りなおすことができる。この処理中の変更はメモリに溜めておいて処理後に追加するが、処理中も古いファイルへ書き込みを続けているので安全。

ちなみに shutdown 時には sync される、aof が無効で save が有効な場合は shutdown 時に save されるので、正常は Redis の再起動ではデータは失われない。

ドットインストールに Redisの基礎 (全14回) ができてみたいです。

『Redisの基礎 (全14回)』をドットインストールに追加しました #dotinstall

Redis の内部を探ってみる (save)

Redis の versin up ついでに内部を軽く探ってみる
対象の version は 2.6.7

Redis を起動すると


WARNING overcommit_memory is set to 0! Background save may fail under low memory
condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf
and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to
take effect.

と表示されることから、save って fork した子供がコピーされたメモリを dump してるのかぁと想像し、実際にコードを見てみることにした。

rdb.c の rdbSaveBackground() の中で fork して書き出している。
fork した子供を看取るのは redis.c の serverCron() がずっと looop で動いていて、いろんな処理をしてる中の一つの仕事で rdb.c の backgroundSaveDoneHandler()。rdbSaveBackground() を実行するのも serverCron() の中。

ということで、save (dump) 処理でレスポンスが落ちるとしたらそれは save 中に更新が多くてメモリの Copy on write が沢山発生する場合なんだろうな。

次回は aof (AppendOnlyFile) を調べてみる。