12

我们基本上使用 memcache 来缓存查询结果。

由于其实施方式,失效是一场噩梦。从那以后,我们通过阅读邮件列表学习了一些使用 memcache 的技术,例如允许一组密钥组失效的技巧。知道的可以跳过下一段。。

对于那些不知道但感兴趣的人,诀窍是在您的密钥中添加一个序列号并将该序列号存储在 memcache 中。然后每次在你做你的“获取”之前,你都会抓住当前的序列号并围绕它构建你的密钥。然后,要使整个组无效,您只需增加该序列号。

所以无论如何,我目前正在修改我们的模型来实现这一点。

我的问题是..

我们不知道这种模式,我敢肯定还有其他我们不知道的。我已经搜索并且无法在网络上找到任何用于实现 memcache、最佳实践等的设计模式。

有人可以指出我这样的事情,甚至只是写一个例子吗?我想确保我们在新的重构中不会犯初学者的错误。

4

5 回答 5

15

对象缓存要记住的一点是,它就是对象/复杂结构的缓存。很多人错误地为直接、高效的查询而命中缓存,这会导致缓存检查/未命中的开销,而数据库本来可以更快地获得结果。

这条建议是我自从教给我以来就牢记在心的一条建议;知道什么时候不缓存,也就是说,当开销抵消了感知的好处时。我知道它没有回答这里的具体问题,但我认为值得指出作为一般提示。

于 2008-11-27T01:55:38.133 回答
6

rob 说的是好建议。根据我的经验,有两种常见的方法来识别和失效标签:唯一标识和基于标签的标识。这些通常组合在一起形成一个完整的解决方案,其中:

  1. 缓存记录被分配一个唯一标识符(通常以某种方式取决于它缓存的数据)和任意数量的标签。
  2. 缓存记录由其唯一标识符调用。
  3. 缓存记录可以通过其唯一标识符(一次一个)或任何标记它们的标签(可能同时使多条记录无效)来失效。

这实现起来相对简单,通常效果很好。我还没有遇到需要更多系统的系统,尽管可能存在一些需要特定解决方案的边缘情况。

于 2008-11-27T02:06:20.203 回答
3

我使用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;

}

将缓存键基于查询的哈希意味着如果另一个开发人员绕过我的模型或在其他地方使用另一个函数来做同样的事情,它仍然会从缓存中提取。通常我用一对生成标记标记缓存(表的名称是一个,另一个是函数的名称)。因此,默认情况下,我们的代码在插入、删除和更新带有表标签的缓存项时无效。总而言之,缓存在我们的基本代码中是非常自动化的,开发人员可以确保缓存在我们所做的项目中“正常工作”。(使用标记还有一个很大的副作用是我们有一个页面,它提供了细粒度的缓存清除/管理,可以选择通过模型函数或表来清除缓存)。

于 2008-11-27T04:16:01.300 回答
1

我们还将数据库(PostgreSQL)的查询结果存储在 memcache 中,并且我们在表上使用触发器来使缓存无效 - 那里有几个 API(例如pgmemcache,我认为 mysql 也有类似的东西,但我没有肯定知道)。好处是数据库自身(触发器)可以处理更改(更新、插入、删除)时数据的失效,您无需将所有这些内容写入您的“应用程序”。

于 2008-11-27T17:50:55.100 回答
0

mysqlnd_qc,它在数据库查询结果返回级别插入 memcaching,自动缓存来自 mysql 的结果集。它非常棒,而且是自动的。

于 2011-02-21T14:08:14.527 回答