偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Spring Boot 緩存優(yōu)化攻略:七個不可錯過的技巧

譯文 精選
開發(fā) 前端
緩存是提高應用性能的有效方法。我們之前發(fā)布過??一篇文章??,介紹了緩存的概念和好處,主要針對 Spring Boot 進行了討論。 在本文中,我們將探討優(yōu)化 Spring Boot 應用程序緩存的 7 種技術。

譯者 | 劉汪洋

審校 | 重樓

緩存是提高應用性能的有效方法。我們之前發(fā)布過一篇文章,介紹了緩存的概念和好處,主要針對 Spring Boot 進行了討論。 在本文中,我們將探討優(yōu)化 Spring Boot 應用程序緩存的 7 種技術。

目錄

1- 確定待緩存的對象

2- 緩存過期

淘汰策略

基于時間的過期策略

自定義淘汰策略

3- 條件緩存

4- 分布式緩存 vs 本地緩存

什么是本地緩存?

何時使用本地緩存 Vs. 分布式緩存?

在Spring Boot中實現(xiàn)本地緩存

5- 自定義鍵生成策略

6- 異步緩存

7- 監(jiān)控緩存指標以發(fā)現(xiàn)瓶頸

如何在Spring Boot中監(jiān)控緩存指標

總結

1.確定待緩存的對象

首先,我們需要明確哪些對象最適合緩存。一般而言,那些代價高昂且耗時的操作的結果需要優(yōu)先考慮,例如數(shù)據(jù)庫查詢、網(wǎng)絡服務調(diào)用或復雜計算的結果。然而,定義一些理想緩存候選對象的通用特征將更重要。這些特征有助于我們在應用程序中識別適合緩存的對象:

  • 頻繁訪問的數(shù)據(jù):經(jīng)常被訪問和重復訪問的數(shù)據(jù)是良好的緩存候選對象。
  • 代價高昂的獲取或計算:需要大量時間或計算資源來檢索或處理的數(shù)據(jù)。
  • 靜態(tài)或變化較少的數(shù)據(jù):變化不頻繁的數(shù)據(jù),確保緩存的數(shù)據(jù)在較長時間內(nèi)保持有效。
  • 高讀寫比率:當數(shù)據(jù)被訪問的頻率遠高于修改或更新的頻率時,可以有效地進行緩存。這保證了緩存快速讀取的優(yōu)勢超過其更新成本。
  • 可預測的訪問模式:遵循可預測訪問模式的數(shù)據(jù),允許更高效的緩存管理。

這些特征可以幫助我們有效地識別和緩存能夠顯著提升應用程序性能的數(shù)據(jù)。 既然我們知道如何找到理想的緩存候選對象,就可以開始在 Spring Boot 應用程序中啟用緩存??梢允褂米⒔饣蚓幊谭绞竭M行緩存配置。我在這篇文章中詳細討論了如何在 Spring Boot 中使用緩存,以及_ Digma_ 如何幫助我們發(fā)現(xiàn)緩存未命中或識別緩存候選對象。

2.緩存過期

緩存過期策略設置得當可以確保緩存數(shù)據(jù)的有效性和及時更新,提高內(nèi)存利用率,從而優(yōu)化 Spring Boot 應用程序的性能和一致性。以下是一些推薦的管理 Spring Boot 應用程序中緩存過期的方法:

淘汰策略

常見的淘汰策略包括:

  • 最近最少使用(LRU):優(yōu)先淘汰最近最少訪問的對象。
  • 最不經(jīng)常使用(LFU):優(yōu)先淘汰訪問頻率最低的對象。
  • 先進先出(FIFO):優(yōu)先淘汰最早放入緩存的對象。

雖然 Spring Cache 抽象本身不直接支持這些淘汰策略,但你可以根據(jù)所選的緩存提供者使用其特定配置。通過仔細選擇和配置合適的淘汰策略,可以確保緩存機制高效運行,并與應用程序的性能和資源利用目標相一致。

基于時間的過期策略

定義緩存條目的生存時間(TTL)在不同緩存提供者中有所不同。例如,在 Spring Boot 應用程序中使用 Redis 進行緩存時,可以通過以下配置指定生存時間:

spring.cache.redis.time-to-live=10m

如果緩存提供者不支持 TTL,可以使用@CacheEvict注解和調(diào)度器來實現(xiàn),例如:

