RedisのRDB持続化とAOF持続化の違い

5682 ワード

RDBメカニズムの利点と省略
RDB永続化とは、メモリ内のデータセットスナップショットを所定の時間間隔でディスクに書き込むことです.
メモリ内のデータをスナップショットでバイナリファイルに書き込むデフォルトの永続化方式でもあり、デフォルトのファイル名はdumpである.rdb.
スナップショットの持続性を自動的に設定する方法を設定できます.Redisはn秒以内にm個以上のkeyが変更されたら自動的にスナップショットを作成するように構成できます.以下はデフォルトのスナップショット保存構成です.
 save 900 1     #900      1 key   ,         
 save 300 10    #300      10 key   ,        
 save 60 10000

RDBファイル保存プロセス
redisはforkを呼び出し、サブプロセスと親プロセスがあります.
親プロセスはclientリクエストを処理し続け、サブプロセスはメモリの内容を一時ファイルに書き込む責任を負います.OSの書き込み時レプリケーションメカニズム(copy on write)親子プロセスは同じ物理ページを共有するため、親プロセスが書き込み要求を処理すると、osは共有ページではなく親プロセスが変更するページのコピーを作成します.したがって、サブプロセスのアドレス空間内のデータはfork時刻のデータベース全体のスナップショットである.
 
サブプロセスがスナップショットをテンポラリ・ファイルに書き込むと、元のスナップショット・ファイルをテンポラリ・ファイルに置き換え、サブプロセスが終了します.
 
クライアントはsaveまたはbgsaveコマンドを使用してredisにスナップショットの永続化を通知することもできます.saveオペレーションは、redisがすべてのclientのリクエストを1つのプライマリ・スレッドで処理するため、プライマリ・スレッドにスナップショットを保存します.この方法では、すべてのclientリクエストがブロックされます.なのでおすすめしません.
もう1つ注意したいのは、スナップショットの永続化のたびにメモリデータをディスクに完全に書き込むことであり、汚れたデータのみをインクリメンタルに同期するわけではありません.データ量が大きい場合、書き込み操作が多い場合は、ディスクio操作が大量に発生し、パフォーマンスに深刻な影響を及ぼす可能性があります.
メリット
 
この方法を採用すると、Redisデータベース全体に1つのファイルしか含まれません.これにより、バックアップが容易になります.例えば、1日もデータをアーカイブしないつもりかもしれません.
 
バックアップが容易で、1つのRDBファイルを他のストレージメディアに簡単に移動できます.
 
RDBは、大きなデータセットを復元する際の速度がAOFの復元速度よりも速い.
 
RDBはRedisの性能を最大化することができる:親プロセスはRDBファイルを保存する時に唯一しなければならないのはforkがサブプロセスを出して、それからこのサブプロセスは次のすべての保存作業を処理して、親プロセスはいかなるディスクI/O操作を実行する必要はありません.

劣勢


 
サーバ障害時にデータを失うことをできるだけ避ける必要がある場合は、RDBはあなたに適していません.Redisでは、異なるセーブポイントを設定してRDBファイルを保存する頻度を制御できますが、RDBファイルはデータセット全体の状態を保存する必要があるため、簡単な操作ではありません.そのため、少なくとも5分でRDBファイルを保存することができます.この場合、障害が発生して停止すると、数分間のデータが失われる可能性があります.
 
RDBを保存するたびに、Redisはfork()にサブプロセスを出力し、サブプロセスによって実際の永続化作業を行う.データセットが膨大な場合、fork()は非常に時間がかかり、サーバがミリ秒以内にクライアントの処理を停止する可能性があります.データセットが非常に大きく、CPU時間が非常に緊張している場合、この停止時間は丸1秒にも及ぶ可能性があります.AOF書き換えもfork()が必要であるが,AOF書き換えの実行間隔がどれだけ長くてもデータの耐久性に何ら損失はない.
 

AOFファイル保存プロセス


redisは、受信した書き込みコマンドをwrite関数でファイルに追加します(デフォルトはappendonly.aof).
redisが再起動されると、ファイルに保存されている書き込みコマンドを再実行することで、データベース全体のコンテンツがメモリに再構築されます.もちろんosはカーネルにwriteの変更をキャッシュするので、すぐにディスクに書き込むわけではないかもしれません.このようにaof方式の持続化も一部の修正を失う可能性がある.しかし、プロファイルを使用して、fsync関数でosをディスクに強制的に書き込むタイミングをredisに伝えることができます.3つの方法があります(デフォルトは毎秒fsyncです)
appendonly yes//aof持続化方式を有効にする#appendfsync always//書き込みコマンドを受け取るたびにディスクに強制的に書き込み、最も遅いが、完全な持続化を保証し、appendfsync everysec//毎秒1回ディスクに強制的に書き込むことをお勧めしない.性能と持続化の面で良い折衷を行い、推奨#appendfsync//はosに完全に依存し、性能が最も良い.永続化は保証されていません
aofの方式も同時に別の問題をもたらした.永続化ファイルはますます大きくなります.たとえばincr testコマンドを100回呼び出し、ファイルにはすべての100のコマンドを保存する必要がありますが、実際には99のコマンドが余分です.データベースの状態を復元するには、実際にファイルにset test 100を保存すれば十分です.
aofの永続化ファイルを圧縮するために.redisはbgrewriteaofコマンドを提供します.このコマンドを受信するとredisは、スナップショットと同様にメモリ内のデータをコマンドで一時ファイルに保存し、最後に元のファイルを置き換えます.具体的な過程は以下の通りである.
 
