javascript
Springboot本地缓存和redis缓存
存儲(chǔ)簡(jiǎn)介:最開始使用的存儲(chǔ)結(jié)構(gòu)是文件形式(如:操作系統(tǒng)),但這時(shí)就存在一個(gè)問題,比如:查一個(gè)大的文件的時(shí)候,就是需要全量IO(在全部文件堆中找到你需要的文件),受磁盤尋址(毫秒)和帶寬的影響會(huì)很慢,所以應(yīng)運(yùn)而生是的數(shù)據(jù)庫(如mysql),數(shù)據(jù)庫通過索引和分治(一堆數(shù)據(jù)分成m塊-建表)降低了復(fù)雜度,但數(shù)據(jù)庫在數(shù)據(jù)量過大、高并發(fā)等場(chǎng)景出現(xiàn)時(shí)也會(huì)出現(xiàn)瓶頸,這時(shí)有兩種解決方案,一是換高并發(fā)處理、負(fù)載均衡和分布式數(shù)據(jù)庫(如:HANA-成本高),二是放緩存(納秒)里,還有一種折中的方法就是將數(shù)據(jù)庫做全量數(shù)據(jù),1/N的熱點(diǎn)數(shù)據(jù)放緩存,自此就產(chǎn)生了內(nèi)存型數(shù)據(jù)庫(如:redis、memcache),這樣緩存就是在內(nèi)存中存儲(chǔ)的數(shù)據(jù)備份,當(dāng)數(shù)據(jù)沒有發(fā)生本質(zhì)改變的時(shí)候,我們就不讓數(shù)據(jù)的查詢?nèi)?shù)據(jù)庫進(jìn)行操作,而去內(nèi)存中取數(shù)據(jù),來提高效率。
規(guī)范
提到緩存就不得不提到大名鼎鼎的JSR107
JSR是Java Specification Requests的縮寫,意思是Java 規(guī)范提案。
2012年10月26日J(rèn)SR規(guī)范委員會(huì)發(fā)布了JSR 107(JCache API)的首個(gè)早期草案。自該JSR啟動(dòng)以來,已經(jīng)過去近12年時(shí)間,因此該規(guī)范頗為Java社區(qū)所詬病,但由于對(duì)緩存需求越來越多,因此專家組加快了這一進(jìn)度。
JCache規(guī)范定義了一種對(duì)Java對(duì)象臨時(shí)在內(nèi)存中進(jìn)行緩存的方法,包括對(duì)象的創(chuàng)建、共享訪問、假脫機(jī)(spooling)、失效、各JVM的一致性等,可被用于緩存JSP內(nèi)最經(jīng)常讀取的數(shù)據(jù),如產(chǎn)品目錄和價(jià)格列表。利用JCACHE,多數(shù)查詢的反應(yīng)時(shí)間會(huì)因?yàn)橛芯彺娴臄?shù)據(jù)而加快(內(nèi)部測(cè)試表明反應(yīng)時(shí)間大約快15倍)。
JSR107
Java Caching定義了5個(gè)核心接口,分別是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
示意圖:
- CachingProvider定義了創(chuàng)建、配置、獲取、管理和控制多個(gè)CacheManager。一個(gè)應(yīng)用可 以在運(yùn)行期訪問多個(gè)CachingProvider。
- CacheManager定義了創(chuàng)建、配置、獲取、管理和控制多個(gè)唯一命名的Cache,這些Cache 存在于CacheManager的上下文中。一個(gè)CacheManager僅被一個(gè)CachingProvider所擁有。
- ?Cache是一個(gè)類似Map的數(shù)據(jù)結(jié)構(gòu)并臨時(shí)存儲(chǔ)以Key為索引的值。一個(gè)Cache僅被一個(gè) CacheManager所擁有。
- ?Entry是一個(gè)存儲(chǔ)在Cache中的key-value對(duì)。
- ?Expiry 每一個(gè)存儲(chǔ)在Cache中的條目有一個(gè)定義的有效期。一旦超過這個(gè)時(shí)間,條目為過期 的狀態(tài)。一旦過期,條目將不可訪問、更新和刪除。緩存有效期可以通過ExpiryPolicy設(shè)置。
2.Spring緩存抽象
Spring從3.1開始定義了org.springframework.cache.Cache 和org.springframework.cache.CacheManager接口來統(tǒng)一不同的緩存技術(shù); 并支持使用JCache(JSR-107)注解簡(jiǎn)化我們開發(fā)。
- Cache接口為緩存的組件規(guī)范定義,包含緩存的各種操作集合。
- Cache接口下Spring提供了各種xxxCache的實(shí)現(xiàn);如RedisCache,EhCacheCache , ConcurrentMapCache。
- 每次調(diào)用需要緩存功能的方法時(shí),Spring會(huì)檢查檢查指定參數(shù)的指定的目標(biāo)方法是否 已經(jīng)被調(diào)用過;如果有就直接從緩存中獲取方法調(diào)用后的結(jié)果,如果沒有就調(diào)用方法 并緩存結(jié)果后返回給用戶。下次調(diào)用直接從緩存中獲取。
- ?使用Spring緩存抽象時(shí)我們需要關(guān)注以下兩點(diǎn):
??????????? 1.、確定方法需要被緩存以及他們的緩存策略
??????????? 2、從緩存中讀取之前緩存存儲(chǔ)的數(shù)據(jù)
摘自鏈接:https://blog.csdn.net/huanghanqian/article/details/103129358
StackOverFlow上有一個(gè)問題https://stackoverflow.com/questions/37780249/spring-boot-cachable-cache-size,提問者使用了Spring Boot的@EnableCaching和@Cacheable注解,想自行設(shè)置cacheable緩存的默認(rèn)最大容量。
public interface VendorRepository extends Repository<Vendor, Long> {@Cacheable("vendorByUsername")Vendor getVendorByUsername(String username);@CacheEvict(value = {"vendorByUsername", "vendor", "vendors"}, allEntries = true)Vendor save(Vendor vendor);@Cacheable("vendor")Vendor findOne(Long id);@Cacheable("vendors")List<Vendor> findAll(); }其實(shí)這位提問者有一個(gè)誤解。Spring的Cacheable注解,不代表Cacheable就是一個(gè)具體的緩存實(shí)例。這個(gè)注解僅僅是一個(gè)抽象層,為緩存的各個(gè)實(shí)現(xiàn)規(guī)范定義。至于緩存的默認(rèn)大小、最大容量……這些都取決于你使用的具體緩存實(shí)現(xiàn)。
Spring的Cache抽象不會(huì)對(duì)cache中低層次的細(xì)節(jié)語義進(jìn)行處理(比如cache大小、cache驅(qū)除(eviction)、cache到期(expiration)等),因?yàn)檫@些低層次的信息在不同cache實(shí)現(xiàn)間差異很大。比如,不少緩存是分布式的,它們?cè)谝恢滦浴⑷哂嘈院涂刂蒲舆t的實(shí)現(xiàn)策略上具有很大的差別,因此,如果說cache接口也需要對(duì)一致性進(jìn)行抽象的話,就無法兼容那些非分布式緩存了。具體的話,可以看看《Spring Reference Guide》https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cache-specific-config?中對(duì)于這一部分的總結(jié):
8.7. How can I Set the TTL/TTI/Eviction(驅(qū)逐) policy/XXX feature?
直接通過你的cache provider來實(shí)現(xiàn)。The cache abstraction是一種抽象,而不是一種實(shí)現(xiàn)。你使用的解決方案可能會(huì)包含不同的數(shù)據(jù)策略和拓?fù)湟?guī)則,而其它解決方案可能會(huì)不支持這些特性。
Spring從3.1開始定義了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口來統(tǒng)一不同的緩存技術(shù);并支持使用JCache(JSR-107)注解簡(jiǎn)化我們開發(fā);
-
Cache接口為緩存的組件規(guī)范定義,包含緩存的各種操作集合;
-
Cache接口下Spring提供了各種xxxCache的實(shí)現(xiàn);如RedisCache,EhCacheCache ,ConcurrentMapCache等;
-
當(dāng)然你也可以使用其它組件提供的實(shí)現(xiàn),比如Guava和Caffeine(來自goole):
可以通過下圖觀測(cè)到,在下面緩存組件中 Caffeine 性能是其中最好的。
按 Caffeine Github 文檔描述,Caffeine 是基于 JAVA 8 的高性能緩存庫。并且在 spring5 (springboot 2.x) 后,spring 官方放棄了 Guava,而使用了性能更優(yōu)秀的 Caffeine 作為默認(rèn)緩存組件。具體為什么可以參考此文:https://blog.csdn.net/qq_33330687/article/details/88857030
-
每次調(diào)用需要緩存功能的方法時(shí),Spring會(huì)檢查檢查指定參數(shù)的指定的目標(biāo)方法是否已經(jīng)被調(diào)用過;如果有就直接從緩存中獲取方法調(diào)用后的結(jié)果,如果沒有就調(diào)用方法并緩存結(jié)果后返回給用戶。下次調(diào)用直接從緩存中獲取。
-
使用Spring緩存抽象時(shí)我們需要關(guān)注以下兩點(diǎn);
1、確定方法需要被緩存以及他們的緩存策略;
2、從緩存中讀取之前緩存存儲(chǔ)的數(shù)據(jù)
本地緩存
一、本地緩存方法一:springbootcache+Caffeine
本地緩存適合在單服務(wù)器上使用,不適合分布式,因?yàn)闆]有了網(wǎng)絡(luò)的時(shí)間消耗,表現(xiàn)上可能會(huì)更好
實(shí)現(xiàn)可以參考此鏈接:https://zhuanlan.zhihu.com/p/109226599
redis緩存(遠(yuǎn)程緩存)
又可以叫分布式緩存,講緩存單獨(dú)作為一個(gè)服務(wù)器,多有分布式服務(wù)器都去這臺(tái)服務(wù)器上進(jìn)行數(shù)據(jù)存取
實(shí)現(xiàn)可參照:https://blog.csdn.net/weixin_38750084/article/details/88526746
或者此文:https://www.jianshu.com/p/8b026187dc62
?
?
?
?
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Springboot本地缓存和redis缓存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Springboo零配置原理
- 下一篇: SpringBoot+Mybatis加载