【讨论】关于 主动式 缓存框架 思路的设想

红薯 发布于 2009/10/16 14:11
阅读 2K+
收藏 8

一般我们在使用缓存的时候,例如 EhCache,会设定一个缓存数据的有效时间,超过这个时间后缓存数据失效,应用必须重新填充缓存数据。

而在 Web 项目中更是如此,访问数据时先访问缓存,如果缓存中有,则返回缓存中的数据,否则重新读取(可能是从数据库中)数据并塞入缓存,然后返回数据。

假设这个重新读取数据的过程可能是一个非常耗时的过程,那么每次缓存失效的时候,用户访问就会非常的慢,再次访问速度才能变快。

问题的关键还在于,有些缓存你是无法主动通过代码去更新的。

那么能不能设计一个主动式的缓存框架,来解决这个问题呢?

我的思路是这样子的:

缓存系统分两块区域,分别是:主缓存区失效缓存区

1. 读取数据的过程是:首先读取主缓存数据,如果数据不存在,则读取失效缓存区的数据,如果数据再不存在才去读取数据库
2. 缓存的数据如果失效,则缓存系统自动将这个数据放到失效区
3. 在读取失效缓存区的数据之前或者之后,应用程序必须通知缓存系统去更新主缓存区的数据。
4. 采用 EhCache 来作为一般的缓存管理

难点在于第3点,缓存系统如何主动去更新主缓存区的数据?要避免缓存系统和应用系统之间的过密的耦合。

目前只是这么一个思路,希望大家一起讨论下。

因为目前 OsChina 就遇见了这个问题,会发现访问个人空间的时候可能会很慢,因为该页面的查询非常的多、非常的复杂,假设缓存失效会导致访问很慢。

 

加载中
0
JavaGG
JavaGG

问一个问题哦

如果分主缓存区失效缓存区 二种,那么是不是和延长缓存时间的效果是一样??

这样内存并没有减小,也一样会有读取数据库的时候

我觉得这个问题得从跟源处理

为什么我们的缓存要有失效时间呢???

这是因为我们的数据会更新,但如果当更新数据库时同时更新缓存,那么不就没有失效之说了

当然这样做有难度,呵呵

0
麦田小圈圈
麦田小圈圈

网站的缓存一般存在两种:一种是列表数据,另外一种是单条的详细数据

你说的页面查询非常多,其实很多是读取列表数据

所以网站应该把列表数据专门拿出来缓存。比如有人添加新闻的时候,你除了缓存这条新闻详细信息外,还要去更新最新新闻列表的缓存,然后才把这个新闻信息写入数据库。

你说的EhCache缓存数据的有效时间,其实最好不要设置有效时间,而是在添加数据的时候就去更新缓存,没有数据更新的时候,缓存就不让它失效。

这样你读取缓存数据的时候,总会读取到数据,而且是最新的。

0
红薯
红薯

引用来自“xiaog”的帖子

网站的缓存一般存在两种:一种是列表数据,另外一种是单条的详细数据

你说的页面查询非常多,其实很多是读取列表数据

所以网站应该把列表数据专门拿出来缓存。比如有人添加新闻的时候,你除了缓存这条新闻详细信息外,还要去更新最新新闻列表的缓存,然后才把这个新闻信息写入数据库。

你说的EhCache缓存数据的有效时间,其实最好不要设置有效时间,而是在添加数据的时候就去更新缓存,没有数据更新的时候,缓存就不让它失效。

这样你读取缓存数据的时候,总会读取到数据,而且是最新的。

并不是所有的缓存数据都是你可以更新的,如果非要更新的话,可能导致代码非常复杂。

举个例子:假设热门话题列表,这个东西你是无从更新的,只能依照缓存失效时自动更新,而且这个对实时性要求也不高。

0
麦田小圈圈
麦田小圈圈

在服务层你完全可以封装一个缓存层

所有更新操作都更新缓存,当然如果你现在的代码没有这么做,只是在DAO那层按逻辑缓存的话,改起来代码量确实很大。

0
红薯
红薯

引用来自“xiaog”的帖子

在服务层你完全可以封装一个缓存层

所有更新操作都更新缓存,当然如果你现在的代码没有这么做,只是在DAO那层按逻辑缓存的话,改起来代码量确实很大。

xiaog 显然没明白我帖子里的意思

0
I
IsapiCache

引用来自“红薯”的帖子

 

引用来自“xiaog”的帖子

网站的缓存一般存在两种:一种是列表数据,另外一种是单条的详细数据

你说的页面查询非常多,其实很多是读取列表数据

所以网站应该把列表数据专门拿出来缓存。比如有人添加新闻的时候,你除了缓存这条新闻详细信息外,还要去更新最新新闻列表的缓存,然后才把这个新闻信息写入数据库。

你说的EhCache缓存数据的有效时间,其实最好不要设置有效时间,而是在添加数据的时候就去更新缓存,没有数据更新的时候,缓存就不让它失效。

这样你读取缓存数据的时候,总会读取到数据,而且是最新的。

并不是所有的缓存数据都是你可以更新的,如果非要更新的话,可能导致代码非常复杂。

举个例子:假设热门话题列表,这个东西你是无从更新的,只能依照缓存失效时自动更新,而且这个对实时性要求也不高。

 支持在数据变动时更新缓存,在能更新缓存的地方就做更新处理,不能做的就保留原来的缓冲方式,主动式缓存没办法做到通用

主缓存区失效缓存区 没本质的区别

0
大东哥
大东哥

还真的不太懂您的意思,能不能具个实际碰到的问题,详细点的列出来,这样可能才会完全理解您的意思.才会讨论到要点上.

0
王全
王全

不知红薯说的是不是高并发下,同时访问一个失效缓存的情况?

如果是,可以使用block cache ,Ehcache已经提供了block cache!

Ehcache 的 Block cache只会block 指定的key,即,如果更新缓存比较耗时,同一个key高并发下也只有一个线程去更新.

至于提到的"3. 在读取失效缓存区的数据之前或者之后,应用程序必须通知缓存系统去更新主缓存区的数据。"。你通知缓存系统后,也不能立马拿到新的数据,前端的访问线程还是要等待

个人认为,失效缓存好像用处不大,数据既然失效了,即使你放到失效缓存区去了,你取出来的也是一个有问题的数据!

不能主动更新的缓存,最好不要设置过期时间,或者设置过期时间后,更新缓存的程序应该在过期前进行更新

0
红薯
红薯

已经在 oschina 项目上做了这个处理了,现在点击个人空间,除了第一次(主缓存和实效缓存区内都无数据时)可能会慢,以后都会很快了。

运行一段时间看看效果先。

0
寻找技术合伙人111

比较支持更新数据库的时候去更新缓存

觉得这可以理解成一个推与拉的过程,在后台更新时就是一个推的过程,通过用户的点击,这是一个拉的过程。

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部