国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

cache2k:Guava Cache及Caffeine之外的新選擇

這篇具有很好參考價值的文章主要介紹了cache2k:Guava Cache及Caffeine之外的新選擇。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本文主要研究一下cache2k這款新型緩存

示例

Cache<String,String> cache = new Cache2kBuilder<String, String>() {}
                .eternal(true)
                .expireAfterWrite(5, TimeUnit.MINUTES)    // expire/refresh after 5 minutes
                .setupWith(UniversalResiliencePolicy::enable, b -> b // enable resilience policy
                                .resilienceDuration(30, TimeUnit.SECONDS)          // cope with at most 30 seconds
                        // outage before propagating
                        // exceptions
                )
                .refreshAhead(true)                       // keep fresh when expiring
                .loader(k -> expensiveOperation(k))         // auto populating function
                .build();

常見問題的解決方案

空值問題

JCache規(guī)范不支持null,所以cache2k默認也不支持,不過可以通過permitNullValues(true)來開啟,這樣子緩存就可以存儲null值

cache stampede問題

又稱作cache miss storm,指的是高并發(fā)場景緩存同時失效導致大面積回源,cache2k采用的是block的請求方式,避免對同一個key并發(fā)回源

org/cache2k/core/HeapCache.java

protected Entry<K, V> getEntryInternal(K key, int hc, int val) {
    if (loader == null) {
      return peekEntryInternal(key, hc, val);
    }
    Entry<K, V> e;
    for (;;) {
      e = lookupOrNewEntry(key, hc, val);
      if (e.hasFreshData(clock)) {
        return e;
      }
      synchronized (e) {
        e.waitForProcessing();
        if (e.hasFreshData(clock)) {
          return e;
        }
        if (e.isGone()) {
          metrics.heapHitButNoRead();
          metrics.goneSpin();
          continue;
        }
        e.startProcessing(Entry.ProcessingState.LOAD, null);
        break;
      }
    }
    boolean finished = false;
    try {
      load(e);
      finished = true;
    } finally {
      e.ensureAbort(finished);
    }
    if (e.getValueOrException() == null && isRejectNullValues()) {
      return null;
    }
    return e;
  }

同步回源造成的接口穩(wěn)定性問題

cache2k提供了refreshAhead參數,在新數據沒有拉取成功之前,過期數據仍然可以訪問,避免請求到來時發(fā)現數據過期觸發(fā)同步回源造成接口延時增大問題。不過具體底層還依賴prefetchExecutor,如果refresh的時候沒有足夠的線程可以使用則會立馬過期,等待下次get出發(fā)同步回源

org/cache2k/core/HeapCache.java

public void timerEventRefresh(Entry<K, V> e, Object task) {
    metrics.timerEvent();
    synchronized (e) {
      if (e.getTask() != task) { return; }
      try {
        refreshExecutor.execute(createFireAndForgetAction(e, Operations.SINGLETON.refresh));
      } catch (RejectedExecutionException ex) {
        metrics.refreshRejected();
        expireOrScheduleFinalExpireEvent(e);
      }
    }
  }

默認的executor如下,采用的是SynchronousQueue隊列,可以通過builder自己去設置refreshExecutor

  Executor provideDefaultLoaderExecutor(int threadCount) {
    int corePoolThreadSize = 0;
    return new ThreadPoolExecutor(corePoolThreadSize, threadCount,
      21, TimeUnit.SECONDS,
      new SynchronousQueue<>(),
      threadFactoryProvider.newThreadFactory(getThreadNamePrefix()),
      new ThreadPoolExecutor.AbortPolicy());
  }

回源故障問題

針對回源的下游出現故障的問題,cache2k提供了ResiliencePolicy策略,其實現類為UniversalResiliencePolicy
當load方法拋出異常且cache里頭還有數據的時候,異常不會拋給client,用當前的數據返回,這里有個resilienceDuration時間,如果超過這個時間load方法還繼續(xù)拋出異常則異常會拋給client。如果沒有單獨設置resilienceDuration,則默認取的是expiryAfterWrite時間

org/cache2k/core/HeapCache.java

