最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實現(xiàn)本地緩存的示例代碼

 更新時間:2024年01月08日 14:59:04   作者:代碼小人物  
在高性能服務(wù)架構(gòu)設(shè)計中,緩存是不可或缺的環(huán)節(jié),因此這篇文章主要為大家詳細(xì)介紹了java中如何實現(xiàn)本地緩存,感興趣的小伙伴可以了解一下

在高性能服務(wù)架構(gòu)設(shè)計中,緩存是不可或缺的環(huán)節(jié)。在實際項目中,我們通常會將一些熱點數(shù)據(jù)存儲在Redis或Memcached等緩存中間件中,只有在緩存訪問未命中時才查詢數(shù)據(jù)庫。

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

為什么要使用本地緩存

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

由此,形成了以本地緩存作為一級緩存、遠(yuǎn)程緩存作為二級緩存的二級緩存架構(gòu)。

總結(jié):

  • 本地緩存基于本地環(huán)境的內(nèi)存,訪問速度非??臁τ谝恍┳兓l率不高、實時性要求不高的數(shù)據(jù),可以放在本地緩存中,以提高訪問速度。
  • 使用本地緩存可以減少與Redis類的遠(yuǎn)程緩存的數(shù)據(jù)交互,減少網(wǎng)絡(luò)I/O開銷,減少這個過程中網(wǎng)絡(luò)通信的耗時。

本地存儲的基本功能

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

方案選擇

1.使用ConcurrentHashMap

緩存的本質(zhì)是KV存儲在內(nèi)存中的數(shù)據(jù)結(jié)構(gòu),對應(yīng)JDK中的線程安全ConcurrentHashMap,但是要實現(xiàn)緩存,需要考慮消除、最大限制、消除緩存過期時間等功能。

優(yōu)點ConcurrentHashMap是實現(xiàn)簡單,不需要引入第三方包,所以比較適合一些簡單的業(yè)務(wù)場景。

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

對于更復(fù)雜的場景,建議使用相對穩(wěn)定的開源工具。

2. 使用Guava緩存

Guava是Google團隊開源的一個Java核心增強庫。它包括集合、并發(fā)原語、緩存、IO、反射和其他工具箱。性能和穩(wěn)定性有保證,應(yīng)用廣泛。

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

示例代碼如下

 <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)   // 緩存的最大數(shù)量,超過該數(shù)量將被淘汰
                .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進程內(nèi)緩存框架,快速且精簡。它是 Hibernate 中默認(rèn)的 CacheProvider。 與Caffeine和Guava Cache相比,Encache功能更豐富,可擴展性更強。 支持LRU、LFU、FIFO等多種緩存淘汰算法。

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

支持多種集群方案,解決數(shù)據(jù)共享問題。

使用方法如下:

 <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()
                // 創(chuàng)建實例
                .withCache(ORDER_CACHE, CacheConfigurationBuilder
              // 聲明一個容量為20的堆內(nèi)緩存
                        .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;
    }
}

本地緩存常見問題

緩存一致性

二級緩存和數(shù)據(jù)庫中的數(shù)據(jù)必須一致。一旦數(shù)據(jù)被修改,本地緩存和遠(yuǎn)程緩存應(yīng)在數(shù)據(jù)庫修改的同時同步更新。

解決方案1:使用MQ。

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

解決方案二:Canal+MQ。

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

如何提高緩存命中率

根據(jù)業(yè)務(wù)場景設(shè)計合理的時效性。

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

設(shè)計合理的緩存粒度。

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

設(shè)計合理的緩存過期策略。

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

合理的緩存預(yù)加載。

redis緩存必須從數(shù)據(jù)庫加載,所以當(dāng)?shù)谝淮问褂脭?shù)據(jù)時,redis需要從數(shù)據(jù)庫加載數(shù)據(jù)。 我們可以在用戶訪問之前將需要的數(shù)據(jù)提前加載到緩存中,這樣用戶第一次訪問時就可以直接去緩存而不用去查詢數(shù)據(jù)庫。

防止緩存崩潰和擊穿。

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

設(shè)計合理的緩存容量。

注意緩存容量,如果太小,會觸發(fā)redis內(nèi)存淘汰機制。線上redis一般配置maxmemory-policy allkeys-lru算法進行內(nèi)存消除。這樣就會刪除一些key,造成緩存穿透,從而降低緩存命中率,所以需要合理配置緩存容量。

