目次
1. 4 つの同期戦略:
2. キャッシュを更新するかキャッシュを削除する
2.1 更新キャッシュ
2.2 キャッシュの削除
3. データベースとキャッシュを先に操作する
3.1 最初にキャッシュを削除し、次にデータベースを更新します
データベースが読み取りと書き込みの分離アーキテクチャを採用している場合、以下に示すように、新たな問題が発生します。
ホームページ データベース Redis Redis キャッシュとデータベース間の一貫性を確保する方法

Redis キャッシュとデータベース間の一貫性を確保する方法

Mar 17, 2022 pm 06:50 PM
redis

この記事では、Redis に関する関連知識を提供します。主に、キャッシュの更新やデータベースの更新など、Redis キャッシュとデータベースの一貫性を確保する方法を紹介します。ヘルプ。

Redis キャッシュとデータベース間の一貫性を確保する方法

推奨される学習: Redis 学習チュートリアル

1. 4 つの同期戦略:

キャッシュの一貫性を確保したいデータベースの二重書き込みでは、4 つの方法、つまり 4 つの同期戦略があります:

  1. 最初にキャッシュを更新してからデータベースを更新する;
  2. 最初にデータベースを更新する、次にキャッシュを更新します。
  3. 最初にキャッシュを削除してから、データベースを更新します。
  4. 最初にデータベースを更新してから、キャッシュを削除します。

これら 4 つの同期戦略のうち、比較する必要があるのは次のとおりです。

キャッシュを更新する方法とキャッシュを削除する方法はどちらがより適切ですか?データベースを最初に操作する必要がありますか、それともキャッシュを最初に操作する必要がありますか?

2. キャッシュを更新するかキャッシュを削除する

次に、キャッシュを更新するか削除するかを分析しましょう。

2.1 更新キャッシュ

利点:キャッシュはデータが変更されるたびに適時に更新されるため、クエリ中にミスが発生する可能性が低くなります。

デメリット:キャッシュの更新には多額の費用がかかります。データをキャッシュに書き込む前に複雑な計算を行う必要がある場合、キャッシュを頻繁に更新するとサーバーのパフォーマンスに影響します。データが頻繁に書き込まれるビジネス シナリオの場合、キャッシュが頻繁に更新されるとデータを読み取るビジネスがなくなる可能性があります。

2.2 キャッシュの削除

メリット:操作が簡単、更新操作が複雑でも、キャッシュ内のデータは削除されません。直接削除されます。

欠点:キャッシュを削除すると、次のクエリ キャッシュが失われるため、データベースを再度読み取る必要があります。上記の比較から、一般に、キャッシュを削除する方が良い解決策となります。

3. データベースとキャッシュを先に操作する

次に、データベースとキャッシュのどちらを先に操作するべきかを分析してみましょう。
まず、最初にキャッシュを削除し、最初にデータベースを更新し、障害が発生した場合の比較を行います。

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

Redis キャッシュとデータベース間の一貫性を確保する方法
上記のように、キャッシュが削除されてからデータベースが更新される 障害が発生した場合に発生する可能性がある問題:

  • スレッド A はキャッシュの削除に成功しましたが、スレッド A はデータベースの更新に失敗します。
  • スレッド B はキャッシュからデータを読み取ります。キャッシュが削除されているため、プロセス B はキャッシュからデータを取得できず、データベースからデータを読み取ります。この時点ではの場合、データベース内のデータの更新は失敗しますが、スレッド B はデータベースから古いデータを正常に取得し、データはキャッシュに更新されます。
  • 最終的に、キャッシュとデータベースのデータは一貫していますが、古いデータのままです
#3.2 最初にデータベースを更新してから削除しますキャッシュ

Redis キャッシュとデータベース間の一貫性を確保する方法 上に示すように、最初にデータベースが更新されてからキャッシュが削除されます。
が失敗した場合に発生する可能性がある問題:

    スレッド A はデータベースを正常に更新し、スレッド A はキャッシュの削除に失敗しました;
  • スレッド B はキャッシュを正常に読み取りました キャッシュの削除に失敗したため、スレッド B はキャッシュ内の古いデータを読み取りました。
  • 最後に、スレッド A はキャッシュを正常に削除し、他のスレッドはキャッシュ内の同じデータ (データベース内のデータと同じ) にアクセスします。
  • 最終的には、キャッシュとデータベースのデータに一貫性が保たれますが、一部のスレッドは古いデータを読み取ります。
上記の比較の結果、

障害が発生した場合、キャッシュを削除するのが先か、データベースを更新するのが先か、どちらの方法が優れているかを明確に区別することはできないことがわかりました。 、どちらも優れていると考えていますが、問題があります。これら 2 つの方法については後でさらに比較しますが、ここではまず、上記のシナリオで発生する問題を解決する方法について説明します。

