系统级信息Cache的实现

这篇Blog接着上篇Blog提出的场景进行解决方案的描述:
在一个信息列表中,每个信息的权限有多种情况,比如信息列表中存在A、B、C三条信息,各条信息的权限授予给了(guest,admin)、(guest)、(admin),这个时候要获取guest的信息列表,加入cache需要提高效率的地方就在于避免获取信息列表时需与数据库进行实时的查询,同时要注意,一般来说,系统的信息数据量会是比较的大。

在和江南白衣聊的时候他提出了oscache提供的cache:cache标签的解决方案,开始想了一下觉得不怎么可行,这也是因为自己对cache标签不熟的原因,后来去网上查了一下cache:cache标签的使用,看了后觉得对于解决上面的需求应该是可行的。
关于cache:cache标签的具体用法网上有很多文章,大家可以google查找,我这里主要讲讲它的实现思路,在使用oscache提供的这个标签主要是通过以下方法来实现的
<cache:cache>
          // jsp代码
</cache:cache>
中间的jsp代码表明需要被缓存的东西,cache标签还提供了key,refresh,time,duration等等属性,对于上面的需求我们通常想的方案都是做数据库级的缓存,避免频繁实时查询数据库,cache标签这种做法的想法却是从入口开始入手,缓存入口自然也就实现了所需要的效果。
要使用cache标签首先需要明确缓存的jsp代码页面是由哪些关键字可以唯一标识出来的,在上面的需求中我们可以得知可以根据用户Id+当前页数+访问的信息类型的ID来唯一标识该页面,那么我们就可以把这个作为cache的key(默认key为uri加上请求的参数),缓存的过期时间可以设为-1(也就是不过期),这个时候我们就得考虑当信息的权限以及信息的数量变更时缓存是得刷新的,通过refresh属性可以达到这个目的,可以建立一个singleton的类来标识哪些信息ID是需要更新缓存的,refresh属性则通过调用此singleton类来确定是否需要更新缓存,这样的情况下需求中所要的效果就实现了,在这种解决方案中我们需要做的就是在对信息进行管理时调用singleton类来标识此id是需要被更新缓存的,在页面上我们只需要定义出能够唯一标识出需缓存页面部分的唯一key(如果能够通过uri加上请求参数作为唯一标识的情况下就不用定义key了,不过在需要权限过滤的地方一般来说是需要自己定义key的,因为要获取当前的用户ID),调用singleton获取refresh的属性,之后加入cache:cache标签就搞定了。
其实从上面的解决方案中我们可以推测oscache标签的实现思路,非常的简单,和通常我们做缓存的思路都一样,只是它提供了对于缓存的一个很好的处理机制,那就是从入口下手,在第一次运行页面的时候,它通过将生成的html作为value缓存到对应的key中,第二次运行页面时它通过此key去获取html,如无此key则运行jsp代码,同理其实可以将它运行到很多系统的场景中。

ps: 在用了这种解决方案后确实不错,系统的性能提升了很多,现在刷新页面几乎就和刷新静态页面的效果完全相同。

posted on 2005-10-18 17:35 BlueDavy 阅读(1371) 评论(7)  编辑  收藏 所属分类: Java

评论

# re: 系统级信息Cache的实现 2005-10-18 21:51 Vinson

I don't think the jsp cache tag is a good solution to improve the performance. It will cause the maintainbility problem.

For an example, one drop down list may be shared among more than one pages. If the cache policy need to be changed, then all the page need to be changed.


Generally speaking, the drop down list is retrieved from database , and the web tier invokes some interface to get the data.

If interceptor (AOP) is applied to the interface , while the interceptor may cache data, then the cahe is transparent to the web as well to the biz tier. All the code related to the cache such as cache provider, cache policy.. is centrialized in the interceptor.  回复  更多评论   

# re: 系统级信息Cache的实现 2005-10-19 09:23 lizongbo

//one drop down list may be shared among more than one pages

oscache的cache是可以指定scope的,application,session,request随便选择。
  回复  更多评论   

# re: 系统级信息Cache的实现 2005-10-19 09:56 Vinson

The cache policy may comprise update policy, cache provider, enviction policy. it is not only the scope.  回复  更多评论   

# re: 系统级信息Cache的实现 2005-10-19 11:44 Programmer's Life

Many thanks to Vinson,I think that system cache can be divided into two side,one is backend data cache,the other is page cache or block cache.
Block cache just from the other view to solute the cache problem,i think the problem what u say can be soluted by oscache's key or the other view solution(such as decorator).  回复  更多评论   

# re: 系统级信息Cache的实现 2005-11-22 09:02 xuefeng

对于一个mvc结构的web应用,jsp的cache仅仅能cache jsp处理的一段代码,但是,对设计良好的应用来说,jsp仅仅是渲染结果,这个速度是非常快的,而在controller中执行的复杂操作如数据库查询速度是很慢的,只有cache这部分结果,才能真正提高速度。

因此我觉得jsp cache tag几乎没有什么用,除非把数据库操作的代码放在中间,只有在controller中直接用oscache才可能cache操作费时的结果如数据库查询结果。  回复  更多评论   

# re: 系统级信息Cache的实现 2005-11-22 09:17 Programmer's Life

... 是的,这个其实也是在MVC框架实现中的一个问题,呵呵,按照MVC来说,所有的页面显示都只是纯的显示而已,这个时候cache要做的话确实就象你说的一样,要在入口处做cache,这样才能起到效果。  回复  更多评论   

# re: 系统级信息Cache的实现 2005-12-09 22:33 Xuefeng

一个办法是在Controller中使用模版方法,把返回的Model缓存起来:

class TemplateController {

protected abstract String getKey();
protected abstract Model getModel(args);

public final handle(args) {
Model model = getFromCache(getKey);
if(model==null) {
model = getModel();
putCache(model);
}
return model;
}
}


  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

公告

 









feedsky
抓虾
google reader
鲜果

导航

<2005年10月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

随笔分类

随笔档案

文章档案

Blogger's

搜索

最新评论

阅读排行榜

评论排行榜