【问题标题】:PHP Memcached keys and incrememnting version numbers to invalidate cache - How?PHP Memcached 键和递增版本号使缓存无效 - 如何?
【发布时间】:2011-12-08 20:05:44
【问题描述】:

我开始向我的应用程序添加一个 memcached 层。到目前为止一切顺利。

然而,我很快意识到,当有人将文件上传到网站时,我需要一次性使大量密钥无效/删除,以保持数据的相关性。

我已经阅读了一些内容,解决此问题的最常见方法似乎是在每个密钥上设置一个版本号,而不是在用户上传时删除密钥(因为可能有很多排列)你增加版本号,下次访问数据时会导致缓存未命中。

我不知道从哪里开始进行编码,而且我不太确定我是否完全理解它。

我的代码目前如下所示:-

$memcache = new Memcache;


$memcache->connect('localhost', 11211) or die ("Could not connect");


$key = md5("songsearch_$textSearch.$rangeSearch");

上面的键 var 中的两个变量是从 get 请求中检索出来的,而 get 请求又会检索大量的 JSON。 (想想产品目录)。

这些变量还决定了查询本身,该查询根据这些变量动态组合在一起。最终,所有这些都为我提供了一个对每个单独的查询都是唯一的键,即使从同一个脚本中我可以生成数百个键。

我希望以上内容很清楚,如果没有,请让我澄清任何要点,以便更好地帮助您回答我的问题。

显然稍后,我正在使用这个设置缓存结果:-

$memcache->set($key, $output, MEMCACHE_COMPRESSED, time() + 24*60*60*365);

就在我对 JSON 进行编码之前。

所以我的问题真的是......我如何添加某种形式的增量版本控制,以便如果用户上传文件,我可以使该脚本生成的所有密钥无效?

非常感谢任何让我至少走上正轨的人。

【问题讨论】:

  • 糟糕的是,内存缓存不允许您删除通配符。只需刷新与某个常量键前缀匹配的所有缓存条目就很容易了; cache_key_related_to_group_of_values*
  • 我完全同意... 会使其功能更强大/更易于使用。 :-(

标签: php memcached libmemcache


【解决方案1】:

你显然是在正确的轨道上。您唯一缺少的东西:在内存缓存中存储一​​个版本号,您可以在构建密钥之前检索该版本号。

$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

// fetch the current version number
$version = $memcache->get('version_number');

// and add the version to the key
$key = md5("songsearch_$textSearch.$rangeSearch") . 'v' . $version;

所以现在,每当有人上传新内容时,您只需增加版本号:

$memcache->increment('version_number');

这会自动导致所有现有查询遇到无效条目。

为了简化访问,我建议您将其包装在一个新的 Memcache 处理程序类中(未经测试):

class VersionedMemcache extends Memcache {

    const VERSION_KEY = 'version_number';

    private $version = 1;

    public function __construct() {
        $version = parent :: get(self :: VERSION_KEY);
        if ($version === false) {
            $version = 1;
            $this->set(self :: VERSION_KEY, $version);
        }
        $this->version = $version;
    }

    public function get($key, &$flags = null) {
        $key = $key . '_v' . $this->version;
        return parent :: get($key, $flags);
    }

    public function incVersion() {
        $this->version = $this->increment(self :: VERSION_KEY);
        return $this->version;
    }

}

所以现在,您只需将脚本修改为:

$memcache = new VersionedMemcache();

$memcache->connect('localhost', 11211) or die ("Could not connect");

$key = md5("songsearch_$textSearch.$rangeSearch");

// this will now result in a fetch on 'ab23...232afe_v1' instead of 'ab23...232afe'
$result = $memcache->get($key);

// when an upload happens, simply
$memcache->incVersion();

【讨论】:

  • 绝妙的回答伙伴。您通过一些出色的示例代码和出色的描述详细介绍了所有内容。非常感谢!
  • 哇,我只是在浏览一些有趣的问题,所以这是迄今为止最有趣/最有力的答案,我遇到了一段时间,我学到了很多!
【解决方案2】:

你可以保存一个数组并避免键地狱。

【讨论】:

  • 感谢 sathia 的建议。我对使用 memcached 很陌生,所以我想知道您是否可以详细说明您的答案。我不太确定这将如何帮助或如何实现它。谢谢!
  • 嗨,我只是建议您可以使用单个键并在其上保存一组键 => 值,在这种情况下,您可以使单个键无效,它会反映到所有键/values 里面。我看到这样的开销要少得多,而且它是透明的(全部由 php 的 memcache 库处理)
  • 其实这是一个非常好的主意!我有 Cassy 的解决方案并且现在正在运行,他的回答质量非常好。但这是一个很好的提示,并且肯定会成为我将使用的方法。非常感谢。
猜你喜欢
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多