Redis 開発における一般的な問題 - キャッシュの侵入 - キャッシュ雪崩 - Redis のブレイン スプリット

Redis 開発における一般的な問題 - キャッシュの侵入 - キャッシュ雪崩 - Redis Brain の分割キャッシュの破壊


序文

日常の開発では、私たちは皆、データを保存するためにデータベースを使用します。一般的なシステム タスクでは通常、高い同時実行性がないため、これは問題になりませんが、一度大量のデータが必要になると、製品を急いで購入したり、ホームページへのアクセス数が瞬間的に多くなったりする場合、データベースを使用してデータを保存するだけのシステムは、ディスク指向であり、ディスクの読み取り/書き込み速度が遅いため、パフォーマンスに重大な欠点が生じます。比較的遅い。何千ものリクエストが受信され、システムは非常に短期間に何千もの読み取り/書き込み操作を完了する必要がある。多くの場合、これはデータベースが耐えられる量ではなく、データベース システムが異常な状態になるのは非常に簡単である麻痺し、最終的にはサービスのダウンタイムにつながる、本番環境に重大な問題が発生する。上記の問題を克服するために、プロジェクトでは通常、メモリベースのデータベースであり、特定の永続化機能を提供する NoSQL テクノロジを導入します。


Redis テクノロジーは NoSQL テクノロジーの 1 つですが、Redis の導入により、キャッシュの侵入、キャッシュなだれ、キャッシュの破壊などの問題が発生する可能性があります。この記事では、これらの問題についてさらに詳しく分析します。

1. Redis キャッシュの浸透

キャッシュペネトレーションとは何ですか?

簡単に言うと、データを取得するときは、まず redis に行ってデータを見つけます。結果が見つからない場合は、MySQL に行ってデータを見つけます。それでも結果が見つからない場合は、受信するすべてのスレッドが次のことを行う必要があります。この場合、データベースへの負荷が大きくなり、クラッシュする現象をキャッシュペネトレーションと呼びます。
ここに画像の説明を挿入します

2. Redis でのキャッシュ雪崩

ここに画像の説明を挿入します

3. Redis のスプリットブレイン問題

ここに画像の説明を挿入します
クライアントはメイン サーバーにデータを書き込みますが、メイン サーバーには同期する時間がありません。メイン サーバーが停止した場合は、この時点で新しいメイン サーバーが選択されます。元のメイン サーバーは一定の時間が経過すると回復します。この時点では、 、元のメインサーバー このサーバーはスレーブサーバーとしてのみ使用できます マスターサーバーのデータは同期できないことがわかります この問題は、redis のスプリットブレイン問題です。

解決

min-slaves-to-write 1 これは、クライアントがデータを書き込むとき、このデータを書き込むためにメイン サーバー上の少なくとも 1 つのスレーブ サーバーが正常に接続されている必要があることを意味します。

min-slaves-max-lag 10: これは、マスターとスレーブの同期時間が 10 秒であることを意味します。

4. キャッシュの内訳

ここで、キャッシュの侵入の違いに注意する必要があります。キャッシュ ブレークダウンとは、非常にホットで常に大量の同時実行を実行するキーを指します。大規模な同時実行は、このポイントへのアクセスに焦点を当てます。キーの有効期限が切れると、継続的な大規模な同時実行はキャッシュを突破し、データベースに直接リクエストします。たとえば、データベースに穴を開けるようなものです。障害。

キーの有効期限が切れると、大量の同時アクセス要求が発生します。このタイプのデータは一般にホット データです。キャッシュの有効期限が切れるため、データベースは同時にアクセスされ、最新のデータのクエリとキャッシュへの書き戻しが行われます。 、これにより、データベースに過剰な負荷が瞬時に発生します。

解決策:
1. ホットスポット データを無期限に設定します
キャッシュ層から​​は有効期限が設定されていないため、ホットスポット キーの有効期限が切れても問題はありません。

2. ミューテックスロックを追加する

分散ロック: 分散ロックを使用すると、1 つのスレッドだけが各キーに対してバックエンド サービスに同時にクエリを実行できるようになります。他のスレッドには分散ロックを取得する権限がないため、待つだけで済みます。この方法では、高い同時実行性の圧力が分散ロックに伝達され、分散ロックにとって大きな課題となります。
ここに画像の説明を挿入します

JAVAコードの実装

 static Lock reenLock = new ReentrantLock();
    public String findPubConfigByKey1(String key) throws InterruptedException {
    
    
        PubConfig result = new PubConfig();
        // 从缓存读取数据
        result = redisService.getObject(PubConfigKeyConstants.TABLE_NAME + "_"+key, PubConfig.class) ;
        if (result== null ) {
    
    
            if (reenLock.tryLock()) {
    
    
                try {
    
    
                    System.out.println("拿到锁了,从DB获取数据库后写入缓存");
                    // 从数据库查询数据
                    result = pubConfigRepository.queryPubConfigInfoByKey(key);
                    // 将查询到的数据写入缓存
                    Gson g = new Gson();
                    String value = g.toJson(result);
                    redisService.setNx(PubConfigKeyConstants.TABLE_NAME + "_"+key, value);
                } finally {
    
    
                    reenLock.unlock();// 释放锁
                }
 
            } else {
    
    
                // 先查一下缓存
                result = redisService.getObject(PubConfigKeyConstants.TABLE_NAME + "_"+key, PubConfig.class) ;
                if (result== null) {
    
    
                    System.out.println("我没拿到锁,缓存也没数据,先小憩一下");
                    Thread.sleep(100);// 小憩一会儿
                    return findPubConfigByKey1(key);// 重试
                }
            }
        }
        return result.getValue();
    }

要約する

ビジネス システムの場合、常にケースバイケースでの分析が行われ、最適なものはなく、最適なものだけが存在します。

キャッシュの満杯やデータ損失など、その他のキャッシュの問題については、自分で学習できます。最後に、LRU、RDB、AOF という 3 つの単語について説明します。通常、私たちはオーバーフローに対処するために LRU 戦略を使用し、特定の状況下でデータのセキュリティを確保するために Redis の RDB および AOF 永続化戦略を使用します。

元のリンク: https://blog.csdn.net/fan521dan/article/details/104782315?spm=1001.2014.3001.5501

おすすめ

転載: blog.csdn.net/qq_38055805/article/details/122445780