分散データベースとキャッシュの二重書き込み一貫性ソリューションの分析

分散データベースとキャッシュの二重書き込み一貫性ソリューションの分析

なぜこの記事を書くのですか?

まず、キャッシュは、その高い同時実行性と高いパフォーマンスにより、プロジェクトで広く使用されてきました。キャッシュの読み取りに関しては、誰もが疑問を抱くことはなく、すべての業務操作は次の図のプロセスに従って実行されます。 しかし、キャッシュを更新する場合、データベースを更新した後、キャッシュを更新するか、キャッシュを削除するべきでしょうか?または、最初にキャッシュを削除してからデータベースを更新することもできます。実際、これについては多くの論争があります。現在、これらのソリューションを分析する包括的なブログはありません。そこでブロガーは、皆から批判されるリスクを冒して、恐る恐るこの記事を書いた。

文章

まず説明させてください。理論的には、キャッシュの有効期限を設定することが最終的な一貫性を保証する解決策となります。このスキームでは、キャッシュに保存されたデータの有効期限を設定できます。すべての書き込み操作はデータベースに基づいており、キャッシュ操作は最善を尽くすだけで済みます。つまり、データベースへの書き込みは成功したがキャッシュの更新に失敗した場合、有効期限が切れている限り、後続の読み取り要求によってデータベースから新しい値が読み取られ、キャッシュが埋め戻されます。したがって、以下で説明するアイデアは、キャッシュの有効期限を設定することに依存しません。

ここでは、3 つの更新戦略について説明します。
  1. 最初にデータベースを更新し、次にキャッシュを更新します

  2. まずキャッシュを削除し、次にデータベースを更新します

  3. まずデータベースを更新し、次にキャッシュを削除します

    なぜ最初にキャッシュを更新し、次にデータベースを更新しなかったのかと聞かれる人はいないはずです。

最初にデータベースを更新し、次にキャッシュを更新します

この計画は一般に皆から反対されている。なぜ?理由は2つあります。

理由1(スレッドの安全性の観点)

リクエストAとリクエストBの両方が同時に更新されている場合、

  1. スレッドAはデータベースを更新する

  2. スレッドBはデータベースを更新する

  3. スレッドBがキャッシュを更新する

  4. スレッドAがキャッシュを更新する

これは、リクエスト A がリクエスト B よりも早くキャッ​​シュを更新する必要があるが、ネットワーク上の理由により、B が A よりも早くキャッ​​シュを更新することを意味します。これによりダーティ データが生成されるため、考慮されません。

理由2(ビジネスシナリオの観点)

ポイントは2つあります。

  1. ビジネス ニーズにデータベース書き込みシナリオが多く、データ読み取りシナリオが少ない場合、このソリューションを採用すると、データが読み取られる前にキャッシュが頻繁に更新され、パフォーマンスが低下します。
  2. データベースに値を書き込む場合、その値はキャッシュに直接書き込まれるのではなく、一連の複雑な計算を経てからキャッシュに書き込まれます。すると、データベースに書き込まれるたびに、キャッシュに書き込まれた値が再計算され、間違いなくパフォーマンスが無駄になります。明らかに、キャッシュを削除する方が適切です。
次に議論すべきことは、最も議論の多いことですが、まずキャッシュを削除してからデータベースを更新することです。または、まずデータベースを更新してから、キャッシュを削除します。

まずキャッシュを削除し、次にデータベースを更新します

この方式が矛盾を生じる理由は次のとおりです。同時に、更新操作のリクエスト A とクエリ操作のリクエスト B が存在します。すると、次のような状況が発生します。

  1. Aに書き込み操作を実行してキャッシュを削除するように要求する
  2. Bにクエリを要求し、キャッシュが存在しないことを確認する

  3. Bにデータベースを照会して古い値を取得するよう要求する
  4. Bに古い値をキャッシュに書き込むように要求する
  5. Aに新しい値をデータベースに書き込むように要求する