redisはforkを呼び出し、親子の2つのプロセスがあります.
サブプロセスは、メモリ内のデータベースのスナップショットに基づいて、データベースの状態を再構築するコマンドを一時ファイルに書き込みます.
親プロセスは、書き込みコマンドを元のaofファイルに書き込む以外にclientリクエストを処理し続けます.同時に受信した書き込みコマンドをキャッシュします.これにより、サブプロセスの書き換えに失敗した場合、問題が発生しないことが保証されます.
サブプロセスがスナップショットの内容をコマンド方式で一時ファイルに書き込むと、サブプロセスは親プロセスに信号を送信します.親プロセスは、キャッシュされた書き込みコマンドも一時ファイルに書き込みます.
親プロセスは、古いaofファイルを一時ファイルで置き換えて名前を変更でき、後で受信した書き込みコマンドも新しいaofファイルに追加されます.
aofファイルを書き換える操作で、古いaofファイルを読み取るのではなく、メモリ全体のデータベース内容をコマンドで新しいaofファイルを書き換えることに注意してください.これはスナップショットと少し似ています.

メリット


 
AOF持続化を使用すると、Redisは非常に耐久性があります(much more durable):fsyncなし、毎秒fsync、または書き込みコマンドを実行するたびにfsyncなどの異なるfsyncポリシーを設定できます.AOFのデフォルトポリシーは、毎秒fsyncです.この構成では、Redisは依然として良好なパフォーマンスを維持し、障害が発生してダウンタイムしても、最大1秒のデータしか失われません(fsyncはバックグラウンドスレッドで実行されるので、メインスレッドはコマンド要求を処理するために努力し続けることができます).
AOFファイルは追加操作のみを行うログファイル(append only log)であるため、AOFファイルの書き込みにseekを行う必要はなく、ログに何らかの理由で書き込みが完了していないコマンド(書き込み時にディスクがいっぱいになったり、書き込みが途中で停止したりするなど)が含まれていても、redis-check-aofツールは簡単にこの問題を修正することができます.Redisは、AOFファイルのボリュームが大きすぎると、AOFをバックグラウンドで自動的に書き換えることができる.書き換えられた新しいAOFファイルには、現在のデータセットを復元するために必要な最小コマンドセットが含まれている.Redisは新しいAOFファイルを作成する過程で、既存のAOFファイルにコマンドを追加し続けるため、書き換え中にダウンタイムが発生しても、既存のAOFファイルは失われません.新しいAOFファイルの作成が完了すると、Redisは古いAOFファイルから新しいAOFファイルに切り替え、新しいAOFファイルの追加操作を開始します.
AOFファイルはデータベースに対して実行されたすべての書き込み操作を秩序正しく保存しており、これらの書き込み操作はRedisプロトコルの形式で保存されているため、AOFファイルの内容は非常に読みやすく、ファイルの分析(parse)も容易である.エクスポート(export)AOFファイルも簡単です.たとえば、FLUSHALLコマンドをうっかり実行したが、AOFファイルが書き換えられていない限り、サーバを停止し、AOFファイルの末尾にあるFLUSHALLコマンドを削除し、Redisを再起動すれば、データセットをFLUSHALL実行前の状態に戻すことができます.

劣勢


 
同じデータセットの場合、AOFファイルのボリュームは通常、RDBファイルのボリュームよりも大きい.
 
使用したfsyncポリシーによれば、AOFの速度はRDBよりも遅くなる可能性がある.一般的に、毎秒fsyncの性能は依然として非常に高く、fsyncを閉じることで、高負荷でもAOFの速度をRDBと同じように速くすることができる.しかし、大きな書き込みロードを処理する場合、RDBは、より保証された最大遅延時間(latency)を提供することができる.
AOFは過去に,個々の命令により,AOFファイルの再読み込み時にデータセットを保存時のままに復元できないというバグが発生した.△たとえば、ブロックコマンドBRPOLPUSHは、このようなバグを引き起こしたことがある.テストキットには、ランダムで複雑なデータセットが自動的に生成され、これらのデータを再ロードすることですべてが正常であることを確認するテストが追加されています.このようなバグはAOFファイルではあまり見られないが,比較的RDBではこのようなバグはほとんど起こり得ない.

まとめ


一般的に、PostgreSQLに匹敵するデータセキュリティを達成するには、2つの永続化機能を同時に使用する必要があります.
データに非常に関心を持っているが、数分以内のデータ損失に耐えられる場合は、RDB永続化のみを使用することができます.
残りの場合、私は個人的にAOFを選ぶのが好きです.