RedisはRDBスナップショットをどのように実装しますか?

みなさん、こんにちは。私の名前はシャオリンです。

Redisはインメモリデータベースですが、データの永続性のために2つのテクノロジーを提供します。

それぞれ「AOFログとRDBスナップショット」です。

どちらの手法も、それぞれログファイルを使用して情報を記録しますが、記録の内容は異なります。

  • AOFファイルの内容は操作コマンドです。
  • RDBファイルの内容はバイナリデータです。

前回の記事でAOF永続性の原則をすでに紹介しましたが、今日は主にRDBスナップショットについて説明します。

いわゆるスナップショットとは、ある瞬間を記録することです。たとえば、風景を撮ると、その瞬間の写真や情報が写真に記録されます。

したがって、RDBスナップショットは、実際のデータを記録する特定の瞬間のメモリデータを記録するものであり、AOFファイルは、実際のデータではなく、コマンド操作のログを記録します。

したがって、Redisがデータを復元する場合、RDBファイルをメモリに直接読み込むことができ、AOFのようなデータを復元するために追加の手順を実行する必要がないため、RDBデータ回復の効率はAOFよりも高くなります。

次に、RDBスナップショットについて詳しく説明します。

スナップショットの使い方は?

何かに精通するためには、最初にそれを使用する方法を確認するためのより良い方法です。

Redisは、RDBファイルを生成するための2つのコマンド、つまりsavebgsave。それらの違いは、「メインスレッド」で実行されるかどうかです。

  • 保存コマンド実行後、メインスレッドでRDBファイルが生成されます。操作コマンドは同じスレッドで実行されるため、RDBファイルの書き込み時間が長すぎるとメインスレッドがブロックされます。
  • bgsavaコマンドを実行すると、RDBファイルを生成するための子プロセスが作成されます。これにより、メインスレッドのブロックを回避できます。

RDBファイルのロードはサーバーの起動時に自動的に実行され、RedisはRDBファイルをロードするための特別なコマンドを提供していません。

Redisは、構成ファイルのオプションを使用して、定期的にbgsavaコマンドを自動的に実行することもできます。デフォルトでは、次の構成が提供されています。

save 900 1
save 300 10
save 60 10000

このオプションはsavaと呼ばれますが、実際にはbgsavaコマンドを実行します。つまり、RDBスナップショットファイルを生成するためのサブプロセスを作成します。

上記の条件のいずれかが満たされている限り、bgsavaが実行され、その意味は次のとおりです。

  • データベースは900秒以内に少なくとも1回変更されています。
  • 300秒以内にデータベースに少なくとも10回の変更。
  • 60秒以内に、データベースに少なくとも10,000の変更が加えられました。

ここで、Redisのスナップショットは完全なスナップショットである、つまり、スナップショットが実行されるたびに、メモリ内の「すべてのデータ」がディスクに記録されることに注意してください。

したがって、スナップショットの実行は比較的重い操作であると見なすことができ、頻度が高すぎると、Redisのパフォーマンスに影響を与える可能性があります。頻度が低すぎると、サーバーに障害が発生したときに失われるデータが増えます。

通常、スナップショットを少なくとも5分に1回保存するように設定できます。このとき、Redisがダウンすると、最大5分間データが失われる可能性があります。

これは、RDBスナップショットの欠点です。サーバーに障害が発生すると、AOF永続性よりも多くのデータが失われます。RDBスナップショットは完全なスナップショットであるため、実行頻度が高すぎることはありません。そうしないと、Redisのパフォーマンスに影響し、AOFログが操作コマンドを数秒で記録するため、失われるデータは比較的少なくなります。

スナップショットの実行中にデータを変更できますか?

ここで問題が発生します。bgsavaの実行中、メインスレッドは子プロセスに渡されてRDBファイルをビルドするため、引き続き機能します。メインスレッドはこの時点でデータを変更できますか?

データを変更できない場合、パフォーマンスは大幅に低下します。データを変更できる場合、どのように行うことができますか?

結論を述べましょう。bgsavaの実行中、Redisは引き続き操作コマンドを処理できます。つまり、データを変更できます。

では、どの程度正確ですか?重要なテクノロジーは、コピーオンライトテクノロジー(*コピーオンライト、COW *)です。

bgsavaコマンドを実行すると、子プロセスがfork()作成されます。このとき、子プロセスと親プロセスは同じメモリデータを共有します。これは、子プロセスが作成されると、親プロセスのページテーブルがコピーされるためです。 、ただし、ページテーブルが指す物理メモリは1のままです。

写真

物理メモリは、メモリデータの変更が発生した場合にのみコピーされます。

写真

これは、子プロセスを作成する際のパフォーマンスの低下を減らし、子プロセスの作成を高速化することを目的としています。結局のところ、子プロセスを作成するプロセスはメインスレッドをブロックします。