private Object loadGotException(Entry<K, V> e, long t0, long t, Throwable wrappedException) {
    ExceptionWrapper<K, V> exceptionWrapper =
      new ExceptionWrapper(keyObjFromEntry(e), wrappedException, t0, e, exceptionPropagator);
    long expiry = 0;
    long refreshTime = 0;
    boolean suppressException = false;
    RefreshAheadPolicy.Context<Object> refreshCtx;
    try {
      if (e.isValidOrExpiredAndNoException()) {
        expiry = timing.suppressExceptionUntil(e, exceptionWrapper);
      }
      if (expiry > t0) {
        suppressException = true;
      } else {
        expiry = timing.cacheExceptionUntil(e, exceptionWrapper);
      }
      refreshCtx = getContext(e, t0, t, true, true, false, expiry);
      refreshTime = timing.calculateRefreshTime(refreshCtx);
    } catch (Exception ex) {
      return resiliencePolicyException(e, t0, t, new ResiliencePolicyException(ex), null);
    }
    exceptionWrapper = new ExceptionWrapper<>(exceptionWrapper, Math.abs(expiry));
    Object wrappedValue = exceptionWrapper;
    if (expiry != 0) {
      wrappedValue = timing.wrapLoadValueForRefresh(refreshCtx, e, exceptionWrapper);
    }
    Object loadResult;
    synchronized (e) {
      insertUpdateStats(e, (V) wrappedValue, t0, t, true, expiry, suppressException);
      if (suppressException) {
        e.setSuppressedLoadExceptionInformation(exceptionWrapper);
        loadResult = e.getValueOrException();
      } else {
        if (isRecordModificationTime()) {
          e.setModificationTime(t0);
        }
        e.setValueOrWrapper(exceptionWrapper);
        loadResult = exceptionWrapper;
      }
      finishLoadOrEviction(e, expiry, refreshTime);
    }
    return loadResult;
  }

這里timing.suppressExceptionUntil是委托給了ResiliencePolicy#suppressExceptionUntil

cache2k-addon/src/main/java/org/cache2k/addon/UniversalResiliencePolicy.java

public long suppressExceptionUntil(K key,
                                     LoadExceptionInfo<K, V> loadExceptionInfo,
                                     CacheEntry<K, V> cachedEntry) {
    if (resilienceDuration == 0 || resilienceDuration == Long.MAX_VALUE) {
      return resilienceDuration;
    }
    long maxSuppressUntil = loadExceptionInfo.getSinceTime() + resilienceDuration;
    long deltaMs = calculateRetryDelta(loadExceptionInfo);
    return Math.min(loadExceptionInfo.getLoadTime() + deltaMs, maxSuppressUntil);
  }

UniversalResiliencePolicy還提供了異常重試的功能,重試間隔為retryInterval,如果沒有配置則為resilienceDuration的5%,采取的是指數退避的模式,factor為1.5

小結

cache2k提供了Guava Cache及Caffeine沒有的ResiliencePolicy,針對C端高并發(fā)場景提供了容錯的功能,值得借鑒一下。

個人公眾號「碼匠的流水賬」(geek_luandun),歡迎關注文章來源地址http://www.zghlxwxcb.cn/news/detail-437499.html

doc

  • cache2k
  • cache2k User Guide
  • Introduction to cache2k
  • caffeine
  • guava cache

