java本地缓存技术或框架
生活随笔
收集整理的這篇文章主要介紹了
java本地缓存技术或框架
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
java中的本地緩存,工作后陸續用到,一直想寫,一直無從下手,最近又涉及到這方面的問題了,梳理了一下。自己構造單例、guava、ehcache基本上涵蓋了目前的大多數行為了。
為什么要有本地緩存?
在系統中,有些數據,數據量小,但是訪問十分頻繁(例如國家標準行政區域數據),針對這種場景,需要將數據搞到應用的本地緩存中,以提升系統的訪問效率,減少無謂的數據庫訪問(數據庫訪問占用數據庫連接,同時網絡消耗比較大),但是有一點需要注意,就是緩存的占用空間以及緩存的失效策略。
為什么是本地緩存,而不是分布式的集群緩存?
? ???目前的數據,大多是業務無關的小數據緩存,沒有必要搞分布式的集群緩存,目前涉及到訂單和商品的數據,會直接走DB進行請求,再加上分布式緩存的構建,集群維護成本比較高,不太適合緊急的業務項目。
? ???這里介紹一下緩存使用的三個階段(摘自info架構師文檔)
? ?? ??
本地緩存在那個區域?
? ???目前考慮的是占用了JVM的heap區域,再細化一點的就是heap中的old區,目前的數據量來看,都是一些小數據,加起來沒有幾百兆,放在heap區域最快最方便。后期如果需要放置在本地緩存的數據大的時候,可以考慮在off-heap區域(direct-memory或者big-memory),但是off-heap區域的話,需要考慮對象的序列化(因為off-heap區域存儲的是二進制的數據),另外一個的話就是off-heap的GC問題。其實,如果真的數據量比較大,那其實就可以考慮搞一個集中式的緩存系統,可以是單機,也可以是集群,來承擔緩存的作用。
搞一個單例模式,里面有個Map的變量來放置數據
關于單例模式,一個既簡單又復雜的模式(http://iamzhongyong.iteye.com/blog/1539642)
非常典型的代碼如下:
public class SingletonMap {
? //一個本地的緩存Map
? private MaplocalCacheStore = new HashMap();?
? //一個私有的對象,非懶漢模式
? private staticSingletonMap singletonMap = newSingletonMap();?
?//私有構造方法,外部不可以new一個對象
? privateSingletonMap(){
? }?
? //靜態方法,外部獲得實例對象
? public staticSingletonMap getInstance(){
? ?? return singletonMap;
? }
? //獲得緩存中的數據
? public ObjectgetValueByKey(String key){
? ?? return localCacheStore.get(key);
? }
? //向緩存中添加數據
? public voidputValue(String key , Object value){
? ?? localCacheStore.put(key, value);
? }
}
這種能不能用?可以用,但是非常局限
但是這種的就是本地緩存了嗎?答案顯然不是,為啥呢?
1、 ?沒有緩存大小的設置,無法限定緩存體的大小以及存儲數據的限制(max sizelimit);
2、 ?沒有緩存的失效策略(eviction policies);
3、 ?沒有弱鍵引用,在內存占用吃緊的情況下,JVM是無法回收的(weakrererences keys);
4、 ?沒有監控統計(statistics);
5、 ?持久性存儲(persistent store);
所以,這種就直接廢掉了。。。
引入EhCache來構建緩存(詳細介紹:?http://raychase.iteye.com/blog/1545906)
EhCahce的核心類:
A、CacheManager:Cache的管理類;
B、Cache:具體的cache類信息,負責緩存的get和put等操作
C、CacheConfiguration :cache的配置信息,包含策略、最大值等信息
D、Element:cache中單條緩存數據的單位
典型的代碼如下:
public static void main(String[] args) {
? ?? //EhCache的緩存,是通過CacheManager來進行管理的
? ?? CacheManager cacheManager =CacheManager.getInstance();
? ?? ?
? ?? //緩存的配置,也可以通過xml文件進行
? ?? CacheConfiguration conf = newCacheConfiguration();
? ?? conf.name("cache_name_default");//設置名字
? ?? conf.maxEntriesLocalHeap(1000);//最大的緩存數量
? ??conf.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU);//設置失效策略
? ?? ?
? ?? //創建一個緩存對象,并把設置的信息傳入進去
? ?? Cache localCache = new Cache(conf);
? ?? ?
? ?? //將緩存對象添加到管理器中
? ?? cacheManager.addCache(localCache);
? ?? ? ?? ? ?
? ?? localCache.put(new Element("iamzhongyong", newDate()));
? ?? ?
? ?? System.out.println(localCache.getSize());
? ??System.out.println(localCache.getStatistics().toString());
? ?? System.out.println(localCache.getName());
? ??System.out.println(localCache.get("iamzhongyong").toString());
? ??System.out.println(localCache.get("iamzhongyong").getObjectValue());??
? }
當然,Cache的配置信息,可以通過配置文件制定了。。。
優點:功能強大,有失效策略、最大數量設置等,緩存的持久化只有企業版才有,組件的緩存同步,可以通過jgroup來實現
缺點:功能強大的同時,也使其更加復雜
引入guava的cacheBuilder來構建緩存
這個非常強大、簡單,通過一個CacheBuilder類就可以滿足需求。
缺點就是如果要組件同步的話,需要自己實現這個功能。
典型的代碼如下:
public class GuavaCacheBuilderTest {
? public static voidmain(String[] args) throws Exception{
? ?? GuavaCacheBuilderTest cache = newGuavaCacheBuilderTest();
? ?? cache.getNameLoadingCache("bixiao");
? }
? public voidgetNameLoadingCache(String name) throws Exception{
? ?? LoadingCache cache = CacheBuilder.newBuilder()? ???
? ?? ? ?.maximumSize(20)//設置大小,條目數 ? ?? ?
? ?? ? ?.expireAfterWrite(20, TimeUnit.SECONDS)//設置失效時間,創建時間? ? ?
? ?? ? ?.expireAfterAccess(20, TimeUnit.HOURS) //設置時效時間,最后一次被訪問? ???
? ?? ? ?.removalListener(new RemovalListener() { //移除緩存的監聽器
? ?? ? ?? ? public voidonRemoval(RemovalNotification notification) {
? ?? ? ?? ? ?? System.out.println("有緩存數據被移除了");
? ?? ? ?? ? }})
? ?? ? ? .build(newCacheLoader(){ //通過回調加載緩存
? ?? ? ?? ? @Override
? ?? ? ?? ? public String load(Stringname) throws Exception {
? ?? ? ?? ? ?? return name + "-" + "iamzhongyong";
? ?? ? ?? ? }
? ?? });
? ?? System.out.println(cache.get(name));
? ?? //cache.invalidateAll();
? }
}
緩存預熱怎么搞?
A、全量預熱,固定的時間段移除所有,然后再全量預熱
適用場景:
1、數據更新不頻繁,例如每天晚上3點更新即可的需求;
2、數據基本沒有變化,例如全國區域性數據;
B、增量預熱(緩存查詢,沒有,則查詢數據庫,有則放入緩存)
適用場景:
1、 ?數據更新要求緩存中同步更新的場景
?集群內部,緩存的一致性如何保證?
如果采用ehcache的話,可以使用框架本身的JGroup來實現組內機器之間的緩存同步。
如果是采用google的cacheBuilder的話,需要自己實現緩存的同步。
A、非實時生效數據:數據的更新不會時時發生,應用啟動的時候更新即可,然后定時程序定時去清理緩存;
B、需要實時生效數據:啟動時可預熱也可不預熱,但是緩存數據變更后,集群之間需要同步
總結
以上是生活随笔為你收集整理的java本地缓存技术或框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决org.apache.hadoop.
- 下一篇: android中xmlns:tools属