首页 > 编程知识 正文

java缓存有哪些,java实现缓存

时间:2023-05-04 05:26:52 阅读:30430 作者:776

java的本地缓存在工作后一个接一个地被使用,一直想写,一直拿不出手。 最近又关于这方面的问题进行了整理。 独有结构单例、guava、ehcache基本涵盖了目前的大部分行为。

为什么需要本地缓存?

一些系统经常访问的数据,即使数据量很少。 例如,国家标准行政区域数据)。 在这种情况下,必须将数据放在APP应用程序的本地缓存中,以提高系统访问效率并减少不必要的数据库访问。 虽然数据库访问占用数据库连接并占用大量网络,但需要注意的是缓存占用空间和缓存禁用策略。

为什么是本地缓存而不是分布式群集缓存?

许多当前数据都是与业务无关的小数据缓存,不需要创建分布式群集缓存。 现在,订单和商品相关的数据,直接去数据库要求。 另外,除了构建分布式缓存外,群集维护成本高,不太适合紧急业务项目。

本节介绍使用缓存的三个阶段。 (摘自info架构师文档) ) ) )。

本地缓存在那个区域吗?

现在被认为占用了JVM的heap区域。 再细分一点的是heap中的old区域。 以现在的数据量来看,都是小数据,加起来不到几百兆。 放在heap区域是最快最方便的。 如果后期需要放在本地缓存中的数据很大,则可以考虑将其存储在off-heap区域(direct-memory或big-memory )中,但对于off-heap区域, 必须考虑对象的序列化((因为off-heap区域中存储的是二进制数据() ) ) ) ) )其实,如果数据量真的很大,实际上创建一个负责缓存的集中式缓存系统单体或集群都可以。

创建单实例模式,其中有Map变量放置数据

单示例模式是简单复杂的模式(3358 iam zhong Yong.iteye.com/blog/1539642 )。

典型的代码如下。

公共类单一贴图{

//本地缓存映射

privatemaplocalcachestore=new hashmap (;

//是私人对象,不是cbdqz模式

privatestaticsingletonmapsingletonmap=newsingletonmap (;

//私人结构方法,不能在外部新建一个对象

私密单次映射

}

//静态方法,从外部获取实例对象

publicstaticsingletonmapgetinstance (

返回单次映射;

}

//获取缓存中的数据

publicobjectgetvaluebykey (字符串密钥) {

returnlocalcachestore.get(key;

}

//将数据添加到缓存中

publicvoidputvalue (字符串密钥,对象值) {

localcachestore.put(key,value;

}

}

这个可以用吗? 可以使用,但非常有限

但是这样的是本地缓存吗? 答案明显不同,为什么呢?

1、没有缓存大小设置,不能限制“最大大小限制”和“存储数据限制”

2、缓存撤销策略(eviction policies );

3、在没有弱密钥引用、内存消耗紧张的情况下,不能回收JVM (weak rere rences keys );

4、无监测统计(统计;

5、持久性存储(永久存储);

所以,这种东西就这样废除了。

部署EhCache以构建缓存(3360http://ray chase.iteye.com/blog/1545906详细信息) ) ) )。

EhCahce核心类:

a、CacheManager:Cache的管理类;

b、Cache :负责缓存的get和put等操作的具体Cache类信息

c、缓存配置:缓存的配置信息。 包括策略、最大值等信息

d,element :缓存中单个缓存数据的单位

典型的代码如下。

publicstaticvoidmain (字符串[ ] args ) {

//EhCache缓存由缓存管理器管理

cachemanagercachemanager=cachemanager.getinstance (;

//缓存的配置也可以在xml文件中进行

cacheconfigurationconf=newcacheconfiguration (;

Conf.name(ca

che_name_default");//设置名字

conf.maxEntriesLocalHeap(1000);//最大的缓存数量

conf.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU);//设置失效策略

//创建一个缓存对象,并把设置的信息传入进去

Cache localCache = new Cache(conf);

//将缓存对象添加到管理器中

cacheManager.addCache(localCache);

localCache.put(new Element("iamzhongyong", new Date()));

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 void main(String[] args) throws Exception{

GuavaCacheBuilderTest cache = new GuavaCacheBuilderTest();

cache.getNameLoadingCache("bixiao");

}

public void getNameLoadingCache(String name) throws Exception{

LoadingCache cache = CacheBuilder.newBuilder()

.maximumSize(20)//设置大小,条目数

.expireAfterWrite(20, TimeUnit.SECONDS)//设置失效时间,创建时间

.expireAfterAccess(20, TimeUnit.HOURS) //设置时效时间,最后一次被访问

.removalListener(new RemovalListener() { //移除缓存的监听器

public void onRemoval(RemovalNotification notification) {

System.out.println("有缓存数据被移除了");

}})

.build(new CacheLoader(){ //通过回调加载缓存

@Override

public String load(String name) 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、需要实时生效数据:启动时可预热也可不预热,但是缓存数据变更后,集群之间需要同步

原文:https://www.cnblogs.com/lyh971134228/p/6874432.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。