到此這篇關(guān)于java實現(xiàn)本地緩存的示例代碼的文章就介紹到這了,更多相關(guān)java本地緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringSecurity中的Filter Chain(過濾器鏈)

    SpringSecurity中的Filter Chain(過濾器鏈)

    Spring Security的Filter Chain是由一系列過濾器組成的管道,每個過濾器執(zhí)行特定的安全功能,Spring Security能夠提供強大而靈活的安全控制機制,從而保護你的應(yīng)用程序不受各種網(wǎng)絡(luò)安全威脅的侵害,本文介紹SpringSecurity中的Filter Chain,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Java中的Semaphore源碼分析

    Java中的Semaphore源碼分析

    這篇文章主要介紹了Java中的Semaphore源碼分析,Semaphore是一個訪問公共資源的線程數(shù)量如限流、停車等,它是一個基于AQS實現(xiàn)的共享鎖,主要是通過控制state變量來實現(xiàn),需要的朋友可以參考下
    2023-11-11
  • Spring Data JPA實現(xiàn)數(shù)據(jù)訪問層簡化高效開發(fā)

    Spring Data JPA實現(xiàn)數(shù)據(jù)訪問層簡化高效開發(fā)

    這篇文章主要介紹了Spring Data JPA實現(xiàn)數(shù)據(jù)訪問層簡化高效開發(fā),數(shù)據(jù)訪問層的開發(fā)是一個重要且繁瑣的部分,傳統(tǒng)的JDBC操作需要編寫大量的重復(fù)代碼,包括數(shù)據(jù)庫連接的建立、SQL語句的執(zhí)行、結(jié)果集的處理等,需要的朋友可以參考下
    2025-05-05
  • 解決啟用 Spring-Cloud-OpenFeign 配置可刷新項目無法啟動的問題

    解決啟用 Spring-Cloud-OpenFeign 配置可刷新項目無法啟動的問題

    這篇文章主要介紹了解決啟用 Spring-Cloud-OpenFeign 配置可刷新項目無法啟動的問題,本文重點給大家介紹Spring-Cloud-OpenFeign的原理及問題解決方法,需要的朋友可以參考下
    2021-10-10
  • Java中JSON數(shù)據(jù)操作與處理全面指南

    Java中JSON數(shù)據(jù)操作與處理全面指南

    JSON(JavaScript Object Notation)是數(shù)據(jù)交換的輕量級格式,它以易于人類閱讀和機器解析的方式組織數(shù)據(jù),基于鍵值對,在Java開發(fā)中,處理JSON數(shù)據(jù)通常涉及使用Jackson、Gson、Fastjson等庫,本文給大家介紹JSON數(shù)據(jù)操作與處理全面指南,感興趣的朋友一起看看吧
    2024-10-10
  • 都9102年了,你還用for循環(huán)操作集合嗎

    都9102年了,你還用for循環(huán)操作集合嗎

    這篇文章主要給大家介紹了關(guān)于java中for循環(huán)操作集合使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java接口和抽象類原理詳解

    Java接口和抽象類原理詳解

    這篇文章主要介紹了Java接口和抽象類原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • 淺談JAVA字符串匹配算法indexOf函數(shù)的實現(xiàn)方法

    淺談JAVA字符串匹配算法indexOf函數(shù)的實現(xiàn)方法

    這篇文章主要介紹了淺談字符串匹配算法indexOf函數(shù)的實現(xiàn)方法,indexOf函數(shù)我們可以查找一個字符串(模式串)是否在另一個字符串(主串)出現(xiàn)過。對此感興趣的可以來了解一下
    2020-07-07
  • 若依前后端打成一個JAR包部署的完整步驟

    若依前后端打成一個JAR包部署的完整步驟

    這篇文章主要介紹了如何將若依前后端分離項目打包成jar,不使用nginx轉(zhuǎn)發(fā),前端修改了路由模式和環(huán)境變量配置,后端增加了依賴、配置了Thymeleaf和訪問路徑,需要的朋友可以參考下
    2025-01-01
  • 解決java.sql.SQLException:索引中丟失 IN或OUT 參數(shù)::x問題

    解決java.sql.SQLException:索引中丟失 IN或OUT 參數(shù)::x問題

    這篇文章主要介紹了解決java.sql.SQLException:索引中丟失 IN或OUT 參數(shù)::x問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評論

志丹县| 巴塘县| 永年县| 九江县| 彝良县| 留坝县| 石狮市| 中卫市| 乐安县| 克山县| 开封市| 甘泉县| 广丰县| 民丰县| 白玉县| 肃南| 丰镇市| 武清区| 博爱县| 平江县| 京山县| 东海县| 古田县| 鹿泉市| 绍兴市| 阿坝县| 扬州市| 汉寿县| 建水县| 资溪县| 大城县| 建始县| 海兴县| 潼关县| 新巴尔虎右旗| 辽中县| 柳河县| 柏乡县| 开化县| 石景山区| 股票|