it技术javaJava 杂谈

本地缓存(Java实现之理论篇)

2016-11-09  本文已影响3992人  撸二行代码

目录:

一:什么是缓存

二:为什么要用本地缓存

三:我们一开始是怎么实施本地缓存的

四: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分布式

六:再次实现本地缓存

哈哈,你们被欺骗了,等明天吧?

上一篇下一篇

猜你喜欢

热点阅读