検索
ホームページデータベースmysql チュートリアルRedis と MySQL の二重書き込みキャッシュが矛盾している場合はどうすればよいですか?ソリューションの共有

Redis と MySQL の二重書き込みキャッシュに矛盾がある場合はどうすればよいですか?この記事では、キャッシュの二重書き込みの不一致の問題を解決する方法を紹介します。

Redis と MySQL の二重書き込みキャッシュが矛盾している場合はどうすればよいですか?ソリューションの共有

redis と mysql の二重書き込みキャッシュには一貫性がありません:

Redis と MySQL の二重書き込みキャッシュが矛盾している場合はどうすればよいですか?ソリューションの共有

ただし、キャッシュの更新に関しては、 データベースの更新が完了しました。キャッシュを更新するべきですか、それともキャッシュを削除すべきですか? または まずキャッシュを削除してからデータベースを更新します。実際には、多くの議論があります。 現時点では、これらのソリューションを分析する包括的なブログはありません。そこでブロガーは、みんなから批判される危険を冒して震えながらこの記事を書きました。

#テキスト

キャッシュされたデータの有効期限を設定する

最初に説明します。理論的には、キャッシュの有効期限は、最終的な整合性を確保するためのソリューションです。このソリューションでは、キャッシュに保存されたデータの有効期限を設定でき、すべての書き込み操作はデータベースの影響を受けるため、キャッシュ操作にのみ最善を尽くす必要があります。つまり、データベースの書き込みが成功し、キャッシュの更新が失敗した場合、有効期限に達している限り、後続の読み取りリクエストは自然にデータベースから新しい値を読み取り、キャッシュをバックフィルします。したがって、次に説明するアイデアは、キャッシュの有効期限を設定するという解決策に依存しません。

ここでは、最初に 3 つの

更新戦略について説明します:

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

この計画は一般に誰もが反対します。なぜ?ポイントは以下の 2 点です。

    理由 1 (スレッド安全性の観点)
(1) スレッド A がデータベースを更新した

(2) スレッド B がデータベースを更新したデータベース
(3) スレッド B がキャッシュを更新しました
(4) スレッド A がキャッシュを更新しました

つまり、A にキャッシュの更新を要求することは、B にキャッシュの更新を要求するよりも先に行う必要がありますが、ただし、ネットワークなどの理由により、B は A よりも早くキャッ​​シュを更新しました。これはデータがダーティになるため、考慮されません。

    理由 2 (ビジネス シナリオの観点)
(1) データベース書き込みシナリオが多く、データ読み取りシナリオが少ないビジネス ニーズがある場合は、これを使用してください。このソリューションでは、次のような問題が発生します。データが読み取られる前にキャッシュが頻繁に更新されるため、パフォーマンスが無駄になります。

(2) データベースに書き込む値がキャッシュに直接書き込まれない場合は、一連の複雑な計算を経てからキャッシュに書き込まれる必要があります。次に、データベースに書き込まれるたびにキャッシュに書き込まれる値を再計算することは、間違いなくパフォーマンスの無駄です。明らかに、キャッシュを削除する方が適切です。

最初にキャッシュを削除してからデータベースを更新してください

この解決策が不整合を引き起こす理由は次のとおりです。同時に、1 つは A に更新操作の実行を要求し、もう 1 つは B にクエリ操作の実行を要求します。次に、次の状況が発生します。

(1) A に書き込み操作の実行とキャッシュの削除を要求します

(2) B にクエリを要求し、キャッシュが存在しないことを確認します
(3 ) B にデータベースにクエリを実行して古い値を取得するように要求します
(4) B に古い値をキャッシュに書き込むように要求します
(5) A に新しい値をデータベースに書き込むように要求します

上記の状況では不整合が発生します。さらに、キャッシュの有効期限戦略を設定しない場合、データは常にダーティ データになります。

それでは、どうすれば解決できるでしょうか?遅延二重削除戦略を採用する

キャッシュ遅延二重削除
public class CacheServiceImpl implements ICacheService {

    @Resource
    private RedisOperator redisOperator;
    
    @Autowired
    private IShopService shopService;