到了這里,關于cache2k:Guava Cache及Caffeine之外的新選擇的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Guava:Cache強大的本地緩存框架

    Guava:Cache強大的本地緩存框架

    Guava Cache是一款非常優(yōu)秀的本地緩存框架。 Guava Cache 的數據結構跟 JDK1.7 的 ConcurrentHashMap 類似,提供了基于時間、容量、引用三種回收策略,以及自動加載、訪問統(tǒng)計等功能。 基本的配置 例子中,緩存最大容量設置為 100 ( 基于容量進行回收 ),配置了 失效策略 和 刷新策

    2024年02月02日
    瀏覽(21)
  • flink1.15 維表join guava cache和mysql方面優(yōu)化

    flink1.15 維表join guava cache和mysql方面優(yōu)化

    優(yōu)化前? mysql響應慢,導致算子中數據輸出追不上輸入,導致顯示cpu busy:100% 優(yōu)化后效果兩個圖對應兩個時刻: - - 圖中guava cache命中率是通過guava自帶統(tǒng)計,打印出來的. 1 guava緩存數據量上限?= 類中配置的guava緩存數據上線 * task個數(即flink并行度) 緩存越久 命中率越高 數據越陳舊

    2024年01月17日
    瀏覽(24)
  • ARM基礎(4):L1 Cache之I-Cache和D-cache詳解

    ARM基礎(4):L1 Cache之I-Cache和D-cache詳解

    在上一篇文章ARM基礎(3):MPU內存保護單元詳解及例子中,我介紹了MPU,我們知道MPU允許按區(qū)域修改一級Cache的屬性,這個Cache一般為L1 Cache,它位于CPU的內部,用來加快指令和數據的訪問速度。同時,CPU在處理共享數據時需要確保CPU和主存之間的數據一致性。這篇文章就來詳細

    2024年02月09日
    瀏覽(15)
  • Service Worker Cache 和 HTTP Cache 的對比

    在 Web 應用開發(fā)中,緩存機制對于提升用戶體驗和減少網絡請求具有重要的作用,其中包括傳統(tǒng)的 HTTP 緩存和 Service Worker 中的 Cache API。這兩種緩存機制各有優(yōu)勢,但是對于 Web 應用,Service Worker 的 Cache API 有著更為顯著的優(yōu)勢。 Service Worker 的 Cache API 提供了比 HTTP 緩存更加豐

    2024年01月17日
    瀏覽(12)
  • 幾個影響 cpu cache 性能因素及 cache 測試工具介紹

    幾個影響 cpu cache 性能因素及 cache 測試工具介紹

    1 cache 性能及影響因素 1.1 內存訪問和性能比較 有如下測試代碼: 該測試代碼預先分配大量內存,并與一個數組指針管理,使其可以通過數組索引訪問該片申請內存,接著對該內存域進行預讀寫,使其在測試中不受 pagefault 影響測試結果。 該測試主要的測試點: 第一個循環(huán)按

    2024年02月14日
    瀏覽(21)
  • 【ARM Cache 系列文章 2 -- Cache Coherence及內存順序模學習】

    請閱讀 【ARM Cache 系列文章專欄導讀】

    2024年02月16日
    瀏覽(22)
  • 如何使用Python內置緩存裝飾器: @lru_cache,@cache 與 @cached_property

    使用緩存是優(yōu)化Python程序速度的重要方法之一 。如果使用得當,可以大幅減少計算資源的負載,有效加快代碼運行速度 Python 的內置庫 functools 模塊附帶了 @lru_cache,@cache, @cached_property 裝飾器,使用非常簡便,不需要安裝第3方庫,不需要 redis 等數據庫保存對象等,通常只需要

    2024年02月11日
    瀏覽(24)
  • python裝飾器原理 | 常用裝飾器使用(@cache, @lru_cache)

    ?? 關于python的裝飾器原理介紹可看這里,講的挺簡潔易懂:python裝飾器原理 ? 弄懂裝飾器原理后,來學學常用裝飾器。 也就是一種裝飾在被執(zhí)行的函數上,將其執(zhí)行的結果緩存起來,當下次請求的時候,如果請求該函數的傳參未變則直接返回緩存起來的結果而不再執(zhí)行函

    2023年04月25日
    瀏覽(38)
  • 【計算機組成原理】高速緩沖存儲器 Cache 的三種映射方式(Cache Mapping)

    【計算機組成原理】高速緩沖存儲器 Cache 的三種映射方式(Cache Mapping)

    緩存是計算機系統(tǒng)中常見的一種高速存儲器,用于臨時存儲常用數據,以便快速訪問。在緩存中,有三種常見的映射方式,分別是直接映射、全相聯(lián)映射和組相聯(lián)映射。 在直接映射中,每個主存塊只能映射到緩存中的一個特定位置。該位置是通過對主存塊的某個地址的一部分

    2024年01月19日
    瀏覽(27)
  • 146. LRU Cache最近最少使用 (LRU) 緩存 Least Recently Used (LRU) cache.

    Design a data structure that follows the constraints of a Least Recently Used (LRU) cache. Implement the LRUCache class: LRUCache(int capacity) Initialize the LRU cache with positive size capacity. int get(int key) Return the value of the key if the key exists, otherwise return -1. void put(int key, int value) Update the value of the key if the key exists. O

    2024年02月10日
    瀏覽(34)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包