上記の状況は矛盾を生じさせます。さらに、キャッシュの有効期限戦略を設定しないと、データは常にダーティ データになります。 それで、どうやって解決するのでしょうか?遅延二重削除戦略を採用します。疑似コードは以下のとおりです

中国語に翻訳された説明は

  1. まずキャッシュを削除する
  2. データベースを再度書き込みます(この 2 つの手順は前と同じです)
  3. 1秒間スリープして再度キャッシュを削除します

これにより、1 秒以内に作成されたキャッシュ ダーティ データを再度削除できるようになります。

では、この 1 秒はどのように決定され、どのくらいの時間眠るべきなのでしょうか?

上記の状況を考慮して、読者は自身のプロジェクトのデータ読み取りビジネス ロジックの時間消費を評価する必要があります。次に、データ読み取りのビジネス ロジックによって消費される時間に基づいて、データ書き込みのスリープ時間を数百ミリ秒増やすことができます。これを行う目的は、読み取り要求が完了し、書き込み要求によって読み取り要求によって発生したキャッシュ ダーティ データを削除できるようにすることです。

MySQL の読み取り/書き込み分離アーキテクチャを使用するとどうなるでしょうか?

この場合、データの不整合の原因は次のとおりです。まだ 2 つのリクエストがあり、1 つは更新操作のリクエスト A で、もう 1 つはクエリ操作のリクエスト B です。

  1. Aに書き込み操作を実行してキャッシュを削除するように要求する
  2. リクエスト A はデータベースにデータを書き込みます。
  3. Bにキャッシュを照会するよう要求し、キャッシュに値がないことを確認する
  4. B にスレーブ データベースを照会するように要求します。この時点では、マスターとスレーブの同期が完了していないため、クエリの結果は古い値になります。
  5. Bに古い値をキャッシュに書き込むように要求する
  6. データベースはマスタースレーブ同期を完了し、スレーブデータベースは新しい値に変更されます。

上記の状況がデータの不整合の原因です。二重削除遅延戦略を引き続き使用します。ただし、マスタースレーブ同期の遅延時間に基づいて、スリープ時間が変更され、数百ミリ秒が追加されます。

この同期除去戦略を採用したときにスループットが低下した場合はどうすればよいでしょうか?

OK、では 2 番目の削除を非同期にします。スレッドを開始し、非同期的に削除します。この方法では、書き込み要求は戻る前に一定時間スリープする必要がありません。そうすることでスループットが向上します。

2 回目の削除が失敗した場合はどうなりますか?

これは非常に良い質問です。なぜなら、2 回目の削除が失敗すると、次の状況が発生するからです。まだ 2 つのリクエストがあります。1 つは更新するリクエスト A 用、もう 1 つはクエリするリクエスト B 用です。便宜上、単一のデータベースを想定します。

  1. Aに書き込み操作を実行してキャッシュを削除するように要求する
  2. Bにクエリを要求し、キャッシュが存在しないことを確認する
  3. Bにデータベースを照会して古い値を取得するよう要求する
  4. Bに古い値をキャッシュに書き込むように要求する
  5. Aに新しい値をデータベースに書き込むように要求する
  6. リクエスト A はリクエスト B によって書き込まれたキャッシュ値を削除しようとしますが、失敗します。

はい、その通りです。 2 回目のキャッシュ削除に失敗すると、キャッシュとデータベースの不整合の問題が再び発生します。

どうすれば解決できるでしょうか?

具体的な解決策については、ブロガーによる第 3 回目の更新戦略の分析を参照してください。

まずデータベースを更新し、次にキャッシュを削除します

まず、これについてお話しさせてください。外国人は「Cache-Aside パターン」と呼ばれるキャッシュ更新ルーチンを提案しました。それは指摘する

  1. 無効化: アプリケーションはまずキャッシュからデータを取得します。データが取得できない場合は、データベースからデータを取得します。成功した場合、データはキャッシュに格納されます。
  2. *** : アプリケーションはキャッシュからデータを取得して返します。
  3. 更新: 最初にデータをデータベースに保存し、成功したらキャッシュを無効にします。