    //1. 采用延时双删,解决数据库和缓存的一致性
    @Override
    public void updateHotCount(String id) {
        try {
            //删除缓存
            redisOperator.del("redis_key_" + id);
            //更新数据库
            shopService.updataHotShop();
            Thread.sleep(1000);//休眠1秒
            //延时删除
            redisOperator.del("redis_key_" + id);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

    @Override
    public Integer getHotCount(String id) {
        return null;
    }}

説明:

    最初にキャッシュを削除します
  1. データベースを再度書き込みます
  2. 1秒スリープしてからキャッシュを削除します (
  3. これにより、キャッシュされたダーティデータを再度1秒以内に削除できます。)

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

データベースが読み取りと書き込みの分離アーキテクチャを採用している場合はどうなるでしょうか? (メイン ライブラリは書き込み操作を担当し、スレーブ ライブラリは読み取り操作を担当します)

わかりました。この場合、データの不一致の理由は次のとおりです。まだ 2 つのリクエストがあり、1 つのリクエスト A は更新操作を実行し、もう 1 つのリクエストは B にクエリ操作を実行します。

(1) A に書き込み操作の実行を要求し、キャッシュを削除し、A にメイン ライブラリへのデータの書き込みを要求します。スレーブ ライブラリからの同期はまだ開始されていません

(2) (1秒以内) B にキャッシュのクエリを要求、キャッシュが見つからず、B にスレーブ データベースのクエリを要求 この時点ではマスタとスレーブの同期は完了しておらず、古い値が見つかり、古い値がキャッシュに書き込まれます。

(3) マスター データベースはマスターとスレーブの同期を完了し、スレーブ データベースは新しい値に変更されます。

上記のプロセスでは、データの不整合と二重削除の遅延が問題になります。という戦略も使われます。ただし、スリープ時間は、マスターとスレーブの同期遅延時間に数百ミリ秒を加えたものに基づいて変更されます。

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

わかりました。2 番目の削除を非同期として扱います。自分でスレッドを開始し、非同期的に削除します。このようにして、書き込まれたリクエストは返される前に一定期間スリープする必要がありません。そうすることでスループットが向上します。

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

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

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

わかりました、つまり。 2 回目にキャッシュの削除に失敗すると、再びキャッシュとデータベースの不整合が発生します。

どうすれば解決できますか?

具体的な解決策については、最初にデータベースを更新してからキャッシュを削除するという更新戦略に関するブロガーの分析を見てみましょう。

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

遅延二重削除キャッシュアサイドは、最初にデータベースを操作してからキャッシュを削除します。 、2 番目の手順でキャッシュを削除できなかったことにより、データの不整合の問題が発生する可能性があります。このソリューションを使用して最適化することができます。削除に失敗した場合は、さらに数回削除して、キャッシュの削除が確実に成功するようにします。したがって、削除キャッシュ再試行メカニズム

を導入できます。 Redis と MySQL の二重書き込みキャッシュが矛盾している場合はどうすればよいですか?ソリューションの共有

    ##(1) データベースのデータを更新します;
  1. (2) さまざまな問題によりキャッシュの削除に失敗しました
    (3) 削除する必要のあるキーをに送信しますメッセージキュー
    (4) メッセージを自分で消費し、削除する必要があるキーを取得します
    (5) 成功するまで削除操作を再試行し続けます
ただし、この解決策はには欠点があり、ビジネスラインコードへの多くの侵入を引き起こします。 2 番目のオプションでは、サブスクリプション プログラムを開始してデータベースのバイナリログをサブスクライブし、操作する必要のあるデータを取得します。アプリケーションで、新しいプログラムを起動して、このサブスクリプション プログラムから情報を取得し、キャッシュを削除します。

biglog の読み取りとキャッシュの非同期削除

Redis と MySQL の二重書き込みキャッシュが矛盾している場合はどうすればよいですか?ソリューションの共有

プロセスは次の図に示すとおりです。 1) データベース データを更新します

(2) データベースは操作情報を binlog ログに書き込みます

(3) サブスクリプション プログラムは必要なデータとキーを抽出します

(4) 非データベースの新しいセクションを開始します情報を取得するためのビジネス コード
(5) キャッシュ操作の削除を試みますが、削除に失敗したことがわかります。
(6) 情報をメッセージ キューに送信します。
(7) データをメッセージ キューから再取得します。メッセージキューを削除して、操作を再試行してください。

備考: 上記の binlog サブスクリプション プログラムには、mysql に canal と呼ばれる既製のミドルウェアがあり、binlog ログをサブスクライブする機能を完了できます。 Oracle については、ブロガーは現在、使用できる既製のミドルウェアがあるかどうかを知りません。また、リトライ機構として、ブロガーはメッセージキューを使用します。一貫性の要件がそれほど高くない場合は、プログラム内で新しいスレッドを開始し、時々再試行してください。これは柔軟に使用できますが、ここではアイデアを提供します。

この記事は、実際には、インターネット上の既存の整合性ソリューションの概要です。最初にキャッシュを削除してからデータベースを更新する更新戦略については、メモリキューを維持する計画もありますが、ブロガーはそれを見て、実装が非常に複雑で不必要であると感じたので、与える必要はありません記事の中で。最後に、皆さんが何かを得られたことを願っています。

[関連する推奨事項:

mysql ビデオ チュートリアル

]

以上がRedis と MySQL の二重書き込みキャッシュが矛盾している場合はどうすればよいですか?ソリューションの共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は简书で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
MySQL:初心者が習得するための必須スキルMySQL:初心者が習得するための必須スキルApr 18, 2025 am 12:24 AM

MySQLは、初心者がデータベーススキルを学ぶのに適しています。 1.MySQLサーバーとクライアントツールをインストールします。 2。selectなどの基本的なSQLクエリを理解します。 3。マスターデータ操作:テーブルを作成し、データを挿入、更新、削除します。 4.高度なスキルを学ぶ:サブクエリとウィンドウの関数。 5。デバッグと最適化:構文を確認し、インデックスを使用し、選択*を避け、制限を使用します。

MySQL:構造化データとリレーショナルデータベースMySQL:構造化データとリレーショナルデータベースApr 18, 2025 am 12:22 AM

MySQLは、テーブル構造とSQLクエリを介して構造化されたデータを効率的に管理し、外部キーを介してテーブル間関係を実装します。 1.テーブルを作成するときにデータ形式と入力を定義します。 2。外部キーを使用して、テーブル間の関係を確立します。 3。インデックス作成とクエリの最適化により、パフォーマンスを改善します。 4.データベースを定期的にバックアップおよび監視して、データのセキュリティとパフォーマンスの最適化を確保します。

MySQL:説明されている主要な機能と機能MySQL:説明されている主要な機能と機能Apr 18, 2025 am 12:17 AM

MySQLは、Web開発で広く使用されているオープンソースリレーショナルデータベース管理システムです。その重要な機能には、次のものが含まれます。1。さまざまなシナリオに適したInnodbやMyisamなどの複数のストレージエンジンをサポートします。 2。ロードバランスとデータバックアップを容易にするために、マスタースレーブレプリケーション機能を提供します。 3.クエリの最適化とインデックスの使用により、クエリ効率を改善します。

SQLの目的:MySQLデータベースとの対話SQLの目的:MySQLデータベースとの対話Apr 18, 2025 am 12:12 AM

SQLは、MySQLデータベースと対話して、データの追加、削除、変更、検査、データベース設計を実現するために使用されます。 1)SQLは、ステートメントの選択、挿入、更新、削除を介してデータ操作を実行します。 2)データベースの設計と管理に作成、変更、ドロップステートメントを使用します。 3)複雑なクエリとデータ分析は、ビジネス上の意思決定効率を改善するためにSQLを通じて実装されます。

