?
?
?
?
?
? Sapphire Cache Framework API
??? Sapphire是一個(gè)高并發(fā)、高緩存吞吐性、高性能的Java分布式內(nèi)存對(duì)象緩存系統(tǒng),其具有簡(jiǎn)單易學(xué)、方便實(shí)用等特點(diǎn)。它能夠用來存儲(chǔ)各種格式的數(shù)據(jù),包括圖像、視頻、文件以及數(shù)據(jù)庫檢索的結(jié)果等。簡(jiǎn)單的說就是將數(shù)據(jù)源中的數(shù)據(jù)臨時(shí)存儲(chǔ)于內(nèi)存中,然后從內(nèi)存中讀取,從而大大提高讀取速度。
?
Sapphire目前最新版本為1.1.7-beta,主要特性包含:
1.敏捷快速;
2.體系結(jié)構(gòu)中立、跨平臺(tái)支持;?
3.多種緩存管理容器實(shí)現(xiàn);
4.多種緩存策略(LRU、LFU、FIFO、RDM);
5.支持緩存注解服務(wù)驅(qū)動(dòng)(Annotation方式直接緩存方法);
6.支持緩存持久化及加載虛擬機(jī)運(yùn)行期數(shù)據(jù);
7.單個(gè)緩存最大緩存容量為1gByte;
8.支持緩存容量單位設(shè)置(byte、kByte、mByte、gByte)
9.支持TCP單播集群、P2P廣播、組播集群、RMI組播集群;?
?
org.sapphire.cache:sapphire基礎(chǔ)包;
org.sapphire.cache.annotation:sapphire注解服務(wù)包;
org.sapphire.cache.bean.config:sapphire配置DTO包;
org.sapphire.cache.cleanup:sapphire緩存回收包;
org.sapphire.cache.exception:sapphire異常包;
org.sapphire.cache.log:sapphire:日志記錄包;
org.sapphire.cache.distributed.tcp:基于tcp分布式緩存包;
org.sapphire.cache.distributed.rmi:基于rmi分布式緩存包;
org.sapphire.cache.distributed.p2p:基于p2p分布式緩存包;
2.Sapphire Framework類型結(jié)構(gòu):
基于org.sapphire.cache包:
-- Cache
-- CacheManager
??? -- CacheManagerImpl
?????? ?-- SapphireCacheManager
????? ? -- CacheManagerForSafety
-- Element
-- CacheSerializable
-- AnalyticSapphireXml
-- LoadOverflowDate
-- OverflowDate
-- PersistenceCacheManager
基于org.sapphire.cache.annotation包:
-- CacheService
測(cè)試中未發(fā)布…
基于org.sapphire.cache.bean.config包:
-- CacheAnnotationBean
-- CacheBean
-- CacheDataBuringBean
-- DiskStoreBean
-- DistributedCacheBean
-- TcpUnicastBean
基于org.sapphire.cache.cleanup包:
-- CacheCleanupPolicy
??? -- CacheCleanupPolicyImpl
??????? -- CacheForLFU
??????? -- CacheForLRU
??????? -- CacheForRDM
基于org.sapphire.cache.exception包:
-- CacheException
??? -- CacheFileNotFoundException
??? -- CacheServiceException
??? -- CacheElementsException
??? -- CacheDistributedException
??????? -- TcpCacheDistributedException
-- CacheRangeError
-- OutOfCacheError
基于org.sapphire.cache.log包:
-- CacheLog
??? -- CacheLogImpl
基于org.sapphire.cache.distributed.tcp包:
-- TcpDistributedCacheConnection
-- TcpDistributedCacheManagerUnicast
-- TcpDistributedCacheManagerFactory
-- TcpDistributedCachePeer
-- TcpDistributedCacheReplicate
基于org.sapphire.cache.distributed.rmi包:
測(cè)試中未發(fā)布…
基于org.sapphire.cache.distributed.p2p包:
測(cè)試中未發(fā)布…
3.使用Sapphire構(gòu)建基礎(chǔ)緩存架構(gòu)
在使用Sapphire為您完成緩存架構(gòu)之前,應(yīng)該先建立一個(gè)屬于Sapphire的配置文件。配置文件的格式以XML的方式為主。
配置文件需要導(dǎo)入Sapphire的DTD標(biāo)簽:
<!DOCTYPE sapphire PUBLIC
"-//Sapphire Cache//DTD Sapphire Configuration 1.0//CN"
"sapphire-cache-1.1.dtd"
Sapphire的缺省配置如下:
<sapphire>
<!-- 緩存注解服務(wù)驅(qū)動(dòng) -->
<service:annotation-driven auto="true" />
<!-- 緩存持久化全局配置 -->
<diskStore path="java.io.tmpdir" diskEternal="true"
timeToRemoveSeconds="5" />
<!-- 缺省緩存配置 -->
<cache name="defaultCache" eternal="false" maxElementsInSize="100"
maxCacheInMemory="1" capacityUnit="kByte" overflowToDisk="true"
diskPersistent="false" timeToLiveSeconds="1" cacheCleanupPolicy="LRU" />
</sapphire>
Sapphire配置文件各個(gè)元素及屬性描述:
<!-- service:annotation-driven -->
<!-- auto: 自動(dòng)緩存需指定方法 -->
<!-- diskStore -->
<!-- path: 緩存持久化臨時(shí)目錄 -->
<!-- diskEternal: 緩存持久化是否永久有效 -->
<!-- timeToRemoveSeconds: 緩存持久化回收時(shí)間/秒 -->
<!-- cache -->
<!-- name: 緩存名稱 -->
<!-- eternal: 緩存是否永久有效 -->
<!-- maxElementsInSize: 緩存最大元素?cái)?shù)量 -->
<!-- maxCacheInMemory: 緩存最大容量 -->
<!-- capacityUnit: 緩存容量單位(byte|kByte|mByte|gByte) -->
<!-- overflowToDisk: 緩存持久化 -->
<!-- diskPersistent: 加載虛擬機(jī)重啟期數(shù)據(jù) -->
<!-- timeToLiveSeconds: 設(shè)置緩存中元素在失效前允許存活時(shí)間/秒 -->
<!-- cacheCleanupPolicy: 當(dāng)緩存中元素失效后,所采用的緩存回收策略 (LRU(最少使用, Least Recently? Used)、LFU(較少使用, Least Frequently Used)、 RDM(隨機(jī), Random)) -->
注意:
在使用Sapphire為您完成緩存架構(gòu)之前,需要將log4j.jar導(dǎo)入至您的項(xiàng)目中。
基于Sapphire的第一個(gè)緩存應(yīng)用程序:
/* 初始化Sapphire容器 */
CacheManager cacheManager = new SapphireCacheManager();
/* 獲取緩存實(shí)例 */
Cache cache = cacheManager.getCache("defaultCache");
/* 緩存數(shù)據(jù)元素 */
cache.put("key", "value");
System.out.println(cache.get("key"));
在您的程序中使用Sapphire來幫助您搭建緩存架構(gòu)是一件極其簡(jiǎn)單且輕松的事情。首先我們只需初始化Sapphire緩存管理容器(上述程序示例中使用到的Sapphire管理容器為SapphireCacheManager),該容器會(huì)負(fù)責(zé)初始化一系列的緩存前期準(zhǔn)備工作。緊接著我們需要通過SapphireCacheManager的getCache(String cacheName)方法取得緩存實(shí)例并得到一個(gè)具體的Cache對(duì)象,最后通過Cache對(duì)象的put(Object key, Object value)方法添加您所需緩存的數(shù)據(jù)即可。
CacheManager為Sapphire的頂層緩存管理容器,其派生類有:
-- CacheManagerImpl
??? -- SapphireCacheManager
??? -- CacheManagerForSafety
提供給您使用的主要是SapphireCacheManager與CacheManagerForSafety這2個(gè)緩存管理實(shí)現(xiàn)。其中SapphireCacheManager為非線程安全,而CacheManagerForSafety則基于線程安全模型。就性能比較而言SapphireCacheManager顯得更為高效,CacheManagerForSafety則更為安全,當(dāng)然您可以根據(jù)您的具體需求選擇合適您的緩存管理實(shí)現(xiàn)。
CacheManager提供的常用方法如下:
getCache(String cacheName) throws Exception: Cache 返回緩存實(shí)例
getCacheInMemoryAll() throws Exception:long 獲取所有緩存已用緩存容量
當(dāng)然不管您是使用任何一種緩存管理容器,Sapphire都為您提供有2種構(gòu)造實(shí)現(xiàn)。假設(shè)您在項(xiàng)目中使用SapphireCacheManager作為緩存管理實(shí)現(xiàn),您可以根據(jù)您具體的配置需求來達(dá)到滿足您具體的實(shí)現(xiàn)。通常情況下,我們建議您使用缺省構(gòu)造,因?yàn)檫@樣不僅僅可以為您減少一定的代碼量,且顯得更為直觀,但使用帶參構(gòu)造則會(huì)使您的應(yīng)用更為靈活和高效。
使用SapphireCacheManager作為管理容器2種實(shí)現(xiàn):
/* 第一種初始化Sapphire容器方式 */
CacheManager cacheManager = new SapphireCacheManager();
或者:
/* 第二種初始化Sapphire容器方式 */
CacheManager cacheManager = new SapphireCacheManager("sapphire.xml");
使用CacheManagerForSafety作為管理容器2種實(shí)現(xiàn):
/* 第一種初始化Sapphire容器方式 */
CacheManager cacheManager = new CacheManagerForSafety();
或者:
/* 第二種初始化Sapphire容器方式 */
CacheManager cacheManager = new CacheManagerForSafety("sapphire.xml");
注意:
如果使用第一種緩存構(gòu)造實(shí)現(xiàn),Sapphire的緩存管理容器會(huì)自動(dòng)在工程目錄查找名為sapphire.xml的緩存配置文件。
4.Cache類型
Sapphire為您提供的Cache類型為具體的緩存對(duì)象,該類型主要負(fù)責(zé)為您緩存您所需緩存的數(shù)據(jù),以及管理這些緩存進(jìn)Sapphire管理容器中的數(shù)據(jù)。Cache實(shí)現(xiàn)自JDK中java.util.concurrent包的ConcurrentHashMap高并發(fā)容器,這樣便能夠?yàn)槟鷰砀咝У木彺嫱掏滦浴?
Cache提供的常用方法如下:
put(Object key, Object value):Object 添加緩存數(shù)據(jù)
get(Object key):Object 獲取緩存數(shù)據(jù)
remove(Object key):Object 清除指定緩存數(shù)據(jù)
clear():void 清除所有緩存數(shù)據(jù)
getElementsInSize():long 獲取當(dāng)前緩存已用元素?cái)?shù)量
getSurplusElementsInSize(): long 獲取當(dāng)前緩存剩余元素?cái)?shù)量
getMaxElementsInSize(): long 獲取當(dāng)前緩存最大元素?cái)?shù)量
getCacheInMemory(): long 獲取當(dāng)前緩存已用緩存容量
getMaxCacheInMemory(): long 獲取當(dāng)前緩存最大緩存容量
getSurplusCacheInMemory():long 獲取當(dāng)前緩存剩余緩存容量
cacheUseRecords(Object key): void 計(jì)算緩存使用記錄
getCacheUseRecords():HashMap 獲取緩存使用記錄
getMaxCacheInMemoryForByte(long maxCacheInMemory,
String capacityUnit): long 計(jì)算當(dāng)前緩存的最大字節(jié)緩存容量
5.使用Sapphire緩存缺省數(shù)據(jù)類型
缺省情況下Sapphire可以為您緩存的數(shù)據(jù)類型為如下3類:
基本數(shù)據(jù)類型;
數(shù)組類型;
String類型;
使用Sapphire緩存缺省數(shù)據(jù)類型實(shí)現(xiàn):
/* 緩存基本數(shù)據(jù)類型 */
cache.put("byte", 1);
cache.put("short", 10);
cache.put("int", 100);
cache.put("long", 1000L);
cache.put("float", 1.5);
cache.put("double", 10.5D);
cache.put("char", 'A');
cache.put("boolean", true);
/* 緩存數(shù)組數(shù)據(jù)類型 */
cache.put("byte[]", new byte[100]);
/* 緩存String數(shù)據(jù)類型 */
cache.put("String", "Sapphire Cache");
6.使用Sapphire緩存復(fù)合數(shù)據(jù)類型
缺省情況下Sapphire并沒有提供對(duì)復(fù)合數(shù)據(jù)類型的支持,但您可以將您需要緩存的復(fù)合對(duì)象實(shí)現(xiàn)Sapphire為您提供的CacheSerializable接口(該接口為標(biāo)記接口,無需任何實(shí)現(xiàn))。一旦您的復(fù)合對(duì)象實(shí)現(xiàn)了該接口,Sapphire便會(huì)允許緩存您所指定的復(fù)合對(duì)象,除了可以實(shí)現(xiàn)CacheSerializable接口,Sapphire仍然允許您實(shí)現(xiàn)JDK原生的Serializable接口。
至于復(fù)合數(shù)據(jù)類型為什么需要實(shí)現(xiàn)CacheSerializable接口或者實(shí)現(xiàn)Serializable接口Sapphire才允許將其緩存呢?其實(shí)Sapphire在對(duì)您的數(shù)據(jù)進(jìn)行緩存之前需要將所有數(shù)據(jù)進(jìn)行序列化處理,以便計(jì)算當(dāng)前所需緩存的數(shù)據(jù)所占緩存容量的內(nèi)存大小。
使用Sapphire緩存復(fù)合數(shù)據(jù)類型實(shí)現(xiàn):
class SaveObject implements CacheSerializable
{
//...
}
/* 初始化Sapphire容器方式 */
CacheManager cacheManager = new SapphireCacheManager();
/* 獲取緩存實(shí)例 */
Cache cache = cacheManager.getCache("defaultCache");
/* 緩存復(fù)合數(shù)據(jù)類型 */
cache.put("object", new SaveObject());
System.out.println(cache.get("object") instanceof CacheSerializable);
注意:
如果您在使用Sapphire為您緩存復(fù)合對(duì)象時(shí)并沒有將所需緩存的數(shù)據(jù)實(shí)現(xiàn)CacheSerializable接口或者Serializable接口,Sapphire將會(huì)拋出java.io.NotSerializableException異常信息。
7.啟動(dòng)緩存注解服務(wù)驅(qū)動(dòng)
通過Sapphire的配置文件我們可以觀察到<service:annotation-driven>標(biāo)簽。該標(biāo)簽主要用作于開啟緩存注解服務(wù)驅(qū)動(dòng),其中包含有一個(gè)auto屬性,該屬性所允許的參數(shù)范圍為“true”與“false”。如果您將auto屬性設(shè)置為“true”,則意味著您將成功開啟Sapphire的緩存注解服務(wù)驅(qū)動(dòng)服務(wù),否則意味著該服務(wù)的狀態(tài)為關(guān)閉狀態(tài)。
至于開啟Sapphire的緩存注解服務(wù)驅(qū)動(dòng)有何用處,想必這是您最為關(guān)心的問題。其實(shí)不難發(fā)現(xiàn)在很多復(fù)雜應(yīng)用的情況下,我們經(jīng)常需要緩存具體的方法返回結(jié)果(比如服務(wù)層與持久層),面對(duì)這種情況雖然我們可以使用Cache對(duì)象的put方法進(jìn)行數(shù)據(jù)緩存,但這并不靈活。所以Sapphire將為您提供了一個(gè)基于注解方式的方法返回值緩存技術(shù),這便是剛才我們所提到的緩存注解服務(wù)。
位于org.sapphire.cache.annotation包下的@CacheService類型正是我們即將使用到的方法返回值緩存技術(shù)的實(shí)現(xiàn)。
緩存注解服務(wù)驅(qū)動(dòng)實(shí)例:
此處省略導(dǎo)包過程…
public class SapphireCacheTest extends TestCase
{
/**
* @param args
*/
public static void main(String[] args) throws Exception
{
/* 初始化Sapphire容器方式 */
CacheManager cacheManager = new SapphireCacheManager();
/* 獲取緩存實(shí)例 */
Cache cache = cacheManager.getCache("defaultCache");
Element element1 = new Element(SaveObject.class.getName(),
"testService1", cache);
element1.put(26);
System.out.println("age: " + cache.get("age"));
Element element2 = new Element(SaveObject.class.getName(),
"testService2", cache);
element2.put(1, "JohnGao");
System.out.println("UserBean: " + cache.get("info"));
}
}
此處省略導(dǎo)包過程…
public class SaveObject implements CacheSerializable
{
@CacheService(cacheElementKey = "age")
public int testService1(int age)
{
return age;
}
@CacheService(cacheElementKey = "info")
public Object testService2(int userId, String userName)
{
class InfoBean implements CacheSerializable
{
int userId;
String userName;
}
InfoBean info = new InfoBean();
info.userId = userId;
info.userName = userName;
return info;
}
}
在您使用Sapphire為您提供的緩存注解服務(wù)器時(shí),您務(wù)必先找到Sapphire的配置文件中的<service:annotation-driven>標(biāo)簽,并將該標(biāo)簽的auto屬性設(shè)置為“true”則意味著注解服務(wù)成功開啟。接著您便可以通過@CacheService(cacheElementKey = "age")的注解方式對(duì)所需緩存的方法進(jìn)行標(biāo)注。這里需要提醒一下@CacheService中需要設(shè)置一個(gè)cacheElementKey的屬性,該屬性所代表的是緩存Key。
當(dāng)您成功的在方法前添加@CacheService標(biāo)注后,仍然還需要使用到一個(gè)類型,那便是Element類型。該類型作為Sapphire的緩存元素類型,在使用緩存注解服務(wù)的時(shí)候您必須使用它才能夠?qū)δ姆椒ǚ祷刂颠M(jìn)行動(dòng)態(tài)緩存。
Element提供的常用方法如下:
Element(String serviceClass, String serviceMethod,
Cache cache) 構(gòu)造函數(shù)(緩存類型名稱、緩存方法名稱、Cache實(shí)例)
put(Object... params):void 添加服務(wù)參數(shù)
cacheParam(Object... params):void 緩存服務(wù)參數(shù)
注意:
如果您并沒有開啟Sapphire的緩存注解服務(wù)便使用時(shí),Sapphire將會(huì)拋出org.sapphire.cache.
exception.CacheServiceException異常。
8.設(shè)置緩存所能存儲(chǔ)的最大元素?cái)?shù)量
Sapphire在緩存管理上為您提供了更為靈活的緩存管理方式,但首先您應(yīng)該先了解Sapphire到底是如何對(duì)緩存進(jìn)行管理的。
通過Sapphire的配置文件我們可以在<cache/>標(biāo)簽中找到一個(gè)名為maxElementsInSize的屬性,該屬性用于定義單個(gè)緩存所允許存放的最大緩存元素?cái)?shù),假設(shè)您將maxElementsInSize屬性設(shè)置為10,那么您的緩存實(shí)例將只允許緩存10個(gè)數(shù)據(jù)元素。
一旦您所定義的maxElementsInSize溢出,Sapphire將會(huì)拋org.sapphire.cache.exception.
CacheElementsException異常。
9.設(shè)置緩存所能存儲(chǔ)的最大緩存容量
Sapphire作為一個(gè)高效的緩存Framework,單個(gè)緩存允許您存儲(chǔ)高達(dá)1Gbyte的緩存數(shù)據(jù)。當(dāng)然Sapphire的緩存容量與實(shí)際的物理內(nèi)存與VM內(nèi)存精密相關(guān),也就是說如果您希望將Sapphire的單個(gè)緩存容量設(shè)置為1GByte,那么你需要觀察您的實(shí)際物理內(nèi)存及VM內(nèi)存是否允許,否則Sapphire將會(huì)拋出java.lang.OutOfMemoryError異常。
通過Sapphire的配置文件我們可以在<cache/>標(biāo)簽中找到2個(gè)名為maxCacheInMemory和capacityUnit的屬性,其中maxCacheInMemory屬性用于設(shè)置您所定義的緩存容量大小,而maxCacheInMemory則用于定義您的緩存容量單位,假設(shè)maxCacheInMemory定義為“10”,capacityUnit定義為“mByte”,那么也就是說您則定義了一個(gè)緩存容量為10mByte的單個(gè)緩存實(shí)例。一旦您所定義的maxCacheInMemory溢出,Sapphire將會(huì)拋出org.sapphire.cache.exception.
OutOfCacheError異常。
在程序中您可以通過Cache類型提供的一些緩存容量及元素檢測(cè)方法來觀測(cè)您具體的緩存容量開銷。
觀測(cè)緩存容量開銷實(shí)例:
/* 初始化Sapphire緩存管理容器 */
CacheManager cacheManager = new SapphireCacheManager();
/* 獲取緩存實(shí)例 */
Cache cache = cacheManager.getCache("defaultCache");
/* 添加緩存元素 */
cache.put("key", new byte[100]);
System.out.println("最大緩存元素長(zhǎng)度:" + cache.getMaxElementsInSize());
System.out.println("當(dāng)前緩存元素長(zhǎng)度:" + cache.getElementsInSize());
System.out.println("剩余緩存元素長(zhǎng)度:" + cache.getSurplusElementsInSize());
System.out.println("最大緩存容量:" + cache.getMaxCacheInMemory());
System.out.println("當(dāng)前緩存容量:" + cache.getCacheInMemory());
System.out.println("剩余緩存容量:" + cache.getSurplusCacheInMemory());
注意:
如果最大緩存元素長(zhǎng)度<=當(dāng)前緩存元素長(zhǎng)度時(shí),剩余緩存元素長(zhǎng)度則為“-1”。如果當(dāng)前緩存容量>最大緩存容量時(shí),剩余緩存容量則為“-1”。
10.緩存持久化
在您使用Sapphire緩存數(shù)據(jù)時(shí),極有可能會(huì)出現(xiàn)maxElementsInSize溢出及maxCacheInMemory溢出。但這些溢出的數(shù)據(jù)可能恰恰是較為重要且不希望丟失的數(shù)據(jù),這個(gè)時(shí)候該怎么辦呢?值得慶幸的是Sapphire為您帶來了高效的緩存持久化技術(shù),也就是說您可以通過Sapphire的配置文件找到<cache/>標(biāo)簽的overflowToDisk屬性,并設(shè)置為“true”時(shí),那么一旦maxElementsInSize或者maxCacheInMemory溢出時(shí),其溢出的數(shù)據(jù)并不會(huì)直接丟失,Sapphire則將會(huì)為您將這一部分溢出的數(shù)據(jù)持久化于本地進(jìn)行存儲(chǔ),以便于您繼續(xù)使用。
如果您希望使用Sapphire為您提供的緩存持久化技術(shù),那么您不僅僅需要將Sapphire配置文件中得overflowToDisk屬性設(shè)置為“true”,您還需要設(shè)置<diskStore>標(biāo)簽中得path、diskEternal、timeToRemoveSeconds等3個(gè)屬性。path屬性缺省為“java.io.tmpdir”,也就是說一旦出現(xiàn)maxElementsInSize或者maxCacheInMemory溢出時(shí),Sapphire會(huì)將溢出數(shù)據(jù)緩存于操作系統(tǒng)的臨時(shí)目錄(不同的操作系統(tǒng)臨時(shí)目錄不同)中進(jìn)行存儲(chǔ),存儲(chǔ)格式為SAPPHIRE_CACHE.data。
除了path屬性外,<diskStore>標(biāo)簽中的另外2個(gè)屬性diskEternal和timeToRemoveSeconds則將滿足您更多的需求。如果您希望您所持久化的緩存數(shù)據(jù)是永遠(yuǎn)有效的,則需要將diskEternal屬性設(shè)置為“true”,這樣一來持久化于本地的緩存將永不失效。如果您將其設(shè)置為“false”時(shí),則意味著timeToRemoveSeconds屬性所定義的內(nèi)容將影響到持久化緩存的失效周期,假設(shè)您將timeToRemoveSeconds屬性定義為“10”,當(dāng)10秒以后,Sapphire的回收器將會(huì)對(duì)持久化緩存進(jìn)行回收。
11.加載虛擬機(jī)重啟期數(shù)據(jù)
當(dāng)您成功將緩存進(jìn)行持久化后,Sapphire為您提供了一種持久化讀取機(jī)制來加載虛擬機(jī)重啟期數(shù)據(jù)。當(dāng)然您需要將Sapphire配置文件中的diskPersistent屬性設(shè)置為“true”
這里有一點(diǎn)您需要稍加注意,如果您在Sapphire的配置文件中設(shè)置的maxElementsInSize或者maxCacheInMemory屬性不再重啟期數(shù)據(jù)的范圍內(nèi),也就是說Sapphire仍然會(huì)將其認(rèn)為溢出,導(dǎo)致重復(fù)緩存持久化。
12.緩存回收策略
Sapphire為您提供有3種緩存回收策略,分別為:LRU、LFU、RMD。
LRU(最少使用, Least Recently Used)將會(huì)根據(jù)您對(duì)緩存元素的實(shí)際使用來動(dòng)態(tài)收回緩存元素,使用次數(shù)最少的緩存元素則優(yōu)先被Sapphire回收器進(jìn)行回收,當(dāng)然您需要通過Sapphire的配置文件找到<cache>標(biāo)簽并設(shè)置timeToLiveSeconds屬性,該屬性主要用于設(shè)置緩存的失效周期,單位為秒。假設(shè)您將timeToLiveSeconds屬性設(shè)置為“10”,則意味著10秒以后Sapphire回收器將會(huì)按照cacheCleanupPolicy屬性所定義的回收策略對(duì)緩存進(jìn)行動(dòng)態(tài)回收。LFU和RMD等回收策略也是經(jīng)常較為適用的,但一般來說我們推薦您使用LRU緩存回收策略。
注意:
如果您在<cache>標(biāo)簽中將eternal屬性設(shè)置為“true”時(shí),則意味著您的緩存為永不失效,同樣cacheCleanupPolicy則也就意味著失效。
13.分布式緩存——TCP集群配置模式
Sapphire為您提供了3種類型的分布式緩存機(jī)制,但Sapphire推薦您使用TCP集群為首選。因?yàn)樵摲植际骄彺娴膶?shí)現(xiàn)方式為TCP單播機(jī)制,無論是安全性、正確性、穩(wěn)定性,哪怕是效率上都是較為優(yōu)秀的。
如果您希望使用TCP集群配置模式的方式來實(shí)現(xiàn)緩存共享,那么首先您需要在Sapphire的配置文件中添加TCP集群配置。
您可以使用Sapphire為您提供的<distributedCacheManagerFactory>標(biāo)簽,該標(biāo)簽中一共包含了3個(gè)屬性,分別是:class、serverHost以及serverPort。其中class用于指定集群類型,serverHost屬性用于指定集群地址,serverPort屬性用于指定集群端口。
假設(shè)您已經(jīng)成功配置TCP集群后,您還需在<cache>標(biāo)簽中添加<distributedCacheListener>子標(biāo)簽,該標(biāo)簽用于啟動(dòng)緩存復(fù)制監(jiān)聽,并包含一個(gè)名為replicateCache的屬性,如果您將其設(shè)置為“true”則意味著您允許緩存實(shí)例實(shí)現(xiàn)緩存共享,否則將意味著拒絕緩存共享。
TCP集群配置示例:
<!-- 緩存注解服務(wù)驅(qū)動(dòng) -->
<service:annotation-driven auto="true" />
<!-- 緩存持久化全局配置 -->
<diskStore path="java.io.tmpdir" diskEternal="false"
timeToRemoveSeconds="60" />
<!-- TCP集群配置模式 -->
<distributedCacheManagerFactory
class="org.sapphire.cache.distributed.tcp.TcpDistributedCacheManagerFactory" serverHost="127.0.0.1" serverPort="30051" />
<!-- 缺省緩存配置 -->
<cache name="defaultCache" eternal="false" maxElementsInSize="100"
maxCacheInMemory="1" capacityUnit="mByte" overflowToDisk="true"
diskPersistent="false" timeToLiveSeconds="60" cacheCleanupPolicy="LRU">
<!-- 啟動(dòng)緩存復(fù)制監(jiān)聽 -->
<distributedCacheListener replicateCache="true" />
</cache>
通過上述示例,您可以發(fā)現(xiàn)< distributedCacheManagerFactory >標(biāo)簽中的class屬性其值為一個(gè)TcpDistributedCacheManagerFactory類型(位于org.sapphire.cache.distributed.tcp包下)。該類型作用于搭建一個(gè)穩(wěn)定且高性能的TCP分布式緩存服務(wù)器。
使用Sapphire來為您實(shí)現(xiàn)分布式緩存是一件及其簡(jiǎn)單的事情,只要您在Sapphire的配置文件中啟用了TCP集群配置模式,并成功開啟了緩存復(fù)制監(jiān)聽,那么就無需您在做任何操作,便可實(shí)現(xiàn)分布式緩存共享。接下來您可以通過一段簡(jiǎn)單的測(cè)試代碼來實(shí)現(xiàn)Sapphire為您提供的基于TCP集群配置模式的分布式緩存。
分布式緩存示例:
/* 初始化Sapphire緩存管理容器 */
CacheManager cacheManager = new SapphireCacheManager();
/* 獲取緩存實(shí)例 */
Cache cache = cacheManager.getCache("defaultCache");
while(true)
{
cache.put("cacheKey", "cacheValue");
System.out.println(cache.get("key"));
Thread.sleep(1000);
}
上述程序一旦運(yùn)行后,Sapphire便會(huì)成功開啟TCP緩存服務(wù)器,啟動(dòng)緩存服務(wù),并成功的實(shí)現(xiàn)緩存共享。但這個(gè)時(shí)候您可能會(huì)覺得奇怪,因?yàn)槟]有使用客戶端對(duì)TCP緩存服務(wù)器進(jìn)行連接,為什么您卻可以獲取共享后的緩存?其實(shí)這是因?yàn)樵谌笔…h(huán)境下Sapphire的TCP緩存服務(wù)器既是服務(wù)端又是客戶端,能夠自身實(shí)現(xiàn)緩存共享。
如果您的網(wǎng)絡(luò)中有其余的節(jié)點(diǎn)需要共享緩存信息,那么您便可以將< distributedCacheManagerFactory >標(biāo)簽中的class屬性的值更改為org.sapphire.cache.distributed.tcp. TcpDistributedCacheConnection即可,該類型為TCP集群連接類型。
注意:
如果程序中,您并沒有成功啟動(dòng)TCP集群配置模式,而直接為class屬性去配置TcpDistributedCacheConnection類型,這個(gè)時(shí)候Sapphire則會(huì)拋出org.sapphire.cache.exception.
TcpCacheDistributedException異常。
還有一點(diǎn)您需要注意,假設(shè)您程序中有多個(gè)緩存實(shí)例都需要實(shí)現(xiàn)緩存共享時(shí),您可以在Sapphire配置文件中為需要實(shí)現(xiàn)緩存共享的緩存類型開啟緩存復(fù)制監(jiān)聽即可。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
