ホームページ  >  記事  >  データベース  >  Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

藏色散人
藏色散人転載
2023-02-15 11:16:251657ブラウズ

前言

四月份的時候、有位朋友去美团面试,他说被 Redis と MySQL 双写一致性はどのように保たれますか? この道の問題は、双書场の環境下でデータベースが保存されている場合、一致性はどのように保たれますか?

  • #github 場所、各スターの印象が一致しています。

性質

# 一貫性とは、データが一貫した状態を保つことであり、分散システムでは、複数のポイントのデータの値が一致していると理解できます。

  • 強い一貫性: この一貫性レベルはユーザーの直感と最も一致しています。システムが書き込む必要があるものはすべて読み出されます。ユーザー エクスペリエンスは良好ですが、実装は困難です多くの場合、システムのパフォーマンスに大きな影響を及ぼします
  • 弱い整合性: この整合性レベルにより、システムは書き込みが成功した直後に書き込まれた値を読み取ることができなくなります。データの一貫性が保たれるまでにどれくらいの時間がかかるかを約束しますが、一定の時間レベル (たとえば、第 2 レベル)
  • 最終整合性 : 最終整合性 これは弱い整合性の特殊なケースであり、システムは一定期間内にデータ整合性状態が達成されることを保証します。ここで最終整合性について個別に説明する理由は、これが弱い整合性で非常に評価されている整合性モデルであり、大規模な分散システムにおけるデータ整合性に関して業界で非常に評価されているモデルであるためです。

3 つの従来のキャッシュ モード

キャッシュによりパフォーマンスが向上し、データベースの負荷が軽減されますが、キャッシュを使用するとデータの 不整合の問題が発生する可能性もあります。一般的にキャッシュをどのように使用するのでしょうか?古典的なキャッシュ パターンは 3 つあります。

  • キャッシュアサイド パターン
  • リードスルー/ライトスルー
  • ライト ビハインド

キャッシュ-Aside パターン

キャッシュ アサイド パターン、つまり バイパス キャッシュ モードは、キャッシュとデータベース間のデータの不整合の問題を可能な限り解決するために提案されています。

キャッシュアサイド読み取りプロセス

キャッシュアサイド パターンの読み取りリクエスト プロセスは次のとおりです:

Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

  1. #読み取りの場合は、まずキャッシュを読み取ります。キャッシュがヒットした場合は、データが直接返されます。
  2. キャッシュがヒットしなかった場合は、データベースを読み取り、データベースからデータを取得し、それを配置しますをキャッシュに格納し、同時に応答を返します。

キャッシュアサイド書き込みプロセス

キャッシュアサイド パターンの書き込みリクエスト プロセスは次のとおりです:

Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

#更新する場合は、まずデータベースを更新してから、キャッシュを削除してください。 リードスルー/ライトスルー (読み取り/書き込み浸透)

リード/ライトスルー

モードでは、サーバーはキャッシュをメインのデータストレージとして使用します。アプリケーションとデータベース キャッシュ間の対話は、抽象キャッシュ層を通じて完了します。 リードスルー

リードスルーの簡単なプロセス

は次のとおりです

Read Through简要流程

リードスルーfromキャッシュ データが読み込めない場合は直接返し、読み取れない場合はデータベースからロードしてキャッシュに書き込んでレスポンスを返します。
  1. この簡単なプロセスは、
  2. キャッシュアサイド
  3. とよく似ていますか?実際、
Read-Through

Cache-Provider の単なる追加レイヤーであり、プロセスは次のとおりです:

リードスルーは実際には

Cache-AsideRedis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン) の上にカプセル化の層があり、これによりプログラム コードがより簡潔になり、データ ソースの負荷が軽減されます。

ライトスルー

ライトスルー

モードでは、書き込みリクエストが発生すると、データソースとキャッシュされたデータも

キャッシュ抽象化レイヤーによって完成されます。

更新プロセスは次のとおりです。 ライト ビハインド (非同期キャッシュ書き込み) Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

ライト ビハインド

の後に、

リードスルー/ライトが続きます。 -Through

類似点があります キャッシュ プロバイダーは、キャッシュとデータベースの読み取りと書き込みを担当します。それらの間には大きな違いがあります。Read/Write Through はキャッシュとデータを同期的に更新しますが、Write Behind はキャッシュのみを更新し、 を通じてデータベースを直接更新しません。データベースを更新するバッチ非同期方法。

この方法では、キャッシュとデータベース間の一貫性は強力ではありません。

高い一貫性要件を持つシステムは注意して使用する必要がありますWrite behind流程。ただし、頻繁に書き込みを行うシナリオには適しており、MySQL の

InnoDB バッファ プール メカニズム

はこのモードを使用します。 キャッシュを操作する場合、キャッシュを削除するべきですか、それともキャッシュを更新するべきですか? 一般的なビジネス シナリオでは、

キャッシュ アサイド

