我最近在我的网站上实现了memcache,它已经在重负载mysql(mysql已尽可能优化).它解决了我所有的负载问题,并且网站运行良好.
我现在面临的问题是过时的缓存值.我在大多数页面上有1小时的自动过期时间,而且当数据库中的值为时,我也删除了密钥,但是我很难跟踪并有效地清除所有密钥.
在某些页面上,它是微不足道的.我可以将密钥设为item_id(例如item_4653),当更新数据或删除项目时,密钥将被清除.
但是在大多数页面上,我使用脚本filename + querystring,md5,并将其用作memcache中的密钥.这对于复杂的URL(非常常见)特别有用.
例如,我加载了以下页面.
index.php?search_keywords = good&search_section = 1&sort = release&page = 2
它将包含一个项目列表,这些项目将从memcache中获取.然后另一个用户提交一个项目,其标题中包含" 好 ",它恰好在值的范围内,它将出现在第2页,除非它不会出现在那里,直到刷新缓存.更复杂的是,新添加的项目也将出现在index.php?sort = newest,以及index.php?category = some_category?page = 1等等.每个项目都有一个独特的key(脚本名称的md5 +查询字符串).
因此,新添加的项目可能会显示在几十个页面上,如果它们是从实时数据库中提取的,但在更新陈旧缓存之前,它们中的任何一个都不可见.唯一的选择是等待项目自动过期.
对于所有可能的缓存页面组合,我的论坛(自定义编码)上的这个问题变得更加明显,其中值必须按需更新.假设我有4页线程,我注意到第2页上有3个垃圾邮件帖子.删除它们后,第2页重建,但是它还必须重建第3页和第4页,否则新重建页面上会有重复的帖子2和旧页面3.这只是一个例子.....有几十个这样的场景.
有任何想法吗?
由于您在memcached中缓存整个页面,因此您的页面无法相互共享数据库中的缓存数据.假设我有page1.php和page2.php,其中page1和page2作为memcached中的键.两个页面都显示项目.我添加了一个新项目.现在我必须使page1和page2失效.
相反,我可以在memcached中有一个项目键,page1.php和page2.php都用于显示项目.当我添加一个新项目时,我使项目密钥到期(或更好,更新它的值),page1.php和page2.php都是最新的.
如果您仍想缓存整个页面,则可以向密钥添加信息,这些信息会在缓存数据发生更改时发生更改(如果数据更改太频繁,这将无济于事).例如:
"page1:[timestamp of newest item]"
这样,您可以查找最新项目的时间戳,廉价查询,并使用它构建缓存密钥.添加新项目后,缓存键将更改,自动过期.此方法意味着您仍然必须每次都按下数据库以查看最新项目的时间戳.