@CacheEvict(value = "cache1", allEntries = true)
@Scheduled(fixedRateString = "${your.config.key.for.ttl.in.milli}")
public void emptyCache1() {
    // 刷新緩存,這里無需編寫任何代碼,除了描述性日志!
}

自定義淘汰策略

通過根據(jù)事件或情況為單個緩存條目或所有條目定義自定義過期策略,可以防止緩存污染并保持其一致性。Spring Boot 具有多種注解來支持自定義過期策略:

  • @CacheEvict:從緩存中刪除一個或所有條目。
  • @CachePut:用新值更新條目。
  • CacheManager:可以使用Spring的CacheManager和Cache接口實現(xiàn)自定義淘汰策略??梢允褂胑vict()、put()或clear()等方法進行操作,還可以通過getNativeCache()方法訪問底層緩存提供者,以獲得更多功能。

實施自定義淘汰策略的關鍵在于找到合適的時機和條件來淘汰緩存對象。

3.條件緩存

條件緩存與淘汰策略共同在優(yōu)化緩存策略中發(fā)揮重要作用。在某些情況下,我們不需要將所有特定實體的數(shù)據(jù)存儲在緩存中。

條件緩存確保只有符合特定條件的數(shù)據(jù)才會存儲在緩存中。

這可以防止緩存中存儲不必要的數(shù)據(jù),從而優(yōu)化資源利用。 @Cacheable和@CachePut注解都具有condition和unless屬性,允許我們?yōu)榫彺骓椂x條件:

  • condition:指定一個 SpEL(Spring表達式語言)表達式,該表達式必須評估為true,數(shù)據(jù)才會被緩存(或更新)。
  • unless:指定一個 SpEL 表達式,該表達式必須評估為false,數(shù)據(jù)才會被緩存(或更新)。

為了更清楚,請看以下代碼示例:

@Cacheable(value = "employeeByName", condition = "#result.size() > 10", unless = "#result.size() < 1000")
public List<Employee> employeesByName(String name) {
    // 檢索數(shù)據(jù)的方法邏輯
    return someEmployeeList;
}

在這段代碼中,只有當結果列表的大小大于 10 且小于 1000 時,員工列表才會被緩存。 最后一點,與前一部分類似,我們也可以使用CacheManager和Cache接口以編程方式實現(xiàn)條件緩存。這提供了更多的靈活性和對緩存行為的控制。

4.分布式緩存 vs. 本地緩存

談到緩存,我們通常會想到分布式緩存,如 Redis、Memcached 或 Hazelcast。在微服務架構盛行的時代,本地緩存也在提升應用性能方面發(fā)揮了重要作用。 理解本地緩存和分布式緩存之間的差異,有助于選擇合適的策略來優(yōu)化 Spring Boot 應用中的緩存。每種類型都有其優(yōu)缺點,根據(jù)應用需求進行權衡至關重要。

什么是本地緩存?

本地緩存是一種緩存機制,其中數(shù)據(jù)存儲在與應用運行的同一臺機器或實例的內(nèi)存中。一些知名的本地緩存庫包括 Ehcache、Caffeine 和 Guava Cache。 本地緩存允許快速訪問緩存數(shù)據(jù),因為它避免了與遠程數(shù)據(jù)檢索(分布式緩存)相關的網(wǎng)絡延遲和開銷。本地緩存通常比分布式緩存更易于設置和管理,并且不需要額外的基礎設施。

何時使用本地緩存 vs. 分布式緩存?

本地緩存適用于小型應用程序或數(shù)據(jù)集較小且可以舒適地放入單臺機器內(nèi)存中的微服務。它也適用于低延遲至關重要且實例間數(shù)據(jù)一致性不是主要問題的場景。本地緩存的優(yōu)勢在于其速度快、設置和管理簡單。 另一方面,分布式緩存系統(tǒng)適用于具有大量數(shù)據(jù)緩存需求的大規(guī)模應用,在這些應用中,可伸縮性、容錯性和多個實例間的數(shù)據(jù)一致性至關重要。分布式緩存能夠分擔數(shù)據(jù)存儲負擔,并在節(jié)點故障時提供數(shù)據(jù)冗余。

在 Spring Boot 中實現(xiàn)本地緩存