さらに、有名なソーシャル ネットワーキング サイト Facebook も、「Facebook での Memcache のスケーリング」という論文で、最初にデータベースを更新してからキャッシュを削除するという戦略を採用することを提案しました。

この場合、同時実行の問題はありませんか?

いいえ。クエリ操作 A のリクエストと更新操作 B のリクエストの 2 つがあると仮定すると、次の状況が発生します。

  1. キャッシュの有効期限が切れました
  2. Aにデータベースを照会して古い値を取得するよう要求する
  3. Bに新しい値をデータベースに書き込むように要求する
  4. Bにキャッシュを削除するよう要求する
  5. 見つかった古い値をキャッシュに書き込むようにAに要求する

はい、上記のような状況が発生すると、確かにダーティデータが発生します。

しかし、これが起こる可能性はどれくらいでしょうか?

上記の状況が発生するには、ステップ(3)のデータベース書き込み操作にかかる時間がステップ(2)のデータベース読み取り操作にかかる時間よりも短いという前提条件があり、これによりステップ(4)がステップ(5)に先行することが可能になります。しかし、考えてみてください。データベースの読み取り操作の速度は、書き込み操作の速度よりもはるかに高速です (そうでなければ、なぜ読み取りと書き込みを分離するのでしょうか? 読み取りと書き込みを分離する意味は、読み取り操作の方が高速で、消費するリソースが少ないためです)。したがって、ステップ(3)はステップ(2)よりも時間がかかりません。このような状況は起こりそうにありません。

ある人が議論を主張し、強迫性障害を患っていて、問題を解決しなければならないとします。私たちは何をすべきでしょうか?

上記の同時実行性の問題を解決するにはどうすればよいでしょうか?

まず、キャッシュの有効期間を設定することが 1 つの解決策です。次に、戦略(2)で示した非同期遅延削除戦略を採用して、読み取り要求が完了した後に削除操作が実行されるようにします。

矛盾が生じる他の理由はありますか?

はい、これはキャッシュ更新戦略 (2) とキャッシュ更新戦略 (3) の両方に存在する問題でもあります。キャッシュの削除に失敗した場合はどうなりますか?それは矛盾を生じさせませんか?たとえば、データの書き込み要求が行われ、データがデータベースに書き込まれても、キャッシュを削除できないため、不整合が発生します。これは、キャッシュ更新戦略(2)に残された最後の質問でもあります。

どうすれば解決できるでしょうか?

保証された再試行メカニズムを提供するだけです。ここに2つの解決策があります。

オプション1:

下の図に示すように

プロセスは以下のとおりです

  1. データベースデータを更新します。
  2. さまざまな問題によりキャッシュの削除に失敗しました
  3. 削除するキーをメッセージキューに送信します
  4. メッセージを自分で消費し、削除する必要があるキーを取得します
  5. 削除操作が成功するまで再試行を続けます

ただし、このソリューションには、ビジネス ライン コードへの大きな侵入を引き起こすという欠点があります。そこで、2番目の解決策があります。 2 番目のソリューションでは、サブスクリプション プログラムを起動してデータベースの binlog をサブスクライブし、操作する必要があるデータを取得します。アプリケーションで別のプログラムを起動して、サブスクリプション プログラムから情報を取得し、キャッシュを削除します。

オプション2:

プロセスを次の図に示します。

  1. データベースデータを更新する
  2. データベースは操作情報をbinlogログに書き込みます。
  3. サブスクリプションプログラムは必要なデータとキーを抽出します
  4. この情報を取得するには、別の非ビジネスコードを開始してください
  5. キャッシュを削除しようとしましたが、削除に失敗しました
  6. この情報をメッセージキューに送信します
  7. メッセージ キューからデータを再度取得し、操作を再試行してください。

