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

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

Mar 15, 2022 am 11:18 AM
mysql redis

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 までご連絡ください。

ホット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な削除メカニズムを使用して有効期限キーを削除します。

phpmyAdminの脆弱性の概要 phpmyAdminの脆弱性の概要 Apr 10, 2025 pm 10:24 PM

PHPMyAdminセキュリティ防衛戦略の鍵は次のとおりです。1。PHPMyAdminの最新バージョンを使用し、PHPとMySQLを定期的に更新します。 2.アクセス権を厳密に制御し、.htaccessまたはWebサーバーアクセス制御を使用します。 3.強力なパスワードと2要素認証を有効にします。 4.データベースを定期的にバックアップします。 5.機密情報が公開されないように、構成ファイルを慎重に確認します。 6。Webアプリケーションファイアウォール(WAF)を使用します。 7.セキュリティ監査を実行します。 これらの測定は、不適切な構成、古いバージョン、または環境セキュリティのリスクにより、PHPMyAdminによって引き起こされるセキュリティリスクを効果的に削減し、データベースのセキュリティを確保することができます。

phpmyadminを開く方法 phpmyadminを開く方法 Apr 10, 2025 pm 10:51 PM

次の手順でphpmyadminを開くことができます。1。ウェブサイトコントロールパネルにログインします。 2。phpmyadminアイコンを見つけてクリックします。 3。MySQL資格情報を入力します。 4.「ログイン」をクリックします。

phpmyAdminの包括的な使用ガイド phpmyAdminの包括的な使用ガイド Apr 10, 2025 pm 10:42 PM

PHPMyAdminは単なるデータベース管理ツールではなく、MySQLを深く理解し、プログラミングスキルを向上させることができます。コア関数には、CRUDおよびSQLクエリの実行が含まれ、SQLステートメントの原則を理解することが重要です。高度なヒントには、データのエクスポート/インポートと許可管理が含まれ、深いセキュリティの理解が必要です。潜在的な問題にはSQLインジェクションが含まれ、ソリューションはパラメーター化されたクエリとバックアップです。パフォーマンスの最適化には、SQLステートメントの最適化とインデックスの使用が含まれます。ベストプラクティスは、コード仕様、セキュリティプラクティス、および定期的なバックアップを強調しています。

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)。

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

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

See all articles