キャッシュ更新のポリシー

6091 ワード

キャッシュ更新のポリシー
 
1、キャッシュを淘汰してから、データベースを更新する
    public void updateData1(DataObject dataObject) {
        //   ,    
        deleteFromCache(dataObject.getId());
        //   ,     
        updateFromDB(dataObject);
    }

問題の分析:
次の2つの同時操作があります.
  • 1、更新要求によりキャッシュ
  • が削除する.
  • 2、クエリ要求ヒットキャッシュがない
  • 3、クエリー要求データベースから読み出すデータをキャッシュ
  • に入れる.
  • 4、更新要求はデータベースのデータを更新した.したがって、キャッシュ中のデータは古いデータであるか、キャッシュ中のデータは汚れた
  • である.
    2、データベースを更新してからキャッシュを変更する
        public void updateData3(DataObject dataObject) {
            //   ,     
            updateFromDB(dataObject);
            //   ,    
            setDataToCache(dataObject.getId(), dataObject);
        }
    

    問題の分析:
    2つの同時更新操作、操作タイミング
  • 1、要求1更新データベース
  • 2、要求2更新データベース
  • 3、要求2 setキャッシュ
  • 4、要求1 setキャッシュデータベースのデータは要求2設定、キャッシュのデータは要求1設定、データベースとキャッシュのデータが一致しない
  • である.
    3、データベースを更新してからキャッシュを淘汰する
        public void updateData2(DataObject dataObject) {
            //   ,     
            updateFromDB(dataObject);
            //   ,    
            deleteFromCache(dataObject.getId());
        }
    

    クラシックなCache Aside Patternです
    問題の分析:
    最初のステップのデータベースの更新に成功し、2番目のステップのキャッシュ操作に失敗すると、キャッシュ内の汚いデータが発生し、原子性が保証されません.
    2つの同時操作で、操作タイミングは以下の通りである:1、クエリー要求がキャッシュにヒットしていない2、クエリー要求がデータベースからデータを読み出す3、更新要求がデータベースを更新した4、更新要求がキャッシュを削除する5、クエリー要求が読み込んだ古いデータをキャッシュに入れるそこで、キャッシュ中のデータが古いデータなのか、キャッシュ中のデータが汚い
    しかし、このcaseは理論的に現れますが、実際に現れる確率は非常に低いかもしれません.この条件は、リードキャッシュ時にキャッシュが失効し、書き込み操作が同時に発生する必要があるからです.実際には、データベースの書き込み操作は読み取り操作よりもずっと遅く、テーブルをロックしますが、読み取り操作は書き込み操作の前にデータベース操作に入る必要があり、書き込み操作よりも遅くキャッシュを更新する必要があります.これらの条件はほとんどありません.
     
    4、データベースを更新してからキャッシュを淘汰し、原子性を保証する
    @Transactional    
    public void updateData(DataObject dataObject) {
            //   ,     
            updateFromDB(dataObject);
            //   ,    
            try {
                deleteFromCache(dataObject.getId());
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    

    問題の分析:
    Cache Aside Patternの改良版であり、クエリーと更新要求が同時に発生する問題も同様である.
    メソッドをトランザクションに配置して実行すると、キャッシュ操作に失敗してRuntimeExceptionを放出するとトランザクションがロールバックされます.原子的な欠点は、redisリモート操作がトランザクションの実行時間を長くし、同時実行を低減することです.
     
    いかなる技術案の設計も、折衷である.適当な案だけが、必ずしも最良の案があるとは限らない.