マイクロサービスキャッシュの使用メトリック

4213 ワード

キャッシュはプログラマーの心の中で最もよく知っている性能最適化手段の一つかもしれないが、旧文の中でマイクロサービスキャッシュ漫談のGuava CacheとRedisクラスタの構築と監視の中でそれぞれ最もよく使われるローカルメモリのGuava Cacheと遠隔のRedis Cacheを紹介した.ここではキャッシュのメトリックについて重点的に説明します.
キャッシュに関するFAQ
キャッシュについては、次のような問題があります.
  • Cache hit ratioキャッシュのヒット率
  • Cache key sizeキャッシュのキー値数
  • Cache resource usageキャッシュのリソース使用率
  • Cache loading performanceキャッシュのロード性能
  • Cache capacityキャッシュの容量
  • Cache lifetimeキャッシュのライフサイクル
  • Cacheは無限に成長することは不可能であり、永遠に有効であることは不可能であるため、Cacheのクリア戦略と失効戦略について細かく考慮しなければならない.Cacheに格納データについても、読み書きが高い方がよい、すなわち、読みが多く、書くことが少なく、頻繁に更新されない.
    キャッシュは万能薬ではなく、キャッシュの使用が適切でないとキャッシュの貫通、破壊、雪崩が発生します.まず、このいくつかの概念を簡単に説明します.
  • は、あるレコードを貫通してルートが存在しないため、キャッシュに見つからず、毎回データベースに読み込む必要がありますが、結果は見つかりません.

  • 一般的な対処法は、ブロンフィルタ(特徴は)または逆キャッシュ(キャッシュにこのレコードを保存し、存在しないことを示す)です.
  • は、あるレコードの期限切れが除去されたことを破壊し、適切に大量の関連クエリー要求このレコードを要求し、瞬時に大量の要求がキャッシュアクセスデータベース
  • を迂回する.
    データベースからデータをロードする操作をロックすることで、キャッシュを迂回するアクセス要求が少なくなります.あるいは、期限切れを設定するのではなく、バックグラウンドjobタイミングでキャッシュをリフレッシュし、外部のリクエストは常にキャッシュからデータを読み出すことができます.
    3.雪崩複数のサーバに記録されたキャッシュが同時に期限切れになって失効し、瞬時にキャッシュを迂回してデータベースにアクセスするよう大量の要求が発生し、これは破壊よりも深刻である.
    一般的な対処法は、複数のサーバ上の複数のレコードに異なる失効時間を設定し、ランダム値をゼロとして大量の同時要求をある時点から1つの期間に分散させることです.
    キャッシュされたメトリック
    キャッシュのヒット率、ロード・パフォーマンスなど、私たちが関心を持っているポイントは次のとおりです.
  • 性能Performance:Cacheロードの遅延latency
  • スループットThroughput:毎秒要求回数CPS(Call Per Second)
  • ヒット率:sucess_ratio = hitCount/(hitCount + missCount)
  • リソース使用量:使用メモリ数
  • リソース飽和度saturation:容量制限でcacheから削除するレコード数により、増加できないレコード数
  • がキャッシュいっぱいになる.
    注意:飽和度は、リソース負荷が処理能力を超えている場所です.
    GuavaCacheの場合、キャッシュ統計は次のルールに従って増加します.
  • キャッシュ検索が既存のキャッシュエントリに遭遇すると、hitCountが増加します.
  • キャッシュが最初に失われたキャッシュエントリを検索すると、新しいエントリがロードされます.
  • エントリのロードに成功すると、missCountとloadSuccessCountが増加し、合計ロード時間(ナノ秒単位)がtotalLoadTimeに追加されます.
  • エントリのロード中に例外が発生すると、missCountとloadExceptionCountが増加し、合計ロード時間(ナノ秒単位)がtotalLoadTimeに追加されます.
  • まだロードされていないキャッシュエントリに遭遇したキャッシュ検索は、ロードが完了するまで待機し(成功するかどうかにかかわらず)、missCountをインクリメントします.
  • がキャッシュからエントリを削除すると、evictionCountが増加します.
  • キャッシュ・エントリが無効または手動で削除された場合、統計は変更されません.
  • キャッシュされたasMapビューで呼び出されたアクションでは、統計は変更されません.

  • コードを書くときにrecordStatsを呼び出してこれらのメトリックデータを記録することができます
     @Bean
        public LoadingCache cityWeatherCache() {
            LoadingCache cache = CacheBuilder.newBuilder()
                    .recordStats()
                    .maximumSize(1000)
                    .expireAfterWrite(60, TimeUnit.MINUTES)
                    .build(weatherCacheLoader());
    
            recordCacheMetrics("cityWeatherCache", cache);
            return cache;
        }
    
        public void recordCacheMetrics(String cacheName, Cache cache) {
            MetricRegistry metricRegistry = metricRegistry();
            metricRegistry.gauge(generateMetricsKeyForCache(cacheName, "hitCount"), () -> () -> cache.stats().hitCount());
            metricRegistry.gauge(generateMetricsKeyForCache(cacheName, "hitRate"), () -> () -> cache.stats().hitRate());
    
            metricRegistry.gauge(generateMetricsKeyForCache(cacheName, "missCount"), () -> () -> cache.stats().missCount());
            metricRegistry.gauge(generateMetricsKeyForCache(cacheName, "missRate"), () -> () -> cache.stats().missRate());
    
            metricRegistry.gauge(generateMetricsKeyForCache(cacheName, "requestCount"), () -> () -> cache.stats().requestCount());
    
            metricRegistry.gauge(generateMetricsKeyForCache(cacheName, "loadCount"), () -> () -> cache.stats().loadCount());
            metricRegistry.gauge(generateMetricsKeyForCache(cacheName, "loadSuccessCount"), () -> () -> cache.stats().loadSuccessCount());
            metricRegistry.gauge(generateMetricsKeyForCache(cacheName, "loadExceptionCount"), () -> () -> cache.stats().loadExceptionCount());
        }
    
     public String generateMetricsKeyForCache(String cacheName, String keyName) {
            String metricKey = MetricRegistry.name("cache", cacheName, keyName);
            log.info("metric key generated for cache: {}", metricKey);
            return metricKey;
        }
    

    未完待続...