実際、キャッシュとデータベースの同期に上記のどの方法を使用しても、2 番目のステップが失敗した場合は、

再試行メカニズムを使用して問題を解決することをお勧めします。上の2枚の写真はすでに塗装済みです。



次に、最初にキャッシュを削除し、最初にデータベースを更新し、障害がない場合の
を比較します。

次のように上記では、最初にキャッシュが削除され、次にデータベースが更新されます。
が失敗しない場合、Redis キャッシュとデータベース間の一貫性を確保する方法 考えられる問題:

  • スレッド A はキャッシュの削除に成功しました;
  • スレッド B はキャッシュの読み取りに失敗しました;
  • スレッド B はデータベースの読み取りに成功し、古いデータを取得しました;
  • スレッド B は古いデータをキャッシュに正常に更新しました;
  • スレッド A は新しいデータをデータベースに正常に更新しました。

プロセス A の 2 つのステップは成功しましたが、同時実行により、プロセス B が 2 つのステップの間にキャッシュにアクセスしたことがわかります。 最終的に、古いデータはキャッシュに保存され、新しいデータはデータベースに保存され、2 つのデータは矛盾します。



Redis キャッシュとデータベース間の一貫性を確保する方法
上記のように、最初にデータベースが更新され、その後キャッシュが削除されます。 が失敗しない場合、 考えられる問題:

  • スレッド A はデータベースを正常に更新します;
  • スレッド B はキャッシュを正常に読み取ります;
  • スレッド A はキャッシュを正常に削除します。

最終キャッシュはデータベース内のデータと一致しており、両方とも最新のデータであることがわかります。ただし、スレッド B はこのプロセス中に古いデータを読み取ります。これら 2 つのステップの間にキャッシュ内の古いデータを読み取るスレッド B のような他のスレッドが存在する可能性がありますが、これら 2 つのステップの実行速度が速いため、影響はありません。大きい。この 2 つの手順を実行すると、他のプロセスがキャッシュされたデータを読み出すときに、プロセス B のような問題は発生しなくなります。

最終結論:

比較すると、最初にデータベースを更新してからキャッシュを削除するのが影響の少ない解決策であることがわかります。 2 番目のステップが失敗した場合は、再試行メカニズムを使用して問題を解決できます。

4. 遅延二重削除

上で述べたように、

最初にキャッシュを削除してからデータベースを更新すると、問題が発生する可能性があります。データの不整合。実際のアプリケーションで、何らかの考慮事項によりこの方法を選択する必要がある場合、この問題を解決する方法はありますか?答えは「はい」です。それは、遅延二重削除戦略を採用することです。遅延二重削除の基本的な考え方は次のとおりです:

キャッシュを削除します。
  1. データベースを更新します;
  2. N ミリ秒スリープします;
  3. キャッシュを再度削除します。
  4. 	public void write(String key, Object data) {
            Redis.delKey(key);
            db.updateData(data);
            Thread.sleep(1000);
            Redis.delKey(key);
        }
    ログイン後にコピー
一定期間ブロックした後、再度キャッシュを削除して、キャッシュ内の矛盾したデータを削除します

。具体的な時間については、業務のおおよその時間を評価し、それに応じて設定する必要があります。 4.1 読み取り/書き込み分離アーキテクチャを採用する場合はどうすればよいですか?

データベースが読み取りと書き込みの分離アーキテクチャを採用している場合、以下に示すように、新たな問題が発生します。


この時点で、A (更新操作) を要求する 2 つのリクエストが来ました。そしてリクエスト B (クエリ操作) Redis キャッシュとデータベース間の一貫性を確保する方法

Request A update Operation, delete Redis;
  1. メイン ライブラリに更新操作の実行をリクエストし、メイン ライブラリとスレーブ ライブラリの同期をリクエストしますデータ ;
  2. B にクエリ操作を依頼して、Redis にデータがないことがわかりました;
  3. データベースからデータを取得してください;
  4. この時点で、データの同期が完了しておらず、取得されたデータは古いデータです;
  5. 現時点での解決策は、Redis を使用してデータを埋めるためにデータベースにクエリを実行する場合、強制的にクエリ用のメイン データベースを指します。

削除に失敗した場合はどうすればよいですか?

それでも削除に失敗する場合は、再試行回数を増やすこともできますが、一定の回数を超えた場合は、エラーの報告、ログの記録、メールによるリマインダーの送信などの措置を講じる必要があります。取らなければなりません。

5. メッセージ キューを使用して削除を補う

最初にデータベースを更新してから、キャッシュを削除します

