我们使用memcache基本上是一种事后的想法,只缓存查询结果。
由于它的实现方式,无效是一场噩梦。从那以后,我们通过阅读邮件列表学习了memcache的一些技术,例如,允许一堆键的组失效的技巧。对于那些知道它的人,请跳过下一段。
对于那些不知道并且感兴趣的人来说,诀窍是将序列号添加到您的密钥中,并将该序列号存储在memcache中。然后,每次你做你的“获取”之前,你抓取当前的序列号,并围绕它构建你的密钥。然后,要使整个组无效,只需增加该序列号即可。
所以不管怎样,我现在正在修改我们的模型来实现这一点。
我的问题是..
我们不知道这种模式,我相信还有其他我们不知道的模式。我已经搜索过了,但在web上找不到任何用于实现memcache、最佳实践等的设计模式。
有没有人能给我指点一下这样的东西,或者只是写个例子?我想确保我们在新的重构中不会犯初学者的错误。
发布于 2008-11-27 01:55:38
关于对象缓存,需要记住的一点是,它只是对象/复杂结构的缓存。很多人都会犯这样的错误:为了简单高效的查询而命中缓存,这会导致缓存检查/未命中的开销,而数据库本可以更快地获得结果。
自从有人教我这个建议以来,我一直把它放在心上;知道什么时候不缓存,也就是什么时候开销抵消了感知到的好处。我知道它没有回答这里的具体问题,但我认为它值得作为一般提示指出。
发布于 2008-11-27 02:06:20
罗伯说的是很好的建议。根据我的经验,有两种常见的方法来标识和使标签无效:唯一标识和基于标签的标识。这些通常组合在一起形成一个完整的解决方案,其中:
为缓存记录分配唯一标识符(通常取决于缓存的数据)和任意数量的标记(可选)。
这是相对简单的实现,通常工作得很好。我还没有遇到需要更多的系统,尽管可能有一些边缘情况需要特定的解决方案。
发布于 2008-11-27 04:16:01
我使用的是Zend Cache组件(如果需要的话,您不必使用整个框架,只使用zend缓存)。它抽象了一些缓存内容(它支持按“标签”对缓存进行分组,尽管memcache后端不支持该功能,我已经相对轻松地推出了自己对“标签”的支持)。因此,我对访问缓存的函数(通常在我的模型中)使用的模式是:
public function getBySlug($ignoreCache = true)
{
if($ignoreCache || !$result = $this->cache->load('someKeyBasedOnQuery'))
{
$select = $this->select()
->where('slug = ?', $slug);
$result = $this->fetchRow($select);
try
{
$this->cache->save($result,'someKeyBasedOnQuery');
}
catch(Zend_Exception $error)
{
//log exception
}
}
else
{
$this->registry->logger->info('someKeyBasedOnQuery came from cache');
}
return $result;
}将缓存键建立在查询的散列上意味着,如果另一个开发人员绕过了我的模型,或者在其他地方使用了另一个做同样事情的函数,它仍然会被从缓存中拉出。通常,我使用一对生成标记(表的名称是一个,另一个是函数的名称)来标记缓存。因此,默认情况下,我们的代码会在插入、删除和更新表的标签时使缓存的项失效。总而言之,缓存在我们的基础代码中是相当自动化的,开发人员可以放心,缓存在我们所做的项目中“就是有效的”。(使用标签的另一个很大的副作用是,我们有一个页面,它提供了细粒度的缓存清理/管理,可以选择通过模型函数或表来清除缓存)。
https://stackoverflow.com/questions/322709
复制相似问题