========================== 困扰和痛苦多时的oscache刷新缓存start =======================
Everyday都不同于2015-9-19 周六15:30
【前言】一般而言,oscache缓存常用于在高并发的情形下。当你初次调用缓存的方法时,如果缓存中还没有响应的key,则会去执行底层的sql语句,并把结果缓存起来。等到【下次】你再调用缓存的方法时,如果传入的是与【这次】”同样“的key(当然不同样的key是会去查库的,并把此次不一样的key对应的查询结果同样地给缓存起来,以此类推。),则会去直接从缓存中取出【这次】缓存好的结果。而不必再去连接数据库执行sql语句了。减少与数据库的交互是oscache缓存的一大作用,频繁的连接数据库但查询的结果都一样可不是什么好事儿。
上述的缓存原理大致的可表示为(涉及oschche jar包,需先导入)
import com.opensymphony.oscache.general.GeneralCacheAdministrator; //………………………………………………………………………………………… GeneralCacheAdministrator oscache; //通常由spring注入 public void setOscache(GeneralCacheAdministrator oscache) { this.oscache = oscache; } //定义一个从缓存里根据key取缓存结果的方法 //………………………………………………………… //如果直接传入的key是null或空的,直接返回null; //………………………………………………………… //先尝试从缓存里取,取到了直接从缓存拿结果返回即可; //………………………………………………………………………… //取不到则从库里取,如果从库里取到了结果,则把结果缓存起来,再把结果返回 //……………………………………………………………………………… }
其中,取缓存的语法是:
Object obj = osCache.getFromCache(key)
保存结果到缓存的语法是:
oscache.putInCache(key, obj);
到这儿,我们会一般认为缓存算是真正用起来了。但是,往往容易忽视一个比较重要的东西,那就是——刷新缓存。
从缓存里取东西对应于”查“,但我们谁也不能保证缓存中某个key对应的数据永远是不变的。比如我们从缓存里取机器的信息。但万一某天增加了机器,或修改或删除了机器呢?我们如果还是直接从缓存里面拿原先的数据,则会跟现在最新的数据不同步,造成”滞后“的错误。这是很严重的!
所以除了查缓存,保存结果到缓存之外,我们也不能忽视:”刷新缓存“。
那我们应该怎么办呢?反编译oscache的jar包就会发现它提供了刷新缓存的语法:
oscache.flushEntry(key);
看起来简单吧,但事实上你key如果处理的不好,仍然很容易出错!
就拿刚才举的关于机器的例子来讲,假设你在db里面有1张对应于机器信息的表。你把查询结果放在一个list中,并用一个常量例如"servers"来作为缓存中的保存list的key。没问题,你可以直接用上述讲到的原理保存到缓存,取缓存;但别忘了,一旦你对该表有任何的修改增加或删除操作,记得要在对应的位置放入刷新缓存的方法:oscache.flushEntry("servers");
这样,当下一次调用上述自己封装的,从缓存取结果的方法时,重新进入【取不到则从库里取,如果从库里取到了结果,则把结果缓存起来,再把结果返回】逻辑分支。因为当你执行了oscache.flushEntry("servers");这行代码时,缓存得到了更新,该servers key就不再对应之前的结果了。自然而然的你此时尝试从缓存取不到结果了,所以又得重新查库,把最新的查询结果缓存起来并返回给你。
重点来了!上面说到的key比较好理解,就是一常量。但当你需要参数去查询缓存的时候呢?依然拿机器的例子来说:假设你现在需要根据机器的id以及机器的使用时间判断它是否还能使用(假设机器一个id可对应多个使用时间,机器id是不能随意删除的,因为它对应多个响应时间)(即是否还能使用由机器id和机器使用时间共同决定)。那你的key该如何设计呢?
(其实理解到这儿,我们不妨把第一种无需传过滤条件的缓存作为一种特殊的”父条件“。从这个角度来看,父条件一般是常量或是不能直接被修改的变量)
如果你把key设置为id + 使用时间。从缓存里取结果是可以的,相当于把id + 时间作为缓存的key,对应的使用状态作为value保存起来下次直接取就好了。但如果我修改了机器的使用时间呢?flushEntry(id + time)会生效吗?——答案是不会(本人亲测)。究其原因,time已经是一个新的值了,从而id + time这个key也跟之前的id+time这个key不同了。你不可能指望缓存直接flush一个新的Key吧!同样,增加一个机器的使用时间,time都是新的,更加不用说了;删除呢?删掉一个机器的使用时间,这个time这个都不存在啦,你更不可能去刷新一个不存在的key吧。
所以,在这种根据一个父条件(这里指机器id)的基础上,再根据一个子条件(这里指使用时间)去共同查询结果(即sql里会有这2个或多个需要过滤的条件,这里就考虑俩好了)的情形。我们必须只把父条件作为缓存的key,而子条件不能作为放入到key里面。因为子条件是可能被修改删除和增加的。刷新缓存的时候,它会重新从sql里取结果(此时sql的过滤条件仍然只能是父条件,子条件不能作为sql的过滤条件。具体原因可思考)。只刷新父条件,再次访问从缓存取的方法时,会进入Pojo的查询数据库的方法。
重点是我们如何在Pojo查询数据库并返回结果的方法里返回怎样的数据结构。比如举的这个例子里,你不妨把使用时间作为key,使用状态作为value,返回一个map。到时候你根据查询缓存的方法去取时,缓存的key依然是机器id,只不过取到的不是该机器id对应的所有使用状态信息罢了,结果是你再根据另一个取的条件time,用map.get(time)就好啦!——即你一旦flush了机器id这个缓存key之后,会得到的是一个”新的“以第2个过滤条件time作为key,对应使用状态作为value的map了。你再通过该map get一个新的time,值自然也出来了。当然,从db查询后返回结果情况的不同,数据结构的选择也不同,这是很重要的,决定了我们从缓存拿数据的效率。
总 而 言 之:
1)做缓存一般是在高并发的情形下,一般的增删改查做缓存没有意义;
2)不要只记得保存结果到缓存和从缓存取结果,还别忘记当有数据修改时,要刷新缓存,否则你拿到的缓存中的数据将会和数据库中最新的结果不同步;
3)查缓存和取缓存的key必须一致;当查询缓存的有过滤条件时,缓存所选择的key不能是”子条件“,而是不能直接做修改操作(包括增。删、改)的父条件。
====================== oscache刷新缓存理解end =======================
相关推荐
OSCache虽然不直接支持分布式缓存,但可以通过与其他分布式缓存服务(如Redis、Memcached)结合使用来实现。 总结起来,OSCache作为一款强大的缓存工具,为Java开发者提供了便捷的页面缓存功能。通过合理配置和编程...
标题与描述概述的知识点主要集中在oscache的使用及其在Java环境下的配置与实施。oscache是一种缓存机制,主要用于提高Web应用的响应速度和优化系统性能。以下是对这些知识点的详细解析: ### oscache简介 oscache...
- 编写Java代码:在Servlet或Controller中,使用osCache API进行缓存操作。 **5. 示例应用** 以下是一个简单的osCache在JSP页面中的应用示例: ```jsp <%@ taglib uri="http://www.opensymphony.com/oscache" ...
osCache是Java开发中常用的缓存框架之一,它主要用于提高应用程序的性能和效率,通过将数据存储在内存中,减少对数据库的访问。osCache不仅可以用于Web应用,也可以用于任何Java应用程序,支持集群环境,提供了丰富...
OsCache是Java应用程序中常用的缓存框架,它能够有效地提高应用程序的性能,通过将经常访问的数据存储在内存中,减少对数据库或其他数据源的访问,从而降低系统负载。本示例将通过一个天气预报Web服务的场景,详细...
- **清理缓存**:可以调用`OsCache.clear()`方法清空整个缓存,或者使用`OsCache.evict(key)`清除指定的缓存条目。 ### 4. osCache的高级特性 - **事件监听**:osCache允许注册监听器来处理缓存的添加、删除和更新...
【基于OSCache的页面缓存】是Web应用中一种有效的性能优化策略,它涉及到缓存技术、分布式系统以及系统开发等多个领域。OSCache是开源的Java缓存框架,能够帮助开发者实现高效的页面和数据缓存,从而降低数据库的...
- **JSP缓存**:使用OSCache的jsp cache标签,如`<oscache:cache>`,配置缓存时间、key等属性。 - **初始化缓存**:在应用启动时初始化缓存,可通过监听器或servlet实现。 - **缓存管理**:可以编程方式清除、...
它支持缓存对象、集合、Map等各种数据类型,并提供了缓存过期、刷新策略等高级特性。 二、osCache工作原理 1. 数据存储:osCache将数据存储在内存中的缓存区域,这些区域可以被细分为多个缓存,每个缓存有自己的...
3. 编写缓存逻辑:使用osCache提供的API进行缓存的插入、查询、更新和删除操作。 4. 集成到应用程序:根据应用场景,将osCache集成到业务代码中,如在数据库查询前后添加缓存处理。 5. 测试与优化:测试缓存效果,...
oscache,全称OpenSymphony OSCache,是一个广泛使用的开源Java对象缓存框架,它允许开发者将数据存储在内存中,以减少对数据库的访问,从而提升应用的响应速度。本文将深入探讨oscache的核心概念、工作原理以及如何...
1、OSCache是什么? 2、OSCache的特点 3、有关“用OSCache进行缓存对象”的研究
为了提高系统性能,通常会采用缓存技术来减少对数据库的直接访问,而OSCache就是一种广泛使用的开源缓存解决方案。本实例将介绍如何结合Hibernate和OSCache实现二级缓存,以优化应用程序的性能。 一级缓存是...
OSCache提供了多种缓存策略,包括LRU(Least Recently Used)最近最少使用、LFU(Least Frequently Used)最不经常使用等。这些策略可以根据不同的业务需求选择合适的实现,以优化内存使用。 此外,OSCache还支持...
OSCache 是一个广泛使用的开源缓存解决方案,尤其在Java应用中,它被JBoss, Hibernate, Spring等知名框架所支持。其主要特点是配置简单,适用于页面级别的缓存管理。以下是对OSCache配置和使用过程的详细说明: 1. ...
3. **缓存刷新与过期**:OSCache 提供了自动和手动两种方式来控制缓存的过期和刷新。自动过期可以通过设置时间戳或者访问次数来触发,而手动刷新则允许开发者根据业务需求来更新缓存内容。 4. **缓存同步**:在多...
总的来说,osCache提供了强大的缓存管理功能,通过合理的配置和使用,能够显著提升Java应用的性能。理解并掌握osCache的配置和使用方法,是优化系统性能、提升用户体验的关键步骤。在实际项目中,应根据业务需求调整...
首先,osCache的内存管理机制允许开发者设置缓存的最大大小,一旦达到设定值,它会根据预设的淘汰策略自动清理过期或最少使用的项。这有助于防止内存溢出,并保持系统稳定运行。 其次,osCache提供了多种缓存策略。...
总的来说,osCache是一个功能强大、易于使用的Java缓存框架,对于优化应用性能、减轻数据库压力具有重要作用。通过深入理解和合理利用osCache的各项特性,开发者可以构建出更加高效、稳定的应用系统。