问题描述
我在使用 Memcache 时遇到了一个奇怪的问题。简短的描述是,我删除了一个键,结果另一个键被删除了。
这是使用 PHP Memcached,带有一个简单的包装类,因此我可以记录请求。 Memcached 配置在单个实例 (AWS Elasticache) 上,在测试用例期间整体使用率/流量非常低。
我们的 memcache 设计是延迟加载:当发生缓存 MISS 时,从其他地方加载数据,然后设置它。相关数据发生变化时显式删除。
这是我的测试用例中缓存交互的顺序:
[02-11 15:12:13] MemCache MISS for example.com:ProjectTree[1]/2_1/6
[02-11 15:12:13] MemCache set example.com:ProjectTree[1]/2_1/6
[02-11 15:12:27] MemCache delete example.com:ProjectTree/2_1/6
[02-11 15:12:27] MemCache delete example.com:ProjectTree/2_1_3_2/6
[02-11 15:12:37] MemCache MISS for example.com:ProjectTree[1]/2_1/6
[02-11 15:12:37] MemCache set example.com:ProjectTree[1]/2_1/6
[02-11 15:12:48] MemCache HIT for example.com:ProjectTree[1]/2_1/6
[02-11 15:12:57] MemCache delete example.com:ProjectTree/2_1/6
[02-11 15:12:57] MemCache delete example.com:ProjectTree/2_1_3_3/6
[02-11 15:13:04] MemCache MISS for example.com:ProjectTree[1]/2_1/6
[02-11 15:13:04] MemCache set example.com:ProjectTree[1]/2_1/6
[02-11 15:13:25] MemCache HIT for example.com:ProjectTree[1]/2_1/6
[02-11 15:14:14] MemCache HIT for example.com:ProjectTree[1]/2_1/6
以下是触发这些操作的操作:
- 我在 15:12:13 加载了页面(MISS 和 SET)。
- 我在 15:12:27 创建了一个新文件夹(两次 DELETE)。
- 我在 15:12:37 刷新了页面(MISS 和 SET)。
- 我在 15:12:48 (HIT) 再次刷新。
- 我在 15:57 添加了另一个文件夹(两个 DELETE)。
- 我在 15:13:04 再次刷新(MISS 和 SET)。
- 我在 15:13:25 (HIT) 再次刷新。
- 我在 15:14:14 (HIT) 再次刷新。
所有这些设置都包括 5 分钟的过期时间(300 秒)。整个测试用了 2 分钟,所以这不应该是一个因素(理论上)。
更令人费解的是,此代码和行为在大约 6 个以上的生产环境以及 10 个以上的开发/测试环境中是一致的。我们有一个测试环境,其中 memcache 操作按我的预期工作 - 删除 ProjectTree/2_1/6
和 ProjectTree/2_1_3_2/6
后,我们继续在 ProjectTree[1]/2_1/6
上获得 HIT。
public function delete($id)
{
return $this->deleteValue($this->generateUniqueKey($id));
}
protected function deleteValue($key)
{
return $this->_cache->delete($key,0);
}
protected function generateUniqueKey($key)
{
// Support sharing of Memcache/ElastiCache instance
// by multiple sites (multitenancy) by prefixing every key
global $gDomain;
// Memcache can't handle keys > 250 chars,but only hash longer ones
if (strlen($key) + strlen($gThisServer) + 1 >= 250)
$key = md5($key);
return $gDomain . ':' . $key;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)