缓存简介
工作机制是:先从缓存中读取数据,如果没有再从慢速设备上读取实际数据(数据也会存入缓存);缓存什么:那些经常读取且不经常修改的数据/那些昂贵(CPU/IO)的且对于相同的请求有相同的计算结果的数据。
如CPU--L1/L2--内存–磁盘就是一个典型的例子,CPU需要数据时先从L1/L2中读取,如果没有到内存中找,如果还没有会到磁盘上找。
还有如用过Maven的朋友都应该知道,我们找依赖的时候,先从本机仓库找,再从本地服务器仓库找,最后到远程仓库服务器找;
还有如京东的物流为什么那么快?他们在各个地都有分仓库,如果该仓库有货物那么送货的速度是非常快的。
缓存命中率
即从缓存中读取数据的次数 与 总读取次数的比率,命中率越高越好:
命中率 = 从缓存中读取次数 / (总读取次数[从缓存中读取次数 + 从慢速设备上读取的次数])
Miss率 = 没有从缓存中读取的次数 / (总读取次数[从缓存中读取次数 + 从慢速设备上读取的次数])
这是一个非常重要的监控指标,如果做缓存一定要健康这个指标来看缓存是否工作良好;
缓存策略
移除策略
移除策略,即如果缓存满了,从缓存中移除数据的策略;常见的有LFU、LRU、FIFO:
FIFO(First In First Out):先进先出算法,即先放入缓存的先被移除;
LRU(Least Recently Used):最久未使用算法,使用时间距离现在最久的那个被移除;
LFU(Least Frequently Used):最近最少使用算法,一定时间段内使用次数(频率)最少的那个被移除;
TTL(Time To Live )
存活期,即从缓存中创建时间点开始直到它到期的一个时间段(不管在这个时间段内有没有访问都将过期)
TTI(Time To Idle)
空闲期,即一个数据多久没被访问将从缓存中移除的时间。
Cache API及默认提供的实现
Spring提供的核心Cache接口:
package org.springframework.cache; public interface Cache { String getName(); //缓存的名字 Object getNativeCache(); //得到底层使用的缓存,如Ehcache,redis ValueWrapper get(Object key); //根据key得到一个ValueWrapper,然后调用其get方法获取值 <T> T get(Object key, Class<T> type);//根据key,和value的类型直接获取value void put(Object key, Object value);//往缓存放数据 void evict(Object key);//从缓存中移除key对应的缓存 void clear(); //清空缓存 interface ValueWrapper { //缓存值的Wrapper Object get(); //得到真实的value } } |
spring 默认提供了如下实现:
concurrentMapCache:使用java.util.concurrent.ConcurrentHashMap实现的Cache;
GuavaCache:对Guava com.google.common.cache.Cache进行的Wrapper,需要Google Guava 12.0或更高版本
EhCacheCache:使用Ehcache实现
JCacheCache:对javax.cache.Cache进行的wrapper
...
另外,因为我们在应用中并不是使用一个Cache,而是多个,因此Spring还提供了CacheManager抽象,用于缓存的管理
package org.springframework.cache; import java.util.Collection; public interface CacheManager { Cache getCache(String name); //根据Cache名字获取Cache Collection<String> getCacheNames(); //得到所有Cache的名字 } |
默认提供的实现:
ConcurrentMapCacheManager/ConcurrentMapCacheFactoryBean:管理ConcurrentMapCache;
GuavaCacheManager;
EhCacheCacheManager/EhCacheManagerFactoryBean;
JCacheCacheManager/JCacheManagerFactoryBean;
另外还提供了CompositeCacheManager用于组合CacheManager,即可以从多个CacheManager中轮询得到相应的Cache
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager"> <property name="cacheManagers"> <list> <ref bean="e |