初心者向けのMySQL:データベース管理を開始します初心者向けのMySQL:データベース管理を開始しますApr 18, 2025 am 12:10 AM

MySQLの基本操作には、データベース、テーブルの作成、およびSQLを使用してデータのCRUD操作を実行することが含まれます。 1.データベースの作成:createdatabasemy_first_db; 2。テーブルの作成:createTableBooks(idintauto_incrementprimarykey、titlevarchary(100)notnull、authorvarchar(100)notnull、published_yearint); 3.データの挿入:InsertIntoBooks(タイトル、著者、公開_year)VA

MySQLの役割:WebアプリケーションのデータベースMySQLの役割:WebアプリケーションのデータベースApr 17, 2025 am 12:23 AM

WebアプリケーションにおけるMySQLの主な役割は、データを保存および管理することです。 1.MYSQLは、ユーザー情報、製品カタログ、トランザクションレコード、その他のデータを効率的に処理します。 2。SQLクエリを介して、開発者はデータベースから情報を抽出して動的なコンテンツを生成できます。 3.MYSQLは、クライアントサーバーモデルに基づいて機能し、許容可能なクエリ速度を確保します。

MySQL:最初のデータベースを構築しますMySQL:最初のデータベースを構築しますApr 17, 2025 am 12:22 AM

MySQLデータベースを構築する手順には次のものがあります。1。データベースとテーブルの作成、2。データの挿入、および3。クエリを実行します。まず、createdAtabaseおよびcreateTableステートメントを使用してデータベースとテーブルを作成し、InsertINTOステートメントを使用してデータを挿入し、最後にSelectステートメントを使用してデータを照会します。

MySQL:データストレージに対する初心者向けのアプローチMySQL:データストレージに対する初心者向けのアプローチApr 17, 2025 am 12:21 AM

MySQLは、使いやすく強力であるため、初心者に適しています。 1.MYSQLはリレーショナルデータベースであり、CRUD操作にSQLを使用します。 2。インストールは簡単で、ルートユーザーのパスワードを構成する必要があります。 3.挿入、更新、削除、および選択してデータ操作を実行します。 4. Orderby、Where and Joinは複雑なクエリに使用できます。 5.デバッグでは、構文をチェックし、説明を使用してクエリを分析する必要があります。 6.最適化の提案には、インデックスの使用、適切なデータ型の選択、優れたプログラミング習慣が含まれます。

See all articles

ホット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ヘンタイを無料で生成します。

ホットツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール