日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java常用缓存

發(fā)布時間:2023/12/10 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java常用缓存 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

memcache:

是一種高性能、分布式對象緩存系統(tǒng),最初設(shè)計于緩解動態(tài)網(wǎng)站數(shù)據(jù)庫加載數(shù)據(jù)的延遲性,你可以把它想象成一個大的內(nèi)存HashTable,就是一個key-value鍵值緩存。C語言所編寫,依賴于最近版本的GCC和libevent。GCC是它的編譯器,同時基于libevent做socket io。在安裝memcache時保證你的系統(tǒng)同時具備有這兩個環(huán)境。支持多個cpu同時工作,在memcache安裝文件下有個叫threads.txt中特別說明,By default, memcached is compiled as a single-threaded application.默認(rèn)是單線程編譯安裝,如果你需要多線程則需要修改./configure --enable-threads,為了支持多核系統(tǒng),前提是你的系統(tǒng)必須具有多線程工作模式。開啟多線程工作的線程數(shù)默認(rèn)是4,如果線程數(shù)超過cpu數(shù)容易發(fā)生操作死鎖的概率。結(jié)合自己業(yè)務(wù)模式選擇才能做到物盡其用。

本身沒有內(nèi)置分布式功能,只能在客戶端通過像一致性哈希這樣的分布式算法來實現(xiàn)Memcached的分布式存儲【當(dāng)客戶端向Memcached集群發(fā)送數(shù)據(jù)之前,首先會通過內(nèi)置的分布式算法計算出該條數(shù)據(jù)的目標(biāo)節(jié)點,然后數(shù)據(jù)會直接發(fā)送到該節(jié)點上存儲。但客戶端查詢數(shù)據(jù)時,同樣要計算出查詢數(shù)據(jù)所在的節(jié)點,然后直接向該節(jié)點發(fā)送查詢請求以獲取數(shù)據(jù)】。無法實現(xiàn)使用多臺Memcache服務(wù)器來存儲不同的數(shù)據(jù),最大程度的使用相同的資源;無法同步數(shù)據(jù),容易造成單點故障。

memagent代理實現(xiàn)集群)通過Magent緩存代理,防止單點現(xiàn)象,緩存代理也可以做備份,通過客戶端連接到緩存代理服務(wù)器,緩存代理服務(wù)器連接緩存連接服務(wù)器,緩存代理服務(wù)器可以連接多臺Memcached機(jī)器可以將每臺Memcached機(jī)器進(jìn)行數(shù)據(jù)同步。如果其中一臺緩存服務(wù)器down機(jī),系統(tǒng)依然可以繼續(xù)工作,如果其中一臺Memcached機(jī)器down掉,數(shù)據(jù)不會丟失并且可以保證數(shù)據(jù)的完整性。

Redis:

支持持久化【數(shù)據(jù)swap時會阻塞,設(shè)置I/O線程池的大小】;豐富的數(shù)據(jù)類型結(jié)構(gòu)存儲;單線程網(wǎng)絡(luò)IO;數(shù)據(jù)存儲即時申請內(nèi)存【不會預(yù)分配內(nèi)存池,不會自動剔除數(shù)據(jù)】;提供事務(wù)操作;消息隊列【不支持持久化,消費方連接閃斷或重連,之間過來的消息會全部丟失】;集群方式【沒有中心節(jié)點,具有線性可伸縮的功能】

Redis cluster配置參考:

在每臺服務(wù)器上執(zhí)行如下操作:

#cd /opt/redis-3.0.2【必須先安裝gcc、make】

#make

#make install【將生成的可執(zhí)行程序復(fù)制到/usr/local/bin目錄中】

#vim redis.conf

port?6379

bind ip【本機(jī)ip,其他節(jié)點可以訪問】

daemonize?yes【可保留】

cluster-enabled?yes

cluster-config-file?nodes-6379.conf

cluster-node-timeout?15000

appendonly?yes【可保留】

#cp redis.conf redis1.conf

#vim redis1.conf【修改port: 6380, cluster-config-file nodes-6380.conf】

#redis-server redis.conf &

#redis-server redis1.conf &

#redis-cli -h 10.30.17.15 -p 6379【測試】

安裝ruby 及 rubygems

#apt-get install ruby rubygems

安裝ruby 的redis 接口支持包

#gem install redis

建立集群

#/opt/redis-3.0.2/src/redis-trib.rb create --replicas 1 10.30.17.85:6379 10.30.17.85:6380 10.30.17.94:6379 10.30.17.94:6380 10.30.17.15:6379 10.30.17.15:6380

測試

#redis-cli -p 6379【exit退出】

>cluster info

>set hello tang

>keys *

>set user_id 1234

>get user_id

在另一臺機(jī)器上執(zhí)行#redis-cli -p 6380

>keys *

>set user_id 1234【error,需#redis-cli -c -p 6380】

在另一臺機(jī)器上執(zhí)行#redis-cli -p 6379

>keys *【empty】

>set user_id 1234【error,需#redis-cli -c -p 6379】

Ehcache【java進(jìn)程中的緩存系統(tǒng)】:

ehcache直接在jvm虛擬機(jī)中緩存,速度快,效率高;但是緩存共享麻煩,集群分布式應(yīng)用不方便。redis是通過socket訪問到緩存服務(wù),效率比ecache低,比數(shù)據(jù)庫要快很多,處理集群和分布式緩存方便,有成熟的方案。如果是單個應(yīng)用或者對緩存訪問要求很高的應(yīng)用,用ehcache。如果是大型系統(tǒng),存在緩存共享、分布式部署、緩存內(nèi)容很大的,建議用redis

補(bǔ)刀:ehcache也有緩存共享方案,不過是通過RMI或者Jgroup多播方式進(jìn)行廣播緩存通知更新,緩存共享復(fù)雜,維護(hù)不方便;簡單的共享可以,但是涉及到緩存恢復(fù),大數(shù)據(jù)緩存,則不合適。

一旦將應(yīng)用部署在集群環(huán)境中,每一個節(jié)點維護(hù)各自的緩存數(shù)據(jù),當(dāng)某個節(jié)點對緩存數(shù)據(jù)進(jìn)行更新,這些更新的數(shù)據(jù)無法在其它節(jié)點中共享,這不僅會降低節(jié)點運行的效率,而且會導(dǎo)致數(shù)據(jù)不同步的情況發(fā)生,所以就需要用到 EhCache 的集群解決方案。EhCache 從 1.7 版本開始,支持五種集群方案,分別是:

  • Terracotta
  • RMI
  • JMS
  • JGroups
  • EhCache Server【它以兩種形式出現(xiàn):適合大多數(shù)Web容器的WAR以及獨立的服務(wù)器。Cache Server有兩種類型的API:面向資源的RESTful以及SOAP。這兩種API都支持任何編程語言。最大的Ehcache單實例在內(nèi)存中可以緩存20GB。最大的磁盤可以緩存100GB。】
  • Ehcache可以對頁面、對象、數(shù)據(jù)進(jìn)行緩存

    ehcache-core-2.5.2.jar 主要針對對象、數(shù)據(jù)緩存

    ehcache-web-2.0.4.jar 主要針對頁面緩存

    頁面緩存主要用Filter過濾器對請求的url進(jìn)行過濾,如果該url在緩存中出現(xiàn)。那么頁面數(shù)據(jù)就從緩存對象中獲取,并以gzip壓縮后返回。其速度是沒有壓縮緩存時速度的3-5倍,效率相當(dāng)之高!其中頁面緩存的過濾器有CachingFilter,一般要擴(kuò)展filter或是自定義Filter都繼承該CachingFilter。CachingFilter功能可以對HTTP響應(yīng)的內(nèi)容進(jìn)行緩存。這種方式緩存數(shù)據(jù)的粒度比較粗,例如緩存整張頁面。它的優(yōu)點是使用簡單、效率高,缺點是不夠靈活,可重用程度不高。EHCache使用SimplePageCachingFilter類實現(xiàn)Filter緩存。該類繼承自CachingFilter,有默認(rèn)產(chǎn)生cache key的calculateKey()方法,該方法使用HTTP請求的URI和查詢條件來組成key。也可以自己實現(xiàn)一個Filter,同樣繼承CachingFilter類,然后覆寫calculateKey()方法,生成自定義的key。CachingFilter輸出的數(shù)據(jù)會根據(jù)瀏覽器發(fā)送的Accept-Encoding頭信息進(jìn)行Gzip壓縮。

    在使用Gzip壓縮時,需注意兩個問題:

    1. Filter在進(jìn)行Gzip壓縮時,采用系統(tǒng)默認(rèn)編碼,對于使用GBK編碼的中文網(wǎng)頁來說,需要將操作系統(tǒng)的語言設(shè)置為:zh_CN.GBK,否則會出現(xiàn)亂碼的問題。

    2. 默認(rèn)情況下CachingFilter會根據(jù)瀏覽器發(fā)送的請求頭部所包含的Accept-Encoding參數(shù)值來判斷是否進(jìn)行Gzip壓縮。雖然IE6/7瀏覽器是支持Gzip壓縮的,但是在發(fā)送請求的時候卻不帶該參數(shù)。為了對IE6/7也能進(jìn)行Gzip壓縮,可以通過繼承CachingFilter,實現(xiàn)自己的Filter,然后在具體的實現(xiàn)中覆寫方法acceptsGzipEncoding。

    具體實現(xiàn)參考:

    protected boolean acceptsGzipEncoding(HttpServletRequest request) {

    boolean ie6 = headerContains(request, "User-Agent", "MSIE 6.0");

    boolean ie7 = headerContains(request, "User-Agent", "MSIE 7.0");

    return acceptsEncoding(request, "gzip") || ie6 || ie7;

    }

    對象緩存就是將查詢的數(shù)據(jù),添加到緩存中,下次再次查詢的時候直接從緩存中獲取,而不去數(shù)據(jù)庫中查詢。對象緩存一般是針對方法、類而來的,結(jié)合Spring的Aop對象、方法緩存就很簡單。這里需要用到切面編程,用到了Spring的MethodInterceptor或是用@Aspect。這里的方法攔截器主要是對你要攔截的類的方法進(jìn)行攔截,然后判斷該方法的類路徑+方法名稱+參數(shù)值組合的cache key在緩存cache中是否存在。如果存在就從緩存中取出該對象,轉(zhuǎn)換成我們要的返回類型。沒有的話就把該方法返回的對象添加到緩存中即可。值得主意的是當(dāng)前方法的參數(shù)和返回值的對象類型需要序列化。我們需要在src目錄下添加applicationContext.xml完成對MethodCacheInterceptor攔截器的配置,該配置主意是注入我們的cache對象,哪個cache來管理對象緩存,然后哪些類、方法參與該攔截器的掃描。

    Spring自身并沒有實現(xiàn)緩存解決方案,但是對緩存管理功能提供了聲明式的支持,能夠與多種流行的緩存實現(xiàn)進(jìn)行集成。

    Spring Cache是作用在方法上的(不能理解為只注解在方法上),其核心思想是:當(dāng)我們在調(diào)用一個緩存方法時會把該方法參數(shù)和返回結(jié)果作為一個鍵值存放在緩存中,等到下次利用同樣的參數(shù)調(diào)用該方法時將不再執(zhí)行該方法,而是直接從緩存中獲取結(jié)果進(jìn)行返回。所以在使用Spring Cache的時候我們要保證我們的緩存的方法對于相同的方法參數(shù)要有相同的返回結(jié)果。

    SpringCache的支持有兩種方式

    基于注解驅(qū)動的緩存

    基于XML配置聲明的緩存

    啟用Spring對注解驅(qū)動緩存的支持,也是有兩種方式的

    Java配置(這個方法可以比較清晰的了解緩存管理器是如何聲明的)

    XML配置(這個方法比較方便簡單,這里的XML配置不能跟上面的“基于XML配置聲明的緩存”搞混,兩者不是同一層概念)

    這兩種方式,Java配置方式是通過使用@EnableCaching啟用注解驅(qū)動的緩存,XML配置方式是通過使用<cache:annotation-driven/>啟用注解驅(qū)動的緩存。本質(zhì)上來講,這兩種工作方式是相同的,它們都會創(chuàng)建一個切面(AOP)并出發(fā)Spring緩存注解的切點(pointcut)。

    在這兩個程序清單中,不僅僅啟用了注解驅(qū)動的緩存,還聲明了一個緩存管理器(cache manager)的bean。緩存管理器是Spring抽象的核心,它能夠與多個流行的緩存實現(xiàn)進(jìn)行集成。

    數(shù)據(jù)緩存是在hibernate或mybatis中加入ehcache

    配置ehcache.xml:

    maxElementsInMemory:緩存中允許創(chuàng)建的最大對象數(shù)

    eternal:緩存中對象是否為永久的,如果是,超時設(shè)置將被忽略,對象從不過期。

    timeToIdleSeconds:緩存數(shù)據(jù)的鈍化時間,也就是在一個元素消亡之前,兩次訪問時間的最大時間間隔值,這只能在元素不是永久駐留時有效,如果該值是 0 就意味著元素可以停頓無窮長的時間。

    timeToLiveSeconds:緩存數(shù)據(jù)的生存時間,也就是一個元素從構(gòu)建到消亡的最大時間間隔值,這只能在元素不是永久駐留時有效,如果該值是0就意味著元素可以停頓無窮長的時間。

    overflowToDisk:內(nèi)存不足時,是否啟用磁盤緩存。

    memoryStoreEvictionPolicy:緩存滿了之后的淘汰算法。

    配置applicationContext.xml:

    ...

    <!--? 緩存? 屬性-->?

    <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">???

    ???????? <property name="configLocation"? value="classpath:com/config/ehcache.xml"/>??

    </bean>??????

    <!-- 默認(rèn)是cacheManager -->?

    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">???

    ???????? <property name="cacheManager"? ref="cacheManagerFactory"/>???

    </bean>

    <!-- 支持緩存注解 -->?

    <cache:annotation-driven cache-manager="cacheManager" />

    實現(xiàn)(常在@Service服務(wù)文件,緩存數(shù)據(jù)):

    @Cacheable(value = "serviceCache", key="#id")【當(dāng)調(diào)用其方法時,會從一個名叫 serviceCache 的緩存中查詢,如果沒有,則執(zhí)行實際的方法(即查詢數(shù)據(jù)庫),并將執(zhí)行的結(jié)果存入緩存中,否則返回緩存中的對象。serviceCache為ehcache.xml中定義的緩存名稱】

    @CacheEvict(value="serviceCache",allEntries=true)【標(biāo)記要清空緩存的方法,allEntries 表示調(diào)用之后,清空緩存,默認(rèn)false, 還有個beforeInvocation 屬性,表示先清空緩存,再進(jìn)行查詢】

    Google Guava

    Google Guava工具包是一個非常方便易用的本地化緩存實現(xiàn),基于LRU算法實現(xiàn),支持多種緩存過期策略。Guava在每次訪問緩存的時候判斷cache數(shù)據(jù)是否過期,如果過期,這時才將其刪除,并沒有另起一個線程專門來刪除過期數(shù)據(jù)。內(nèi)部維護(hù)了2個隊列accessQueue和writeQueue來記錄緩存中數(shù)據(jù)訪問和寫入的順序。訪問緩存時,先用key計算出hash,從而找出所在的segment,然后再在segment中尋找具體數(shù)據(jù),類似于使用ConcurrentHashMap數(shù)據(jù)結(jié)構(gòu)來存放緩存數(shù)據(jù)。

    Caffeine

    Caffeine是基于Java8,對Guava緩存的重寫版本,在Spring Boot 2.0中將取代Guava,基于LRU算法實現(xiàn),支持多種緩存過期策略。Caffeine使用Disruptor框架的RingBuffer數(shù)據(jù)結(jié)構(gòu)記錄,RingBuffer是一個環(huán)形隊列,并且是無鎖的,利用的是緩存行的特性。Caffeine讀比寫的性能比Guava和EhCache要高很多。

    總結(jié)

    以上是生活随笔為你收集整理的Java常用缓存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。