关于缓存
缓存是实际工作中非常常用的一种提高性能的方法。而在java中,所谓缓存,就是将程序或系统经常要调用的对象存在内存中,再次调用时可以快速从内存中获取对象,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。
在增删改查中,数据库查询占据了数据库操作的80%以上,而非常频繁的磁盘I/O读取操作,会导致数据库性能极度低下。而数据库的重要性就不言而喻了:
- 数据库通常是企业应用系统最核心的部分
- 数据库保存的数据量通常非常庞大
- 数据库查询操作通常很频繁,有时还很复杂
在系统架构的不同层级之间,为了加快访问速度,都可以存在缓存
spring cache特性与缺憾
现在市场上主流的缓存框架有ehcache、redis、memcached。spring cache可以通过简单的配置就可以搭配使用起来。其中使用注解方式是最简单的。
Cache注解
从以上的注解中可以看出,虽然使用注解的确方便,但是缺少灵活的缓存策略,
缓存策略:
- TTL(Time To Live ) 存活期,即从缓存中创建时间点开始直到它到期的一个时间段(不管在这个时间段内有没有访问都将过期)
- TTI(Time To Idle) 空闲期,即一个数据多久没被访问将从缓存中移除的时间
项目中可能有很多缓存的TTL不相同,这时候就需要编码式使用编写缓存。
条件缓存
根据运行流程,如下@Cacheable将在执行方法之前( #result还拿不到返回值)判断condition,如果返回true,则查缓存;
- @Cacheable(value = "user", key = "#id", condition = "#id lt 10")
- public User conditionFindById(final Long id)
如下@CachePut将在执行完方法后(#result就能拿到返回值了)判断condition,如果返回true,则放入缓存
- @CachePut(value = "user", key = "#id", condition = "#result.username ne 'zhang'")
- public User conditionSave(final User user)
如下@CachePut将在执行完方法后(#result就能拿到返回值了)判断unless,如果返回false,则放入缓存;(即跟condition相反)
- @CachePut(value = "user", key = "#user.id", unless = "#result.username eq 'zhang'")
- public User conditionSave2(final User user)
如下@CacheEvict, beforeInvocation=false表示在方法执行之后调用(#result能拿到返回值了);且判断condition,如果返回true,则移除缓存;
- @CacheEvict(value = "user", key = "#user.id", beforeInvocation = false, condition = "#result.username ne 'zhang'")
- public User conditionDelete(final User user)
小试牛刀,综合运用:
- @CachePut(value = "user", key = "#user.id")
- public User save(User user) {
- users.add(user);
- return user;
- }
- @CachePut(value = "user", key = "#user.id")
- public User update(User user) {
- users.remove(user);
- users.add(user);
- return user;
- }
- @CacheEvict(value = "user", key = "#user.id")
- public User delete(User user) {
- users.remove(user);
- return user;
- }
- @CacheEvict(value = "user", allEntries = true)
- public void deleteAll() {
- users.clear();
- }
- @Cacheable(value = "user", key = "#id")
- public User findById(final Long id) {
- System.out.println("cache miss, invoke find by id, id:" + id);
- for (User user : users) {
- if (user.getId().equals(id)) {
- return user;
- }
- }
- return null;
- }
配置ehcache与redis
spring cache集成ehcache,spring-ehcache.xml主要内容:
- <dependency>
- <groupId>net.sf.ehcache</groupId>
- <artifactId>ehcache-core</artifactId>
- <version>${ehcache.version}</version>
- </dependency>
- <!-- Spring提供的基于的Ehcache实现的缓存管理器 -->
- <!-- 如果有多个ehcacheManager要在bean加上p:shared="true" -->
- <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
- <property name="configLocation" value="classpath:xml/ehcache.xml"/>
- </bean>
- <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
- <property name="cacheManager" ref="ehcacheManager"/>
- <property name="transactionAware" value="true"/>
- </bean>
- <!-- cache注解,和spring-redis.xml中的只能使用一个 -->
- <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
spring cache集成redis,spring-redis.xml主要内容:
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-redis</artifactId>
- <version>1.8.1.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-pool2</artifactId>
- <version>2.4.2</version>
- </dependency>
- <dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- <version>2.9.0</version>
- </dependency>
- <!-- 注意需要添加Spring Data Redis等jar包 -->
- <description>redis配置</description>
- <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
- <property name="maxIdle" value="${redis.pool.maxIdle}"/>
- <property name="maxTotal" value="${redis.pool.maxActive}"/>
- <property name="maxWaitMillis" value="${redis.pool.maxWait}"/>
- <property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/>
- <property name="testOnReturn" value="${redis.pool.testOnReturn}"/>
- </bean>
- <!-- JedisConnectionFactory -->
- <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
- <property name="hostName" value="${redis.master.ip}"/>
- <property name="port" value="${redis.master.port}"/>
- <property name="poolConfig" ref="jedisPoolConfig"/>
- </bean>
- <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
- p:connectionFactory-ref="jedisConnectionFactory">
- <property name="keySerializer">
- <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
- </property>
- <property name="valueSerializer">
- <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
- </property>
- <property name="hashKeySerializer">
- <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
- </property>
- <property name="hashValueSerializer">
- <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
- </property>
- </bean>
- <!--spring cache-->
- <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"
- c:redisOperations-ref="redisTemplate">
- <!-- 默认缓存10分钟 -->
- <property name="defaultExpiration" value="600"/>
- <property name="usePrefix" value="true"/>
- <!-- cacheName 缓存超时配置,半小时,一小时,一天 -->
- <property name="expires">
- <map key-type="java.lang.String" value-type="java.lang.Long">
- <entry key="halfHour" value="1800"/>
- <entry key="hour" value="3600"/>
- <entry key="oneDay" value="86400"/>
- <!-- shiro cache keys -->
- <entry key="authorizationCache" value="1800"/>
- <entry key="authenticationCache" value="1800"/>
- <entry key="activeSessionCache" value="1800"/>
- </map>
- </property>
- </bean>
- <!-- cache注解,和spring-ehcache.xml中的只能使用一个 -->
- <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
项目中注解缓存只能配置一个,所以可以通过以下引入哪个配置文件来决定使用哪个缓存。
当然,可以通过其他配置搭配使用两个缓存机制。比如ecache做一级缓存,redis做二级缓存。
更加详细的使用与配置,可以参考项目中spring-shiro-training中有关spring cache的配置。
相关推荐
本篇文章将深入探讨关于缓存的一些核心概念、工作原理以及在ASP.NET中的应用。 首先,我们要理解缓存的基本原理。缓存是一种存储机制,它临时存储经常访问的数据,以便快速获取。当一个请求到达时,系统会首先检查...
关于缓存的一点心得 一、缓存的基本概念与分类 缓存技术是现代软件开发中提高系统性能的重要手段之一,特别是在Web应用中扮演着关键角色。根据存储内容的不同,缓存可以分为两大类:页面缓存和数据缓存。 1. **...
【JavaEye的Boss分享关于缓存的理解】 缓存是一种关键的技术,它在现代软件系统中扮演着提升性能和效率的角色。JavaEye的Boss在分享中深入浅出地讲解了缓存的基本概念及其在不同层次的应用。 首先,缓存是高速缓冲...
面试官询问关于缓存算法及其作用时,面试者更是无法回答,显示出对缓存算法的基本概念和应用缺乏了解。 命中率是指访问缓存时成功获取数据的次数与总访问次数的比例。命中率越高,说明缓存效果越好,能够有效减少对...
除了直接访问文件,还可以使用InternetExplorer对象来获取关于缓存的更多信息,例如通过History或Favorities集合。但这种方式需要更深入的COM交互,涉及到ActiveX控件和Automation。 需要注意的是,读取用户缓存...
`item.c/h`文件包含了关于缓存项的数据结构和管理逻辑。 5. **并发与线程安全** Memcached是单线程的,但为了处理多个客户端请求,它使用事件驱动模型,如libevent库,以非阻塞方式处理I/O。源代码中的`event.c/h`...
缓存的实现,我只是选择了实现文件,相信.h文件大家一眼也能看出如何写来了,小弟就不多废话了。
其中包含了一系列关于缓存管理和数据更新的高级特性。 ##### 3.1 内存占用 在设计缓存系统时,内存占用是一个必须考虑的关键因素。不当的内存管理会导致资源浪费甚至引起系统崩溃。NCV5提供了一些机制来帮助开发者...
【标题】"MyNopCommerce(不删,006_清理缓存)"涉及的是针对开源电子商务平台NopCommerce的反向工程与优化过程,尤其是关于缓存清理的部分。NopCommerce是一个基于ASP.NET MVC技术的成熟电子商务解决方案,它利用缓存...
在Java面试中,缓存是经常被讨论的重要话题,因为它在...以上内容详细阐述了Java面试中关于缓存的常见问题及其解答,涵盖了缓存的基本概念、实现、策略、问题及解决方法,有助于理解和掌握缓存技术在实际项目中的应用。
- 对于希望深入学习缓存机制及流媒体技术的读者,可以参考W3C关于缓存控制规范的文档以及MPEG-DASH等流媒体标准的相关资料。 - 另外,对于视频编码感兴趣的朋友,可以进一步了解H.264、H.265等视频编码格式及其工作...
关于缓存的实现,文档提到了各种缓存策略,比如“FIFO”(先进先出),“LFU”(最不经常使用)以及“LRU”(最近最少使用)。这些策略用于管理缓存数据,决定哪些数据应该被保留以及哪些应该被淘汰。例如,LRU缓存...
在这些目录中,你可能会找到关于缓存实现的源代码、配置文件、文档等资源,通过深入研究,可以更具体地了解该项目的实现细节。 总之,C#实现的分布式缓存系统是一个复杂且重要的技术领域,涉及到多个层面的设计和...
3. **缓存层级**:在复杂的应用场景下,可以建立多级缓存体系,如浏览器缓存、本地缓存、服务器缓存和分布式缓存等,形成缓存链路,根据数据的热度和访问频率动态调整数据在不同层级之间的存储位置。 #### 结论 ...
此外,还探讨了缓存的高级话题,如缓存头字段、缓存与性能的关系,以及如何在面试中回答关于缓存的问题。 适用人群: 本博客主要面向网络技术初学者,特别是那些对浏览器缓存和HTTP缓存机制感兴趣,希望能够在面试中...
7. **配置 Shiro**:在不自定义缓存的情况下,Shiro 的配置文件(如 `shiro.ini` 或 `Java配置类`)通常会缺少关于缓存的相关设置。开发者可以通过添加 `cacheManager` 配置项来指定自定义缓存实现。 总结,"shiro-...
在IT行业中,缓存机制是优化...通过深入研究SimpleCache项目,我们可以掌握更多关于缓存设计和优化的知识,这将对我们的Java编程和系统优化能力大有裨益。同时,源码参考也是提升自身编程技巧和理解复杂系统的好途径。
关于 缓存依赖
此外,还探讨了缓存的高级话题,如缓存头字段、缓存与性能的关系,以及如何在面试中回答关于缓存的问题。 适用人群: 本博客主要面向网络技术初学者,特别是那些对浏览器缓存感兴趣,希望能够在面试中表现出色的人。...