本地缓存(Java实现之理论篇)
目录:
一:什么是缓存
二:为什么要用本地缓存
三:我们一开始是怎么实施本地缓存的
四:Java本地缓存标准
五:Java开源缓存框架
六:再次实现本地缓存
一:什么是缓存
所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。
缓存主要可分为二大类:
1:通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;
2:内存缓存,也就是创建一个静态内存区域,将数据存储进去,例如我们B/S架构的将数据存储在Application中或者存储在一个静态Map中。
二:为什么要用本地缓存
为什么要有本地缓存?
在系统中,有些数据,数据量小,但是访问十分频繁(例如国家标准行政区域数据或者一些数据字典等),针对这种场景,需要将数据搞到应用的本地缓存中,以提升系统的访问效率,减少无谓的数据库访问(数据库访问占用数据库连接,同时网络消耗比较大),但是有一点需要注意,就是缓存的占用空间以及缓存的失效策略。
所谓的本地缓存是相对于网络而言的(包括集群,数据库访问等)
为什么是本地缓存,而不是分布式的集群缓存?
很多情况的数据,大多是业务无关的(CodeMaster,数据字典等)数据缓存,没有必要搞分布式的集群缓存,再加上分布式缓存的构建,集群维护成本比较高,不太适合这种情况数据。
这里介绍一下缓存使用的三个阶段(摘自info架构师文档)
缓存使用的三个阶段三:我们一开始是怎么实施本地缓存的
public class CacheManager {
//一个本地的缓存Map
private Map localCacheStore =new HashMap();
//一个私有的对象,非懒汉模式
private static CacheManager cacheManager =new CacheManager();
//私有构造方法,外部不可以new一个对象
private CacheManager(){
}
//静态方法,外部获得实例对象
public static CacheManager getInstance(){
return cacheManager;
}
//获得缓存中的数据
public Object getValueByKey(String key){
return localCacheStore.get(key);
}
//向缓存中添加数据
public void putValue(String key ,Object value){
localCacheStore.put(key, value);
}
}
这是一个典型的单例模式,里面有个Map的变量来存储对象。
这段代码有什么问题吗?
完全没有,只是局限性很强。
四:Java本地缓存标准
Java缓存新标准(javax.cache),这个标准由JSR107所提出,已经被包含在Java EE7中。
特性:
1.原子操作,跟java.util.ConcurrentMap类似
2.从缓存中读取
3.写入缓存
4.缓存事件监听器
5.数据统计
6.包含所有隔离(ioslation)级别的事务
7.缓存注解(annotations)
8.保存定义key和值类型的泛型缓存
9.引用保存(只适用于堆缓存)和值保存定义
虽然这些现在使用不是很普遍,但是大家使用过Spring Boot的时候,大家应该发现Spring Boot的Cache已经开始在向这个方向进行靠近了。很多也在使用了。
对于以上的特点,大家看看以前我们实现的那段代码有什么问题吗?
1、 没有缓存大小的设置,无法限定缓存体的大小以及存储数据的限制(max size limit);
2、 没有缓存的失效策略(eviction policies);
3、 没有弱键引用,在内存占用吃紧的情况下,JVM是无法回收的(weak rererences keys);
4、 没有监控统计(statistics);
5、 持久性存储(persistent store)
五:Java开源缓存框架
比较有名的本地缓存开源框架有:
1.OSCache
OSCache有以下特点:缓存任何对象,你可以不受限制的缓存部分jsp页面或HTTP请求,任何java对象都可以缓存。拥有全面的API--OSCache API给你全面的程序来控制所有的OSCache特性。永久缓存--缓存能随意的写入硬盘,因此允许昂贵的创建(expensive-to-create)数据来保持缓存,甚至能让应用重启。支持集群--集群缓存数据能被单个的进行参数配置,不需要修改代码。缓存记录的过期--你可以有最大限度的控制缓存对象的过期,包括可插入式的刷新策略(如果默认性能不需要时)。
2.JCache
Java缓存新标准(javax.cache)
3.cache4j
cache4j是一个有简单API与实现快速的Java对象缓存。它的特性包括:在内存中进行缓存,设计用于多线程环境,两种实现:同步与阻塞,多种缓存清除策略:LFU, LRU, FIFO,可使用强引用。
4.ShiftOne
ShiftOneJavaObject Cache是一个执行一系列严格的对象缓存策略的Java lib,就像一个轻量级的配置缓存工作状态的框架。
5.WhirlyCache
Whirlycache是一个快速的、可配置的、存在于内存中的对象的缓存。
6.Guava Cache
Guava Cache是一个全内存的本地缓存实现,它提供了线程安全的实现机制。
推荐几个分布式缓存框架:
1:Ehcache
Ehcache是一个Java实现的开源分布式缓存框架,EhCache 可以有效地减轻数据库的负载,可以让数据保存在不同服务器的内存中,在需要数据的时候可以快速存取。同时EhCache 扩展非常简单,官方提供的Cache配置方式有好几种。你可以通过声明配置、在xml中配置、在程序里配置或者调用构造方法时传入不同的参数。
2:Cacheonix– 高性能Java分布式缓存系统
Cacheonix同样也是一个基于Java的分布式集群缓存系统,它同样可以帮助你实现分布式缓存的部署。
3:JBoss Cache– 基于事物的Java缓存框架
JBoss Cache是一款基于Java的事务处理缓存系统,它的目标是构建一个以Java框架为基础的集群解决方案,可以是服务器应用,也可以是Java SE应用。
4:Voldemort– 基于键-值(key-value)的缓存框架
Voldemort是一款基于Java开发的分布式键-值缓存系统,像JBoss Cache一样,Voldemort同样支持多台服务器之间的缓存同步,以增强系统的可靠性和读取性能。
5:Redis
Redis是基于内存、可持久化的日志型、Key-Value数据库高性能存储系统,并提供多种语言的API.
6:memcached
memcached是应用最广的开源cache产品,它本身不提供分布式的解决方案,我猜想一方面它想尽量保持产品简单高效,另一方面cache的key-value的特性使得让memcached分布式起来比较简单。memcached的分布式主要在于客户端,通过客户端的路由处理来搭建memcached集群环境,因此在服务端,memcached集群环境实际上就是一个个memcached服务器的堆积品,环境的搭建比较简单。下面从客户端做路由和服务端集群环境搭建两方面来谈如何让memcached分布式
六:再次实现本地缓存
哈哈,你们被欺骗了,等明天吧?