モードを使用します。

キャッシュアサイド

リクエストを書くときに、なぜ キャッシュを更新せずにキャッシュを削除するのですか?と尋ねる友人もいるかもしれません。

Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

#キャッシュを運用する場合、キャッシュを削除するべきでしょうか、それともキャッシュを更新するべきでしょうか?まず例を見てみましょう:

    スレッド A は最初に書き込み操作を開始し、最初のステップはデータベースを更新することです
  1. スレッド B次に、書き込み操作を開始します。 書き込み操作、2 番目のステップでデータベースを更新します。
  2. ネットワークやその他の理由により、スレッド B が最初にキャッシュを更新します。
  3. スレッド A がキャッシュを更新します。
このとき、キャッシュにはAさんのデータ(古いデータ)が保存され、データベースにはBさんのデータ(新しいデータ)が保存されており、

不整合となり、ダーティなデータが現れます。 。 がキャッシュ を更新する代わりにキャッシュを削除すると、このダーティ データの問題は発生しません。

キャッシュの更新には、キャッシュの削除と比較して 2 つの欠点があります。:

    書き込むキャッシュ値が複雑な計算の後に取得される場合。キャッシュが頻繁に更新されると、パフォーマンスが無駄になります。
  • データベース書き込みシナリオが多く、データ読み取りシナリオが少ない場合、データは読み取られる前に更新されることが多く、これもパフォーマンスを無駄にします (実際、書き込みが多いシナリオでは、それほどパフォーマンスは向上しません)キャッシュを使用すると費用対効果が高くなります)
二重書き込みの場合、データベースを最初に操作する必要がありますか、それともキャッシュを最初に操作する必要がありますか?

キャッシュアサイドキャッシュ モードでも、まだ質問がある友人がいます。リクエストを書くときに、なぜ 最初にデータベースを操作するのですか?なぜ まずキャッシュ を操作しないのでしょうか?

2 つのリクエスト A と B があり、A に更新操作の実行を要求し、B にクエリと読み取り操作の実行を要求するとします。

Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

    スレッド A が書き込み操作を開始します。最初のステップはキャッシュの削除です。
  1. この時点で、スレッド B が読み取り操作を開始します。キャッシュ ミスです。
  2. スレッド B は続行 DB の読み取り、古いデータの読み取りを行います
  3. 次に、スレッド B が古いデータをキャッシュに設定します
  4. スレッド A が最新のデータを DB に書き込みます
Jiang Zi には問題があります。La、

キャッシュとデータベースのデータが矛盾しています。キャッシュには古いデータが保存され、データベースには新しいデータが保存されます。したがって、Cache-Aside キャッシュ モードは、キャッシュを最初に操作するのではなく、データベースを最初に操作することを選択します。 キャッシュ遅延二重削除

一部の友人は、最初にデータベースを操作する必要はなく、

キャッシュ遅延二重削除

戦略を使用するだけでよいと言うかもしれません。遅延二重削除とは何ですか?

Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

最初にキャッシュを削除します
  1. 次にデータベースを更新します
  2. しばらく (1 秒など) スリープしてから削除します再びキャッシュ。
  3. 一時的に眠るのに通常どれくらいかかりますか?全部1秒ですか?

このスリープ時間 = ビジネス ロジック データの読み取りにかかる時間は数百ミリ秒です。読み取りリクエストを確実に終了させるために、書き込みリクエストは、読み取りリクエストによってもたらされる可能性のあるキャッシュされたダーティ データを削除できます。

削除キャッシュの再試行メカニズム

遅延二重削除

キャッシュアサイドは最初にデータベースを操作してからキャッシュを削除します , キャッシュを削除する 2 番目のステップが失敗した場合、削除の失敗によりダーティ データが生成されます~

削除に失敗した場合は、さらに数回削除して、キャッシュの削除が成功したことを確認してください~だから
キャッシュの削除再試行メカニズムを導入できます

Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)

データベースを更新するためのリクエストの書き込み
  1. キャッシュに失敗しました何らかの理由で削除
  2. 削除に失敗したキーをメッセージキューに入れる
  3. ##メッセージキューからメッセージを消費し、削除するキーを取得
  4. ##削除を再試行するキャッシュ操作
  5. biglog を読む非同期キャッシュ削除
  6. 削除キャッシュ メカニズムの再試行は問題ありませんが、大量のビジネス コード侵入を引き起こします。実際、
データベースのバイナリログを通じてキー

を非同期的に削除することもできます。

mysql を例にとると、Alibaba のカナルを使用して binlog ログを収集し、MQ キューに送信し、ACK メカニズムを通じて更新メッセージを確認して処理できます。 、キャッシュを削除し、データ キャッシュの整合性を確保する

推奨学習: "Redis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)Redis ビデオ チュートリアル

"

以上がRedis と MySQL の間で二重書き込みの一貫性を確保するにはどうすればよいですか? (美団エルミアン)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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