日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在高性能服務架構設計中,緩存是不可或缺的環節。在實際項目中,我們通常會將一些熱點數據存儲在redis或Memcached等緩存中間件中,只有在緩存訪問未命中時才查詢數據庫。

在提高訪問速度的同時,還可以減輕數據庫的壓力。

為什么要使用本地緩存?

隨著不斷的發展,這個架構也得到了完善。在某些場景下,僅僅使用Redis類的遠程緩存可能還不夠。需要進一步與本地緩存配合使用,比如Guava或者Caffeine,從而再次提高程序的響應速度和服務性能。

由此,形成了以本地緩存作為一級緩存、遠程緩存作為二級緩存的二級緩存架構。

總結:

  1. 本地緩存基于本地環境的內存,訪問速度非常快。對于一些變化頻率不高、實時性要求不高的數據,可以放在本地緩存中,以提高訪問速度。
  2. 使用本地緩存可以減少與Redis類的遠程緩存的數據交互,減少網絡I/O開銷,減少這個過程中網絡通信的耗時。

本地存儲的基本功能

  • 它可以存儲、讀取和寫入。
  • 原子操作(線程安全),例如ConcurrentHashMap。
  • 可以設置緩存的最大限制。
  • 超過最大限制有相應的淘汰策略,如LRU、LFU。
  • 統計監控。

方案選擇

1.使用ConcurrentHashMap。

緩存的本質是KV存儲在內存中的數據結構,對應JDK中的線程安全ConcurrentHashMap,但是要實現緩存,需要考慮消除、最大限制、消除緩存過期時間等功能。

優點ConcurrentHashMap是實現簡單,不需要引入第三方包,所以比較適合一些簡單的業務場景。

缺點是如果需要更多的功能,需要定制開發,成本會比較高,穩定性和可靠性難以保證。

對于更復雜的場景,建議使用相對穩定的開源工具。

2. 使用Guava緩存

Guava是google團隊開源的一個JAVA核心增強庫。它包括集合、并發原語、緩存、IO、反射和其他工具箱。性能和穩定性有保證,應用廣泛。

  • Guava Cache 支持許多功能:
  • 支持最大容量限制。
  • 支持兩種過期刪除策略。
  • 支持簡單的統計功能。 它是基于LRU算法實現的。

示例代碼如下

 <dependency><dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
</dependency>
@Slf4j
public class GuavaCacheTest {
    public static void mAIn(String[] args) throws ExecutionException {
        Cache<String, String> cache = CacheBuilder.newBuilder()
                .initialCapacity(5)  // 初始容量
                .maximumSize(10)   // 緩存的最大數量,超過該數量將被淘汰
                .expireAfterWrite(60, TimeUnit.SECONDS) // 過期時間
                .build();

        String orderId = String.valueOf(123456789);
        String orderInfo = cache.get(orderId, () -> getInfo(orderId));
        log.info("orderInfo = {}", orderInfo);

    }

    private static String getInfo(String orderId) {
        String info = "";
        // 首先查redis
        log.info("get data from redis");
        // redis不存在 查db
        log.info("get data from MySQL");
        info = String.format("{orderId=%s}", orderId);
        return info;
    }
}

3. 使用Encache

Encache是?一個純Java進程內緩存框架,快速且精簡。它是 Hibernate 中默認的 CacheProvider。 與Caffeine和Guava Cache相比,Encache功能更豐富,可擴展性更強。 支持LRU、LFU、FIFO等多種緩存淘汰算法。

緩存支持三種類型:堆內存儲、堆外存儲、磁盤存儲(支持持久化)。

支持多種集群方案,解決數據共享問題。

使用方法如下:

 <dependency><dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.9.7</version>
</dependency>
@Slf4j
public class EhcacheTest {
    private static final String ORDER_CACHE = "orderCache";
    public static void main(String[] args) {
        CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                // 創建實例
                .withCache(ORDER_CACHE, CacheConfigurationBuilder
              // 聲明一個容量為20的堆內緩存
                        .newCacheConfigurationBuilder(String.class, String.class, ResourcePoolsBuilder.heap(20)))
                .build(true);
        // 得到緩存實例
        Cache<String, String> cache = cacheManager.getCache(ORDER_CACHE, String.class, String.class);

        String orderId = String.valueOf(123456789);
        String orderInfo = cache.get(orderId);
        if (StrUtil.isBlank(orderInfo)) {
            orderInfo = getInfo(orderId);
            cache.put(orderId, orderInfo);
        }
        log.info("orderInfo = {}", orderInfo);
    }

    private static String getInfo(String orderId) {
        String info = "";
        // 首先從redis查
        log.info("get data from redis");
        // 不存在 查db
        log.info("get data from mysql");
        info = String.format("{orderId=%s}", orderId);
        return info;
    }
}

本地緩存常見問題

1. 緩存一致性。

二級緩存和數據庫中的數據必須一致。一旦數據被修改,本地緩存和遠程緩存應在數據庫修改的同時同步更新。

解決方案1:使用MQ。

目前的部署一般都是集群部署,不同節點有多個本地緩存。 可以利用MQ的廣播模式,在數據修改時向MQ發送消息,由節點監聽并消費該消息,刪除本地緩存,達到最終一致性。
 

解決方案二:Canal+MQ。

如果你的業務代碼中不想發送MQ消息,也可以應用近年來比較流行的方法:訂閱數據庫變更日志,然后操作緩存。 Canal訂閱Mysql的Binlog日志,當發生變化時向MQ發送消息,從而也實現了數據的一致性。

2.如何提高緩存命中率?

  • 根據業務場景設計合理的時效性。

緩存適用于讀多寫少的場景,盡可能關注訪問頻率高、時效性要求不高的熱點業務。 訪問頻率越高,點擊率越高。 時效性越低,緩存時間越長,相同key、相同請求數下命中率越高。

  • 設計合理的緩存粒度。

緩存的粒度越小,緩存命中率越高。 單個key緩存的數據單元越小,被改變的可能性就越小。

  • 設計合理的緩存過期策略。

這里的緩存過期策略并不是redis內置的定期刪除和惰性刪除策略,而是根據業務場景優化了key的過期時間。 例如,如果用戶的關鍵信息同時過期,那么當多個用戶同時查詢時,都會落入數據庫,也就是說避免緩存同時失效。

  • 合理的緩存預加載。

redis緩存必須從數據庫加載,所以當第一次使用數據時,redis需要從數據庫加載數據。 我們可以在用戶訪問之前將需要的數據提前加載到緩存中,這樣用戶第一次訪問時就可以直接去緩存而不用去查詢數據庫。

  • 防止緩存崩潰和擊穿。

緩存擊穿和崩潰也會影響緩存命中率。當然,如果發生的話,應用失敗的可能性很大。

  • 設計合理的緩存容量。

注意緩存容量,如果太小,會觸發redis內存淘汰機制。線上redis一般配置maxmemory-policy allkeys-lru算法進行內存消除。

這樣就會刪除一些key,造成緩存穿透,從而降低緩存命中率,所以需要合理配置緩存容量。

分享到:
標簽:java
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定