: 上記の binlog サブスクリプション プログラムには、MySQL の canal と呼ばれる既製のミドルウェアがあり、binlog ログのサブスクリプション機能を実行できます。 Oracle に関しては、現時点では既製のミドルウェアが利用可能かどうかはわかりません。さらに、再試行メカニズムとして、ブロガーはメッセージ キュー方式を使用します。一貫性の要件がそれほど高くない場合は、プログラム内で別のスレッドを直接開始し、時々再試行することができます。ご自身のアイデアを柔軟に活用できます。これは単なる提案です。

要約する

この記事は、インターネット上の既存の一貫性ソリューションをまとめたものです。最初にキャッシュを削除してからデータベースを更新するという更新戦略に関しては、メモリ キューを維持するという提案もあります。ブロガーは見て、実装が非常に複雑で不必要だと感じたので、記事で紹介する必要はないと判断しました。 ***、皆さんがそこから何かを得られることを願っています。

<<:  【WOT2018】Li Mingyu: OpenStackクラウド上でビッグデータシステムを実行する際の難しさと方法

>>:  TICのブロックチェーン技術、UCloudがブロックチェーンセキュリティアプリケーションの実装をリード

推薦する

Hujiang.com: 英語を「売る」組立ラインがB2Cによって推進されている

スタートアップID起業家:傅才瑞創業時期: 2001年スタートアップ拠点:上海ビジネスモデル:広告収...

高級品ウェブサイトが停止、購買代理店の混乱がグループ購入の失敗を繰り返す可能性

中国の高級品オンラインショッピングの巨大な市場需要は、少しの混乱で簡単に変わることはないだろう。現在...

検索エンジンアービトラージの2つのモデルの分析

裁定取引は金融用語です。学術的な説明では、2 つの市場で同じ商品を有利な価格で売買することを意味しま...

恥ずかしい道を歩んでいる今、新浪微博は何をすべきか?

みなさんこんにちは、シャオシです。今日は「新浪微博の終焉」という記事を読みました。よく書かれていると...

2024 年のエンタープライズ クラウド戦略の 7 つのトレンド

クラウド コンピューティング市場が常に方向を変えていることは、すべての CIO が認識しています。し...

ブラックフライデーの草の根ウェブマスターの悪夢

かつて、金曜日は多くの草の根ウェブマスターが心待ちにしていた日であり、毎週の百度アップデートは何千人...

ドメイン名の履歴はSEOに影響を与える要因です

月給5,000~50,000のこれらのプロジェクトはあなたの将来ですドメイン名の履歴は、ウェブサイト...

推奨: certifiedhosting - 50% オフ ホスティング プロモーション/フェニックス/アトランタ

この昔ながらのホスティング会社、certifiedhosting では、仮想ホスティングの 50% ...

10分で自分のイメージを構築する方法を学ぶ

Docker イメージを作成するには、一般的に 2 つの方法があります。 ハブウェアハウスの既存の環...

機能的なユーザーエクスペリエンスの観点から、360 Search と Baidu Search の類似点と相違点について説明します。

360 Searchは最近、広く宣伝されています。最近、360 Searchを試しています。結局のと...

Linodeはどうですか?フランスのパリのデータセンターにおけるクラウドサーバーレビュー

Linodeはどうですか? Linode France クラウド サーバーはいかがでしょうか? Ak...

Nutanix、2019年のエンタープライズクラウドインデックスレポートを発表、企業のハイブリッドクラウドへの移行を支援するために協力

ハイパーコンバージェンスからスタートし、中国市場にハイパーコンバージェンスを成功裏に導入したNuta...

Pinduoduo はなぜ Gome を買収したいのでしょうか?

国美は自社製品を拼多多の店頭に並べた。ピンドゥオドゥオは4月19日、家電販売チェーンの国美小売が発行...

承徳双樓星業暖房はスマート暖房を実現するために、優先クラウドサービスプロバイダーとしてアマゾンウェブサービスを選択

2022年11月15日、アマゾン ウェブ サービスは、都市暖房業界の情報化の先駆者である承徳双管区星...