Spring Boot 支持通過各種內(nèi)存緩存提供程序(如 Ehcache、Caffeine 或 ConcurrentHashMap)實現(xiàn)本地緩存。我們只需添加所需的依賴項,并在 Spring Boot 應用程序中啟用緩存即可。例如,要使用 Caffeine 實現(xiàn)本地緩存,我們需要添加以下依賴項:

<dependency>
    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-cache</artifactId>

</dependency>

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>

    <artifactId>caffeine</artifactId>

</dependency>

然后使用 @EnableCaching 注解啟用緩存:

@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

除了通用的 Spring 緩存配置外,我們還可以使用特定的配置來調(diào)整 Caffeine 緩存,如下所示:

spring:
  cache:
    caffeine:
      spec: maximumSize=500,expireAfterAccess=10m

5. 自定義鍵生成策略

Spring 緩存注解中的默認鍵生成算法通常如下:

如果沒有參數(shù),則返回 0。 如果只有一個參數(shù),則返回該實例。 如果有多個參數(shù),則返回由所有參數(shù)的哈希值計算出的鍵。 只要 hashCode() 能準確反映對象的自然鍵,這種方法對具有自然鍵的對象效果良好。

但在某些情況下,默認的鍵生成策略效果并不好:

  • 我們需要有意義的鍵。
  • 方法有多個相同類型的參數(shù)。
  • 方法具有可選參數(shù)或空參數(shù)。
  • 我們需要在鍵中包含上下文數(shù)據(jù),如區(qū)域、租戶 ID 或用戶角色,以使其唯一。

Spring Cache 提供了兩種定義自定義鍵生成策略的方法:

  • 通過 key 屬性指定一個 SpEL(Spring 表達式語言)表達式,該表達式應計算出一個新的鍵:
@CachePut(value = "phonebook", key = "#phoneNumber.name")
PhoneNumber create(PhoneNumber phoneNumber) {
    return phonebookRepository.insert(phoneNumber);
}
  • 定義一個實現(xiàn) KeyGenerator 接口的 bean,并將其指定給 keyGenerator 屬性:
@Component("customKeyGenerator")
public class CustomKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object target, Method method, Object... params) {
        return "UNIQUE_KEY";
    }
}

@CachePut(value = "phonebook", keyGenerator = "customKeyGenerator")
PhoneNumber create(PhoneNumber phoneNumber) {
    return phonebookRepository.insert(phoneNumber);
}

使用自定義鍵生成策略可以顯著提升應用程序緩存的性能。設計良好的鍵生成策略能夠確保緩存條目的唯一性,最大限度地減少緩存丟失,并提高緩存命中率。

6. 異步緩存

如你所見,Spring 緩存抽象 API 是阻塞且同步的。如果你使用 WebFlux 棧,通過 Spring 緩存注解(如 @Cacheable 或 @CachePut)將緩存應用于 Reactor 包裝對象(Mono 或 Flux)。在這種情況下,你有三種方法:

  • 在 Reactor 類型上調(diào)用 cache() 方法,并在該方法上添加 Spring 緩存注解。
  • 使用底層緩存提供程序的異步 API(如果支持),并以編程方式處理緩存。
  • 實現(xiàn)一個圍繞緩存 API 的異步包裝器,使其支持異步操作(如果緩存提供程序不支持)。

然而,自Spring Framework 6.2 發(fā)布以來,如果緩存提供程序支持 WebFlux 項目的異步緩存(如 Caffeine Cache):

Spring 的聲明式緩存基礎設施會檢測到返回 Mono 或 Flux 的反應式方法,并異步緩存其產(chǎn)生的值,而不是緩存返回的 Reactive Streams Publisher 實例。這需要目標緩存提供程序的支持,例如將 CaffeineCacheManager 設置為 setAsyncCacheMode(true)。

配置示例如下:

@Configuration
@EnableCaching
public class CacheConfig {
  @Bean
  public CacheManager cacheManager() {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager();
    cacheManager.setCaffeine(buildCaffeineCache());
    cacheManager.setAsyncCacheMode(true); // <--
    return cacheManager;
  }
}

7. 監(jiān)控緩存指標以發(fā)現(xiàn)瓶頸