したがって、bgsave子プロセスを作成した後は、親プロセスのすべてのメモリデータを共有するため、メインスレッドのメモリデータを直接読み取り、RDBファイルに書き込むことができます。

メインスレッドがこれらの共有メモリデータに対して読み取り専用操作も実行する場合、メインスレッドとbgsave子プロセスは相互に影響を与えません。

ただし、メインスレッドが共有データ内の特定のデータ(キーと値のペアなどA)を変更する場合は、コピーオンライトが発生するため、このデータの物理メモリがコピーされます(キー-値ペアA'、次にメインスレッドA'はこのデータコピー(キーと値のペア)に対して変更操作を実行します同時に、 bgsave子プロセスは、元のデータ(キーと値のペア)をRDBファイルに書き込み続けることができAます。

これで、Redisはbgsaveを使用して、現在のメモリ内のすべてのデータのスナップショットを取得します。この操作は、bgsaveサブプロセスによってバックグラウンドで実行され、実行中にメインスレッドがブロックされないため、メインスレッドがデータを変更できます。同時に。

注意深い学生は、bgsaveスナップショットプロセス中に、メインスレッドが共有データを変更した場合、コピーオンライトが発生した後、RDBスナップショットが元のメモリデータを保存し、メインスレッドによって変更されたばかりのデータがによって保存されることを発見したはずです。この時点でRDBファイルに書き込まれる内容のメソッドは、次のbgsaveスナップショットにのみ引き渡すことができます。

したがって、Redisがbgsaveスナップショットを使用している場合、メインスレッドがメモリデータを変更すると、共有メモリデータであるかどうかに関係なく、RDBスナップショットは、メインスレッドによって変更されたばかりのデータを書き込むことができません。メインスレッドと子スレッドのメモリをRDBスナップショットに書き込むことはできません。データは分離されており、子スレッドによってRDBファイルに書き込まれるメモリデータは元のメモリデータのみになります。

RDBスナップショットファイルが作成された直後にシステムがクラッシュした場合、Redisはスナップショット中にメインスレッドによって変更されたデータを失います。

さらに、コピーオンライトが発生するような極端なケースがあります。

RedisがRDB永続性を実行すると、メインプロセスと子プロセスはフォークされたばかりのときに同じ物理メモリを共有しますが、メインプロセスは書き込み操作を処理し、途中で共有メモリを変更するため、現在変更されているデータの物理メモリはコピーされます。

極端な場合、すべての共有メモリが変更された場合、この時点でのメモリ使用量は元の2倍になります。

したがって、書き込み操作が多いシナリオでは、スナップショットプロセス中のメモリの変更に注意して、メモリがいっぱいにならないようにする必要があります。

RDBとAOFの組み合わせ

RDBデータの回復速度はAOFよりも高速ですが、スナップショットの頻度を制御するのは簡単ではありません。

  • 頻度が低すぎる場合、サーバーが2つのスナップショット間でダウンすると、より多くのデータが失われる可能性があります。
  • 頻度が高すぎる場合、ディスクへの頻繁な書き込みと子プロセスの作成により、パフォーマンスのオーバーヘッドが増加します。

RDBの高速リカバリの利点とデータ損失の少ないAOFの利点だけでなく、どのような方法がありますか?

もちろん、これはRDBとAOFを組み合わせることです。この方法はRedis 4.0で提案されました。この方法は、AOFログとメモリスナップショットの混合使用と呼ばれ、混合永続性とも呼ばれます。

ハイブリッド永続機能を有効にする場合は、Redis構成ファイルで次の構成項目をyesに設定できます。

aof-use-rdb-preamble yes

ハイブリッド永続性は、AOFログ書き換えプロセスで機能します。

ハイブリッド永続性が有効になっている場合、AOFがログをリライトすると、発信forkリライトサブプロセスは最初にメインスレッドと共有するメモリデータをRDBモードでAOFファイルに書き込み、次にメインスレッドによって処理された操作コマンドが記録されます。リライトバッファの場合、リライトバッファ内のインクリメンタルコマンドはAOFモードでAOFファイルに書き込まれます。書き込みが完了すると、メインプロセスに通知され、古いAOFファイルをRDB形式とAOFを含む新しいAOFファイルに置き換えます。 format.document。

つまり、ハイブリッド永続性を使用すると、AOFファイルの前半はRDB形式の完全なデータであり、後半はAOF形式の増分データです

写真

これの利点は、データをロードするためにRedisを再起動するときに、前半がRDBコンテンツであるため、ロード速度が非常に速くなることです

RDBのコンテンツが読み込まれた後、後半のAOFコンテンツが読み込まれます。ここでのコンテンツは、Redisバックグラウンド子プロセスによるAOFの書き換え中にメインスレッドによって処理される操作コマンドであり、損失を減らすことができます。データの

おすすめ

転載: blog.csdn.net/qq_34827674/article/details/123448691