この状況でも問題が発生します。たとえば、データベースが更新されます。成功しましたが、キャッシュ削除の段階でエラーが発生して削除が成功しなかった場合、この時に再度キャッシュを読み込むと、毎回データが間違ってしまいます。
Redis キャッシュとデータベース間の一貫性を確保する方法現時点での解決策は、メッセージ キューを使用して削除を補うことです。特定のビジネス ロジックは次の言語で説明されています:

スレッド A に最初にデータベースを更新するよう要求します;
  1. Redis の削除時にエラーが報告され、削除に失敗しました;
  2. このとき、Redis キーがメッセージ本文としてメッセージ キューに送信されます;
  3. システムは、メッセージ キューによって送信されたメッセージを受信した後、再度 Redis を削除します;
  4. しかし、このソリューションには、ビジネス コードへの侵入が多くなり、相互に深く結合されるという欠点があるため、現時点では最適化方法が用意される予定です。Mysql データベースは で更新されることがわかっています。操作後の binlog 対応する操作をすべて見つけることができ、Mysql データベースの binlog ログをサブスクライブしてキャッシュを操作できます。


Redis キャッシュとデータベース間の一貫性を確保する方法 推奨学習:

Redis チュートリアル

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

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Redisクラスターモードの構築方法 Redisクラスターモードの構築方法 Apr 10, 2025 pm 10:15 PM

Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

基礎となるRedisを実装する方法 基礎となるRedisを実装する方法 Apr 10, 2025 pm 07:21 PM

Redisはハッシュテーブルを使用してデータを保存し、文字列、リスト、ハッシュテーブル、コレクション、注文コレクションなどのデータ構造をサポートします。 Redisは、スナップショット(RDB)を介してデータを維持し、書き込み専用(AOF)メカニズムを追加します。 Redisは、マスタースレーブレプリケーションを使用して、データの可用性を向上させます。 Redisは、シングルスレッドイベントループを使用して接続とコマンドを処理して、データの原子性と一貫性を確保します。 Redisは、キーの有効期限を設定し、怠zyな削除メカニズムを使用して有効期限キーを削除します。

Redisのすべてのキーを表示する方法 Redisのすべてのキーを表示する方法 Apr 10, 2025 pm 07:15 PM

Redisのすべてのキーを表示するには、3つの方法があります。キーコマンドを使用して、指定されたパターンに一致するすべてのキーを返します。スキャンコマンドを使用してキーを繰り返し、キーのセットを返します。情報コマンドを使用して、キーの総数を取得します。

Redisのバージョン番号を表示する方法 Redisのバージョン番号を表示する方法 Apr 10, 2025 pm 05:57 PM

Redisバージョン番号を表示するには、次の3つの方法を使用できます。(1)情報コマンドを入力し、(2) - versionオプションでサーバーを起動し、(3)構成ファイルを表示します。

Redis-Serverが見つからない場合はどうすればよいですか Redis-Serverが見つからない場合はどうすればよいですか Apr 10, 2025 pm 06:54 PM

Redis-Serverが見つからない問題を解決するための手順:インストールを確認して、Redisが正しくインストールされていることを確認します。環境変数Redis_hostとredis_portを設定します。 Redis Server Redis-Serverを起動します。サーバーがRedis-Cli pingを実行しているかどうかを確認します。

Redis Zsetの使用方法 Redis Zsetの使用方法 Apr 10, 2025 pm 07:27 PM

Redis Orderedセット(ZSET)は、並べ替えられた要素を保存し、関連するスコアでソートするために使用されます。 zsetを使用する手順には次のものがあります。1。zsetを作成します。 2。メンバーを追加します。 3.メンバースコアを取得します。 4。ランキングを取得します。 5.ランキング範囲のメンバーを取得します。 6.メンバーを削除します。 7.要素の数を取得します。 8。スコア範囲のメンバーの数を取得します。

Redisのソースコードを読み取る方法 Redisのソースコードを読み取る方法 Apr 10, 2025 pm 08:27 PM

Redisソースコードを理解する最良の方法は、段階的に進むことです。Redisの基本に精通してください。開始点として特定のモジュールまたは機能を選択します。モジュールまたは機能のエントリポイントから始めて、行ごとにコードを表示します。関数コールチェーンを介してコードを表示します。 Redisが使用する基礎となるデータ構造に精通してください。 Redisが使用するアルゴリズムを特定します。

Redisコマンドの使用方法 Redisコマンドの使用方法 Apr 10, 2025 pm 08:45 PM

Redis指令を使用するには、次の手順が必要です。Redisクライアントを開きます。コマンド(動詞キー値)を入力します。必要なパラメーターを提供します(指示ごとに異なります)。 Enterを押してコマンドを実行します。 Redisは、操作の結果を示す応答を返します(通常はOKまたは-ERR)。

See all articles