ホームページ  >  記事  >  データベース  >  MySQL データを Redis キャッシュに同期する方法

MySQL データを Redis キャッシュに同期する方法

王林
王林転載
2023-05-27 09:08:101394ブラウズ

1 Mysql はデータをチェックして Redis に同期的に書き込みます

デメリット 1: Redis への同期書き込み自体に遅延があり、再試行が必要なため、インターフェースに遅延が発生します。書き込みが失敗すると、再試行する必要があり、さらに時間がかかります。

欠点 2: 切り離しがありません。redis がクラッシュすると、スレッドが直接ブロックされます。

欠点 3: 誰かがデータベースの場合、対応するデータベースが同期されない限り、同期されません。 Redis ですが、Redis の削除プロセスには時間差があります

2 Mysql はデータをチェックした後、MQ

を送信してコンシューマー スレッドで Redis を同期します欠点 1:つまり、MQ の層が多くなります。同期遅延の問題が発生する可能性が高くなります。

欠点 2: MQ の可用性を妨げる

欠点 3: 誰かがデータベースを使用している場合、同期されません

利点 1: インターフェイスの遅延応答の問題を大幅に軽減できます

#利点 2: MQ 自体に再試行メカニズムがあるため、手動で再試行コードを記述する必要がありません

利点 3: 分離、Mysql クエリ、および Redis 同期は完全に分離されており、相互に干渉しません

3 Mysql の Binlog ファイルをサブスクライブします (Canal の助けを借りて実行できます)

CanalServer は MysqlServer スレーブ ライブラリであるふりをして、MysqlServer メイン ライブラリの Binlog ファイルをサブスクライブします

Canal が開始されると、対応するメッセージ MQ (RabbitMQ、RocketMQ、Kafka) が設定されます。 Binlog ファイルでは、変更された SQL ステートメントを json 形式に変換し、メッセージの内容として送信します。MQ の

プロジェクトでは、対応する MQ を監視している限り、その内容を取得できます。ビンログの変更: Json データにはクリア操作タイプ (CURD) と対応するデータがあります。対応するデータを redis に同期するだけです。

欠点 1: Binlog にサブスクライブする運河の操作プロセス全体がシングルスレッドであるため、超高同時実行に直面すると、パフォーマンスが優れていない可能性があります。複数の Canal と複数のコンシューマをデプロイできますが、繰り返し発生する消費の問題を回避し、冪等性検証を実行することに注意する必要があります。

利点 1: データベースが手動で変更された場合でも、監視および同期されます。

利点 2: 非同期同期、インターフェイスの戻りに余分な遅延がない

4 遅延二重削除

変更された SQL を実行する前に Redis データを削除します

更新 SQL を実行します

一定期間遅延します

redis データを再度削除します

// 延迟双删伪代码
deleteRedisCache(key);   // 删除redis缓存
updateMysqlSql(obj);        // 更新mysql
Thread.sleep(100);           // 延迟一段时间
deleteRedisCache(key);   // 再次删除该key的缓存

欠点: この遅延時間は制御が難しく、遅延の長さは非常に困難です。評価するために

遅延二重削除を使用しない場合は、キャッシュを削除してから MySQL データを変更するだけです。この2ステップだけだとどんな問題が起きるでしょうか?

5. 単一リクエスト、単一スレッドは問題ありませんが、高い同時実行性とマルチスレッドでは問題が発生します。

6. Thread1 スレッドがデータを更新したい場合、Thread1 スレッドは Redis をクリーンアップします。この時点で

7. この時点で、Thread2 のスレッドが到着しましたが、Thread1 は mysql の更新を完了していません。

8. Thread2 のクエリ redis は null である必要があります。この時点で、Thread2 はチェックしますmysql を実行し、見つかったデータをキャッシュに書き込みます

9. Thread1 には mysql データを変更する時間がなかったため、この時点で Thread2 によって見つかったデータは [古いデータ] であり、Thread2 は古いデータを書き込みます再び Redis へ

#10 このとき Thread3 スレッドが来て、Redis にクエリを実行してデータがあることがわかると、キャッシュされたデータを直接取得します。このとき、[Thread3 は古いデータを見つけます]

11. 遅延二重削除の 2 番目の削除機能は、Thread2 が古いデータを再度書き込むのを防ぐことです。遅延二重削除では、Thread3 は依然として Null を取得します。 Redis にクエリを実行し、mysql

12 から最新のデータを取得します。したがって、通常の遅延時間は、Thread2 のキャッシュの確認から mysql データの取得、Redis への保存までの全時間となるはずです (Thread1 の遅延時間と同様)。ただし、Thread2 の処理時間は多くの要因に影響されるため、どのくらいの時間がかかるかを判断することは困難です

5 遅延二重書き込み

// 延迟双写伪代码
updateMysqlSql(obj);        // 更新mysql
addRedis(key);   // 再次删除该key的缓存

上記のコードの欠陥;

  • 高い同時実行性では、2 つのスレッドが同時に実行されます。上記のコードは mysql に変更され、変更内容がブロックされるため、Redis と Mysql データの間で不整合が発生する可能性があります

  • T1 スレッドは updateMysqlSql の実行を終了し、行ロックを解放します。このとき、T2 スレッドは updateMysqlSql と addRedis を再度実行し、最後に T1 が addRedis を実行します。この状況により、データベースは次のように変更されます。 T2 スレッドのデータですが、Redis は T1 スレッドのデータです

Optimization

// 完美延迟双写伪代码
开启事务
updateMysqlSql(obj);        // 更新mysql
addRedis(key);   // 再次删除该key的缓存
提交事务

上記のコードの修正:

2 つを入れますT1 が Mysql と Redis の実行を終了した場合にのみ、T2 が実行を開始できるため、データの一貫性が確保されます。分散ロックの使用をお勧めします。

二重書き込みの欠点: Mysql と Redis はシングルスレッドです。パフォーマンスが良くないため、

の使用はお勧めしません。

以上がMySQL データを Redis キャッシュに同期する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。