用于缓存相关数据的模式

时间:2010-09-29 07:25:39

标签: php database caching cakephp scalability

我目前正在开发应用程序的基础,并寻找优化性能的方法。我的设置基于the CakePHP framework,但我相信我的问题与任何技术堆栈相关,因为它与数据缓存有关。

让我们看一个典型的作者后关系,它由我的数据库中的2个表表示。当我在数据库中查询特定的博客文章时,同时CakePHP中的内置ORM功能也会获取帖子的作者,帖子上的评论等等。所有这些都作为一个大屁股嵌套数组返回,我使用相关博客文章的唯一标识符存储在缓存中。

更新博客文章时,要删除帖子的缓存是儿童游戏,并在下次请求时重新生成。

但是当主要实体(在这种情况下是博客文章)没有得到更新时会发生什么,而是一些相关数据呢?例如,可以删除评论,或者作者可以更新他的化身。是否有任何方法(模式)可用于跟踪相关数据的更新,并相应地将更新应用于我的缓存?

我很想知道你是否也遇到了类似的挑战,以及你是如何设法克服障碍的。如果您正在使用另一个堆栈,请随意提供一个抽象的视角。无论如何,您的意见非常感谢,非常感谢!

2 个答案:

答案 0 :(得分:2)

相当简单,缓存条目可以是

  • 加入
  • 破坏

当相关数据发生变化时,您应该注意销毁缓存条目(因此在应用程序层中除了更新数据之外,您还应该在更新某些表时销毁某些类型的缓存条目;通过对其进行硬编码来跟踪依赖关系)。

如果你想要聪明一点,你可以让你的缓存对象说明他们的依赖关系并缓存数据库表的最后更新时间。

然后你可以

  • 获取缓存数据,检查依赖项,
  • 获取相关数据库表的更新时间和
  • 如果记录是陈旧的(您的大屁股缓存条目所依赖的表的更新时间晚于缓存条目的时间)将其丢弃并从数据库中获取新数据。

您甚至可以将上述内容集成到持久层中。

修改
当然,上述内容适用于您希望拥有一致缓存的时间。有时,对于某些数据,您可以放松一致性要求,并且在某些情况下,简单的TTL就足够了(对于一个简单的例子,如果你有1秒的ttl,你应该主要是没有用户的麻烦,可以帮助数据处理;以及更高的时间你可能仍然没问题 - 例如,假设你正在缓存国家ISO代码列表;如果你说让我们缓存86400秒你的应用程序可能完全没问题)

此外,您还可以跟踪呈现给用户的信息的时间,例如

  • 假设用户已从缓存中看到数据A,并且我们知道此数据是在时间t1创建/修改的
  • 用户对数据A进行更改(并使其成为数据B)并提交更改
  • 然后,应用程序层可以检查数据A是否仍然像DB一样(如果用户做出决定和/或更改的缓存数据确实是新鲜的)
  • 如果新鲜,则存在冲突,用户应确认更改

这需要从DB中额外读取数据A的成本,但它仅在写入时发生。 此外,冲突不仅可能因为缓存而发生,还因为多个用户试图更改数据(即它与锁定策略有关)。

答案 1 :(得分:1)

memcached的一种方法是使用标签(http://code.google.com/p/memcached-tag/)。例如,你有你的Post“big-ass嵌套数组”,比方说,它包括autors信息,帖子本身,并显示在首页和侧边栏的某个框中。因此它获取标签:frontpage,{auhothor-id},侧边栏,{post-id} - 现在如果有人更改了作者信息,则使用标签{author-id}刷新每个缓存条目。但那仅仅是一个解决方案,仅适用于支持标签的缓存后端,例如不支持APC(afaik)。希望这给了你一个榜样。