管理键(在 memcache 中)以防止过时的缓存值的最佳方法是什么?

2022-08-31 01:03:56

我最近在我的网站上实现了memcache,它一直处于重的mysql负载下(mysql尽可能地优化)。它解决了我所有的加载问题,网站运行得很好。

我现在面临的问题是过时的缓存值。我在大多数页面上都有1小时的自动过期时间,并且当DB chnage中的值时,我也删除了密钥,但是我很难跟踪并有效地清除所有密钥。

在某些页面上,它是微不足道的。我可以使密钥item_id(例如item_4653),当更新它的数据或删除项目时,密钥将被清除。

但是在大多数页面上,我采用脚本文件名+查询字符串,md5 it,并将其用作memcache中的键。这对于复杂的URL(非常常见)特别有用。

例如,我加载了以下页面。

index.php?search_keywords=good&search_section=1&sort=release&page=2

它将包含一个项目列表,这些项目将从memcache中获取。然后,另一个用户提交一个项目,该项目的标题中包含“”,并且它恰好在值范围内,它将出现在第2页上,除了它不会出现在那里,直到刷新缓存。更复杂的是,新添加的项目也将出现在索引.php?sort=latest,以及索引.php?category=some_category?page=1等。其中每个 1 个都有一个唯一的键(脚本名称 + 查询字符串的 md5)。

因此,如果从实时数据库获取新添加的项目,则它们可能会出现在数十个页面上,但在更新过时的缓存之前,它在任何页面上都不可见。唯一的选择是等待项目自动过期。

这个问题在我的论坛(自定义编码)上变得更加明显,其中所有可能的缓存页面组合的值都必须按需更新。假设我有4页线程,我注意到第2页上有3个垃圾邮件帖子。删除它们后,将重建页面 2,但随后还必须重新生成页面 3 和 4,否则在新建页面 2 和旧页面 3 上将出现重复的帖子。这只是一个例子.....有几十种这样的场景。

有什么想法吗?


答案 1

由于您要在 memcached 中缓存整个页面,因此您的页面无法相互共享数据库中的缓存数据。假设我有 page1.php 和 page2.php,其中 page1page2 是 memcached 中的键。两个页面都显示项目。我添加了一个新项目。现在我必须使第1页和第2页过期。

相反,我可以在 memcached 中有一个 items 键,即 page1.php 和 page2.php都用于显示条目。当我添加新项目时,我会使 items 键过期(或者更好的是更新它的值),并且 page1.php 和 page2.php都是最新的。

如果仍要缓存整个页面,则可以向键中添加信息,这些信息在缓存的数据更改时会更改(如果数据更改太频繁,则这没有意义)。例如:

"page1:[timestamp of newest item]"

通过这种方式,您可以查找最新项的时间戳,这是一个廉价的查询,并使用它构建缓存键。添加较新的项后,缓存键将更改,自动过期。此方法意味着您仍然必须点击数据库才能查看每次最新项的时间戳是什么。


答案 2

Memcached::set 有一个 expire 参数。也许您可以将其默认值设置为一小时,但对于返回搜索结果的页面 - 或者在您的论坛中,您可以将其设置为较短的时间段。


推荐