redis はメモリ上に格納され、一般的なプログラミング言語で一般的に使用されるデータ構造の保存タイプを提供するため、サーバーがクラッシュした場合のデータ回復処理によく使用されます。
サーバーは、特定の指定されたプロセスで json オブジェクトの形式で Redis に保存する必要があるデータを保存できます。これは、私たちがよくスナップショットと呼ぶものです。サーバーの実行中に、redis が読み取られて、復元する必要があります。データは引き続き処理されます。
ビジネス プロセスが完了したら、Redis データを削除するだけです。
Redis は、データ バックアップのためにメモリ データをハード ディスクにエクスポートするための 2 つの方法を提供します。
RDB 方法 (デフォルト)
RDB 方法の永続化は、スナップショット (スナップショット) によるものです。完了すると、特定の条件が満たされると、Redis がメモリ内のすべてのデータのスナップショットを自動的に作成し、ハードディスクに保存します。スナップショットを取得する条件は、ユーザーが設定ファイルでカスタマイズでき、時間と変更されたキーの数の 2 つのパラメータで構成されます。指定した時間内に変更されたキーの数が指定した値を超えると、スナップショットが作成されます。 RDB は、redis によって使用されるデフォルトの永続化メソッドです。構成ファイルには 3 つの条件が事前に設定されています:
save 900 1 # 900 秒以内に少なくとも 1 つのキーが変更された場合、スナップショットが作成されます
save 300 10 # 300 秒以内に少なくとも 10 個のキーが変更された場合はスナップショットを作成します
save 60 10000 # 60 秒以内に少なくとも 10,000 個のキーが変更された場合はスナップショットを作成します
複数の条件があり、条件間には「OR」の関係があり、いずれかの条件が満たされていればスナップショットが取得されます。自動スナップショットを無効にしたい場合は、すべての保存パラメータを削除してください。
Redis は、デフォルトでスナップショット ファイルを現在のディレクトリ (CONFIG GET dir で表示可能) の dump.rdb ファイルに保存します。スナップショット ファイルのストレージ パスとファイル名は、設定によって指定できます。それぞれ dir パラメータと dbfilename パラメータ。
Redis がスナップショットを実装するプロセス
Redis は fork 関数を使用して、現在のプロセス (親プロセス) のコピー (子プロセス) をコピーします。
親プロセスは続行します。顧客を受け入れて処理するため コマンドがターミナルから送信され、子プロセスはメモリ内のデータをハードディスク上の一時ファイルに書き込み始めます;
子プロセスがすべてのデータの書き込みを完了すると、古い RDB ファイルは一時ファイルに置き換えられます。これまでのスナップショット操作は完了です。
フォークを実行するとき、オペレーティング システム (Unix 系オペレーティング システム) はコピーオンライト戦略を使用します。つまり、親プロセスと子プロセスは、フォーク関数が発生した時点で同じメモリ データを共有します。親プロセスが必要な場合 特定のデータが変更されると (書き込みコマンドの実行など)、オペレーティング システムは子プロセスのデータが影響を受けないようにそのデータをコピーします。 file には、フォークが実行された時点のメモリ データが保存されます。
Redis は、スナップショット プロセス中に RDB ファイルを変更しません。スナップショットが完了した後でのみ、古いファイルを新しいファイルに置き換えます。つまり、RDB ファイルはいつでも完成します。これにより、RDB ファイルを定期的にバックアップすることで、Redis データベースのバックアップを実装できるようになります。 RDB ファイルは圧縮されたバイナリ形式 (CPU 使用率を節約するために圧縮を無効にするように rdbcompression パラメータを構成できます) であるため、メモリ内のデータ サイズより占有されるスペースが小さくなり、送信が容易になります。
自動スナップショットに加えて、SAVE または BGSAVE コマンドを手動で送信して、Redis にスナップショットを実行させることもできます。2 つのコマンドの違いは、前者はメイン プロセスによって実行され、他のリクエストをブロックすることです。後者はフォークを通じて実行されます。子プロセスはスナップショット操作を実行します。 Redis が起動すると、RDB スナップショット ファイルが読み取られ、ハードディスクからメモリにデータがロードされます。この時間は、データのサイズと構造、およびサーバーのパフォーマンスによって異なります。 1,000 万個の文字列型キーを記録する 1 GB のスナップショット ファイルをメモリにロードするには、通常 20 ~ 30 秒かかります。永続性は RDB を通じて実現され、Redis が異常終了すると、最後のスナップショット以降に変更されたデータはすべて失われます。このため、開発者は、特定のアプリケーション シナリオに基づいて自動スナップショット条件を組み合わせて設定することにより、データ損失の可能性を許容範囲内に制御する必要があります。データが非常に重要であり、いかなる損失も許容できない場合は、永続化のために AOF メソッドの使用を検討できます。
AOF メソッド
デフォルトでは、Redis は AOF (ファイル追加のみ) 永続性を有効にしません。これは、redis.conf の appendonly パラメーターを通じて有効にできます:
appendonly yes
Redis は起動時に AOF ファイル内のコマンドを 1 つずつ実行してハードディスク内のデータをメモリにロードします。ロード速度は RDB より遅くなります。
AOF を有効にする永続性 Redis 内のデータを変更するコマンドが実行されるたびに、Redis はそのコマンドをハード ディスク上の AOF ファイルに書き込みます。 AOF ファイルの保存場所は RDB ファイルの場所と同じで、両方とも dir パラメータで設定されます。デフォルトのファイル名は appendonly.aof ですが、appendfilename パラメータで変更できます:
appendfilename appendonly.aof
redis が AOF ファイルを自動的に書き換える条件を構成します
auto-aof-rewrite-percentage 100 # 現在の AOF ファイル サイズが、実行中に AOF ファイル サイズのパーセンテージを超えた場合最後の書き換え、再度実行されます。 書き換え、以前に書き換えられていない場合、起動時の AOF ファイル サイズに基づきます
auto-aof-rewrite-min-size 64mb #最小 AOF書き換え可能なファイルサイズ
AOF ファイルの書き込み後にシステムがハードディスク キャッシュを更新するように要求するメカニズムを構成します
# appendfsync always # 書き込みが実行されるたびに同期が実行されます。これが最も安全で最も時間がかかります
appendfsync eachsec # 同期操作を 1 秒ごとに実行します
# appendfsync no # 同期操作を積極的に実行せず、完全にオペレーティング システムに任せます (つまり、30 秒に 1 回)。これが最も高速です
Redis では、AOF と RDB を同時に開くことができるため、データのセキュリティが確保されるだけでなく、バックアップやその他の操作も非常に簡単になります。この時点で Redis を再起動した後、Redis は AOF ファイルを使用してデータを復元します。これは、AOF 永続化により失われるデータが少なくなる可能性があるためです。
redis = require('redis'),//导入js模块 RDS_PORT = , //端口号 RDS_HOST = '', //服务器IP RDS_OPTS = {}, //设置项 redisdb = redis.createClient(RDS_PORT, RDS_HOST, RDS_OPTS);//创建连接 redisdb.select(20);//指定分区库 redisdb.on('ready', function (res) { console.log('ready'); }); redisdb.on('connect', function () { console.log('connect'); }); exports.redisdb = redisdb; function redis_opt(opt, key, value, callback) { if (opt == 'get') { redisdb.get(key, function (err, data) { if (err == null) { callback(data); } else { callback(err); } }); } else if (opt == 'set') { redisdb.set(key,value, function (err,result) { if (err == null) { callback(result); } else { callback(err); } }); } else if (opt == 'del') { redisdb.del(key, function (err, result) { if (err == null) { callback(result); } else { callback(err); } }); } else { callback("error opt!"); } } function update(key) { redis_opt("get", key, null, function (data) { console.log("the redis data is " + data); if (data) { count = parseInt(data); redis_opt("set", key, ++count , function (data) { console.log("set " + count + " " + data); }); } else { redis_opt("set", key, 10000, function (data) { console.log("set " + 10000 + " " + data); }); } }); } function clear(key) { redis_opt("del", key, null, function (ret) { console.log("del " + key + " " + ret); }); } function main() { var key = "count_test"; setInterval(function () { clear(key) }, 5000); setInterval(function () { update(key) }, 1000); } //testmain(); main();
上記のコードは単純なタイマー関数です。つまり、このコードは、実行後に定期的に読み取られます。サーバーを起動し、redis データが存在する場合は累積的に変更され、存在しない場合は初期化されますが、同時に説明の便宜上、データを定期的に削除するようにタイマーが設定されています。
redis の詳細については、redis 入門チュートリアル 列に注目してください。
以上がRedis を使用したサーバークラッシュからのデータ復旧の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。