管理缓存失效

时间:2009-11-10 20:08:00

标签: caching

只是想知道你们如何管理缓存失效。鉴于缓存中可能存在可能由不同算法或规则触发的对象(数百和数千)。你如何跟踪这一切?

无论如何,您是否可以从数据库中的表中引用关系并以某种方式强制执行它?

请耐心等待,因为我之前从未做过任何缓存。

7 个答案:

答案 0 :(得分:12)

缓存层的目的应该是:反映数据库中的相应数据,但提供的速度比数据库快,或者至少提供它而不会使数据库忙碌。

要实现这一目标,您有两种解决方案:

  1. 了解您在缓存中存储的所有内容的确切生命周期
  2. 使您的缓存与数据库保持同步
  3. 第一种非常罕见,但很容易处理:只需定期更新缓存。

    第二点是您最有可能在项目中处理的问题:只需在更新数据库时更新缓存。这比你想象的要简单:

    • 在成功将新对象添加到数据库后立即将新对象添加到缓存中。
    • 在数据库中成功更新对象后立即更新缓存中的对象。
    • 在数据库中成功删除对象后立即从缓存中删除对象。

    如果您的代码足够干净,那么应该很容易在其上实现有效的缓存策略。关于缓存以及如何在that answer I posted some times ago中做得更好。希望这一切都能帮到你:)。

答案 1 :(得分:10)

正如您似乎已经解决的那样,它并不像新闻报道更新时更新新闻报道的缓存那么简单。还有其他关系,例如,您需要更新的最新新闻报道列表。

最简单的方法是关联所有相关的对象。我之前使用过缓存组的概念。继续我的新闻示例,在缓存组'news'中将是;新闻报道,各种新闻报道和其他任何包含新闻报道的清单。

当我编辑新闻报道时,系统会识别出需要更新缓存组'新闻'并完成以下过程......

  1. 在保存更新之前获取每个对象
  2. 保存
  3. 再次获取对象,如果是不同的更新,各种缓存
  4. 当然,这是一个非常简单的例子。更简洁的方法是编写代码以始终维护对象,就像它在缓存中一样。

    如果您在新闻文章中添加标签,您可以将这些更改写入数据库,但如果您更新新闻文章对象和相关标签对象,这两个对象都可以“知道”它们已经更改(简单设置为hasChanged = true),然后您可以更新缓存并自动保存到数据库。

答案 2 :(得分:3)

如果您使用的是SQL Server 2005或更高版本以及.NET,则可能需要考虑使用SQLDependency class。这个类的作用是使用SQL Server Service Broker在您的数据发生某些修改时通知您。您可以将此作为触发器来使缓存无效。同样,这仅适用于您使用这些技术的情况。

答案 3 :(得分:3)

如果您的实体密切相关,并且您需要在相关实体的任何部分发生变化时更新缓存,最好的方法是将其构建为

如果obj B是obj A的外键并且A的某些属性发生了变化,则还需要更新B的缓存。

使用基于树的结构,如果识别出“分支”中的更改,则更新所有“叶子”的缓存。或者,如果更新“root”,则更新所有“分支”的缓存+“离开”。思考等级。

答案 4 :(得分:2)

See this article及相关的Stack Overflow question

通常,缓存失效可能相当棘手,尤其是在更新缓存对象时。

答案 5 :(得分:0)

对于一般解决方案,您可以查看Juha提供的链接。

但是关注你的问题,我想描述一下,我们的项目是如何完成的 我们不对缓存使用任何通用解决方案。我们的缓存最终增长。最初我们根本无意使用缓存。但后来缓存诞生了。随着缓存最近被添加到系统中,它不知道任何“数据库”或其他“智能东西”。相反,我们仔细检查是否有人更改了缓存。所以,我称我们的缓存为“算法驱动”。

(唯一真正必要的一般是处理缓存中未命中的功能 值得关注的另一件事是与客户识别:如果你有多个客户端,一个缓存可能不够......但对于这两个问题,只添加了特定的解决方案,而不是一般的!)

我知道,描述这样一个基本功能可能听起来很傻。有人可能会说“我们必须首先使用普通缓存”。但是你知道,实际上有时候有些东西是你无法控制的,你只需要做到最好。

总结一下:我们不需要一般解决方案。我们的算法控制缓存。这使缓存保持较小(在运行时在代码和内存中)。这是我们的方法。

答案 6 :(得分:0)

  

只是想知道你们如何管理缓存失效。鉴于缓存中可能存在可能由不同算法或规则触发的对象(数百和数千)。你如何记录这一切?

我不确定清楚这一部分,但我认为你应该定义不同的"regions"(就像在Hibernate术语中一样),每个都有自己的内容和规则。

  

无论如何,您是否可以从数据库中的表引用关系并以某种方式强制执行它?

在我看来,持久层是最好的地方,因为它知道持久性和潜在缓存实体正在发生的事情。例如,Hibernate支持(第二级)caching并允许定义二级缓存区域的名称,每个实体的缓存策略(只读,读写,非严格读写,事务) 。 Hibernate实际上定义了一个接口,并允许根据您的需要(缓存类型,支持的策略,群集支持)插入缓存实现。

  

请耐心等待,因为我之前从未做过任何缓存。

根据您需求的复杂程度,这可能不是一项简单的任务。也许你应该使用或查看现有的解决方案。在Java世界中,EHCacheOSCacheSwarmCacheJBoss Cache 2 无效缓存(或支持它)。这只是一个建议,因为你没有提到任何语言。