監(jiān)控緩存指標對于識別瓶頸和優(yōu)化應用程序中的緩存策略至關重要。 需要監(jiān)控的關鍵指標包括:

  • 緩存命中率:緩存命中次數(shù)與總請求次數(shù)的比率,表明緩存的有效性。低命中率表明緩存未被有效利用。
  • 緩存未命中率:緩存未命中次數(shù)與總請求次數(shù)的比率,表明緩存經(jīng)常無法提供請求的數(shù)據(jù),可能是由于緩存大小不足或鍵管理不當。
  • 緩存淘汰率:緩存中項目被淘汰的頻率。高淘汰率表明緩存大小過小或淘汰策略不適合當前的訪問模式。
  • 內(nèi)存使用量:緩存使用的內(nèi)存量。
  • 延遲:從緩存中檢索數(shù)據(jù)所需的時間。
  • 錯誤率:通常指的是系統(tǒng)在處理請求時遇到的錯誤數(shù)量或比例。錯誤率可以包括緩存無法響應請求、超時錯誤等。

如何在 Spring Boot 中監(jiān)控緩存指標

Spring Boot Actuator 啟動時會自動為所有可用的 Cache 實例配置 Micrometer。對于啟動后,動態(tài)創(chuàng)建或以編程方式創(chuàng)建的緩存,需要進行注冊。請查看相關文檔以確保您的緩存提供程序得到支持。 首先,添加 Actuator 和 Micrometer 依賴項:

<dependency>
    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

<dependency>
    <groupId>io.micrometer</groupId>

    <artifactId>micrometer-registry-prometheus</artifactId>

</dependency>

然后,啟用 Actuator 端點:

management.endpoints.web.exposure.include=*

現(xiàn)在,可以使用 /actuator/caches 端點查看配置的緩存列表。對于緩存指標,可以使用以下端點:

  • /actuator/metrics/cache.gets
  • /actuator/metrics/cache.puts
  • /actuator/metrics/cache.evictions
  • /actuator/metrics/cache.removals

總結

在本文中,我們詳細學習了 7 種優(yōu)化 Spring Boot 應用緩存的技術。優(yōu)化緩存至關重要,因為它通過減少后端系統(tǒng)的負載和加快數(shù)據(jù)檢索速度,直接提升了應用的性能和可擴展性。高效的緩存策略能夠最小化延遲,確保更快的響應時間,從而顯著改善整體用戶體驗。

譯者介紹

劉汪洋,51CTO社區(qū)編輯,昵稱:明明如月,一個擁有 5 年開發(fā)經(jīng)驗的某大廠高級 Java 工程師,擁有多個主流技術博客平臺博客專家稱號,博客閱讀量 400W+,粉絲 3W+。2022 年騰訊云優(yōu)秀創(chuàng)作者,2022 年阿里云技術社區(qū)最受歡迎技術電子書 TOP 10 《性能優(yōu)化方法論》作者,慕課網(wǎng):剖析《阿里巴巴 Java 開發(fā)手冊》、深度解讀《Effective Java》 技術專欄作者。

原文標題:Top 7 Techniques to Optimize Caching in Spring Boot,作者:Saeed Zarinfam

責任編輯:華軒 來源: 51CTO
相關推薦

2024-01-09 18:01:38

2022-01-19 11:48:21

安全開源工具

2021-01-25 15:42:53

開源安全 工具

2025-05-28 05:10:00

策略Spring性能

2025-01-07 08:21:03

2009-05-20 16:17:39

Linux硬盤技巧

2024-03-12 10:02:31

Python內(nèi)存編程

2019-07-23 09:00:00

vuejavascript前端

2023-03-19 16:02:33

JavaScrip技巧編程語言

2025-01-26 10:49:52

2023-09-07 16:28:46

JavaScrip

2021-11-22 12:13:54

Linuxwget 命令

2021-11-09 06:55:02

Windows 10系統(tǒng)技巧

2022-08-17 09:54:57

Java性能優(yōu)化

2023-05-30 09:59:38

2018-05-24 08:47:15

數(shù)據(jù)存儲技巧

2023-10-17 18:03:30

Code更改函數(shù)

2024-06-25 15:41:41

2022-04-14 10:40:11

領導者IT團隊遠程團隊

2021-08-17 10:08:44

HTML網(wǎng)站網(wǎng)絡
點贊
收藏

51CTO技術棧公眾號