.. Append Only File HOWTO .. _append_only_file: ====================== 追記専用ファイルモード ====================== .. General Information 一般的な情報 ---------------------- .. Append only file is an alternative durability option for Redis. What this mean? Let's start with some fact: 追記専用ファイルは、Redisを強固にするオプションです。意味が分からない?では、一緒に観ていきましょう: .. * For default Redis saves snapshots of the dataset on disk, in a binary file called dump.rdb (by default at least). For instance you can configure Redis to save the dataset every 60 seconds if there are at least 100 changes in the dataset, or every 1000 seconds if there is at least a single change in the dataset. This is known as "Snapshotting". 標準のRedisでは、データセットをDiskにバイナリでdump.rdbに保存します(初期設定の場合)。データセットに対して、60秒で100回変更が有った時、もしくわ1000秒で1回変更があった時にファイルに保存します、この設定は変更することも出来ます。この動作を"Snapshotting"と呼びます。 .. * Snapshotting is not very durable. If your computer running Redis stops, your power line fails, or you write killall -9 redis-server for a mistake, the latest data written on Redis will get lost. There are applications where this is not a big deal. There are applications where this is not acceptable and Redis was not an option for this applications. Snapshottingは、堅牢性が高いとは言えません。もし、あなたのPCでReidsが動いている最中に電源コードが抜けたら? もし、間違って"killall -9 redis-server"を間違って実行してしまったら?Redisに保存されている最新のデータセットは失われてしまいます。これは、アプリ側に取ってはうれしい話ではありません。There are applications where this is not acceptable and Redis was not an option for this applications. .. What is the solution? To use append only file as alternative to snapshotting. How it works? その問題を解決する為に、Snapshottingに追記専用ファイルを使用します。使うためには? .. * It is an 1.1 only feature. * Ver.1.1のみで使用できます。 .. * You have to turn it on editing the configuration file. Just make sure you have "appendonly yes" somewhere. * 設定ファイルで、" :conf:`appendonly` yes"の項目を有効化します。 .. * Append only files work this way: every time Redis receive a command that changes the dataset (for instance a SET or LPUSH command) it appends this command in the append only file. When you restart Redis it will first re-play the append only file to rebuild the state. * Redisがコマンドを受け取るたびにすべてのコマンドをファイルに追記していきます。Redisを再起動した場合には、コマンドをすべてリプレイしデータセットの状態をリビルドします。 .. Log rewriting ログの書き換えについて ------------------------------ .. As you can guess... the append log file gets bigger and bigger, every time there is a new operation changing the dataset. Even if you set always the same key "mykey" to the values of "1", "2", "3", ... up to 10000000000 in the end you'll have just a single key in the dataset, just a few bytes! but how big will be the append log file? Very very big. データセットに変更があるたびに追記すると、ご想像の通りログファイルはドンドン大きくなります。"mykey"というキーにバリューを'1', '2', '3'....と増やし提起'100000000000'まで増やしていったときログファイルは数バイトですみます。 .. So Redis supports an interesting feature: it is able to rebuild the append log file, in background, without to stop processing client commands. The key is the command BGREWRITEAOF. This command basically is able to use the dataset in memory in order to rewrite the shortest sequence of commands able to rebuild the exact dataset that is currently in memory. Redisは興味深い機能を持っています。追記型のログファイルのリビルドは、クライントからのコマンドプロセスを停止させずにバックグラウンドで動作います。 .. So from time to time when the log gets too big, try this command. It's safe as if it fails you will not lost your old log (but you can make a backup copy given that currently 1.1 is still in beta!). 時間が経つに連れLogがドンドン大きくなってきます。たまにリビルドを行うことで安全に古いログを保管できます。(ただし、Ver1.1のベータの機能で提供されています) .. Wait... but how does this work? .. --------------------------------- ちょっと待って。でもどうやって使うの? ---------------------------------------------------- .. Basically it uses the same fork() copy-on-write trick that snapshotting already uses. This is how the algorithm works: 基本的に、Snapshottingはいつもcopy-on-writeと同じような挙動をとります。 .. * Redis forks, so now we have a child and a parent. * Redisは、親要素と子要素をフォークします。 .. * The child starts writing the new append log file in a temporary file. * テンポラリーファイルの子要素に新規のログを追加します。 .. * The parent accumulates all the new changes in an in-memory buffer (but at the same time it writes the new changes in the old append only file, so if the rewriting fails, we are safe). * メモリー内で親要素はすべての新規子要素を集めます。 .. * When the child finished to rewrite the file, the parent gets a signal, and append the in-memory buffer at the end of the file generated by the child. * 子要素が集まったらファイルを書き換えます。親要素は書き換え完了を受け取るとメモリー内で子要素がファイルに書き込み完了したことを記録します。 .. * Profit! Now Redis atomically renames the old file into the new one, and starts appending new data into the new file. * プロフィット!: Redisは、古いファイルと新しいファイルのリネーム作業などをすべて自動で行ないます。 .. How durable is the append only file? 追記専用ログファイルを使うとどれくらい安全? ---------------------------------------------------------- .. Check redis.conf, you can configure how many times Redis will fsync() data on disk. There are three options: redis.confを見てみよう。あなたはいつでもコンフィギュレーションを変更できます、fsync()に関しては、3つのオプションがあります。 .. * Fsync() every time a new command is appended to the append log file. Very very slow, very safe. .. * Fsync() one time every second. Fast enough, and you can lose 1 second of data if there is a disaster. .. * Never fsync(), just put your data in the hands of the Operating System. The faster and unsafer method. * Fsync() evry time は、すべてのコマンドをログファイルに追記していきます。とてもとても遅いですが、とても安全です。 * Fsync() one time は、毎秒毎にログファイルに追記していきます。十分に高速に動作します。最悪1秒間のデータが失われます。 * Never Fsync() 標準のOSのファイルシステムで保存するモノです。最高に速いですが安全ではありません。 .. The suggested (and default) policy is "everysec". It is both very fast and pretty safe. The "always" policy is very slow in practice, even if it was improved in Redis 2.0.0 there is no way to make fsync() faster than it is. デフォルトの設定では"毎秒”が設定されています。それは、スピードと安全性でバランスの取れた設定です。”always”オプションはとても遅いのです。Redis2.0では、より速い実装が予定されています。 .. What should I do if my Append Only File gets corrupted? もし不正動作に見舞われたら? --------------------------------- .. It is possible that the server crashes while writing the AOF file (this still should never lead to inconsistencies) corrupting the file in a way that is no longer loadable by Redis. When this happens you can fix this problem using the following procedure: 無いとは言えません。追記専用ファイルの書き込み時にサーバがクラッシュして、Redisで読み込み不能なファイルが作成された場合などです。もしこのような事態になった場合は以下の手順を試してください。 .. * Make a backup copy of your AOF file. .. * Fix the original file with: ./redis-check-aof --fix .. * Optionally use diff -u to check what is the difference between two files. .. * Restart the server with the fixed file. * 追記専用ファイルのバックアップコピーを作成してください。 * オリジナルファイルに対してフィックスをかけます。 .. code-block:: nginx ./redis-check-aof --fix * フィックスしたオリジナルファイルとバックアップファイルの2つでDiffを取り差分をチェックしてください。 * フィックスしたファイルでサーバをリスタートしてください。