如果在不提取值的情况下将值存储在Memcache中,如何检入PHP?我不喜欢抓取它,因为我设置的值都是1MB大小,在我获取它之后,我没有用它,所以我浪费资源。我在脚本中使用它来检查某些键是否缓存在memcache中,如果没有,它会从慢速数据源读取它们并将它们设置在memcache中。
修改:如果我使用Memcached::append
将NULL
附加到我正在检查的密钥上会怎样?成功时返回TRUE
或失败时返回FALSE
。如果密钥不存在,Memcached::getResultCode
将返回Memcached::RES_NOTSTORED
。这样我检查密钥是否存在,它应该把密钥放在LRU列表的顶部吗?
谢谢。
答案 0 :(得分:6)
我不确定这对你有什么帮助,但你可以使用
Memcache::add ( string $key , mixed $var)
如果密钥已经存在,它将返回false。
如果返回true,您可以使用
Memcache::delete ( string $key)
删除刚设置的密钥。这样你就不需要获取数据了。
答案 1 :(得分:5)
我想知道为什么Memcached没有特殊的方法。以下是我在考虑之后得出的结论:
function has($key)
{
$m->get($key)
return \Memcached::RES_NOTFOUND !== $m->getResultCode();
}
答案 2 :(得分:3)
基本上你想要做的就是用你的数据填充memcached,对吧?
问题是在没有检索值的情况下询问密钥是否存在并不是很有用。见这种情况:
您询问密钥是否存在且确实存在。在您询问之后,密钥的数据将从缓存中排除。虽然你的回复表明日期已经存在,但实际情况是数据不存在。所以你没时间问,因为答案与现实不同。
我想你想要做的是询问密钥是否存在,然后如果不存在,请填写您的数据。为什么不直接填写所有数据?顺便说一句,您是否考虑过在使用数据填充memcached时,您可能正在驱逐刚才插入的密钥?
答案 3 :(得分:3)
我通过使用Memcached :: append解决了这个问题。我尝试追加值NULL,如果返回TRUE,则表示密钥存在。如果返回FALSE则表示密钥不存在。如果密钥存在,它也会将它放在LRU列表的顶部。
答案 4 :(得分:2)
我不喜欢添加/删除建议,因为它会插入应用程序可能依赖的无效数据。如果您的应用程序确实做出了这个假设,那么由于它引入的竞争条件,它会导致一个经常发生的细微错误。
一个解决方案是查看值,如果它的临时数据假装它不在那里,但这需要所有应用程序代码使用相同的api,或者你需要更新应用程序本身,既不好玩又由于额外的复杂性,有些容易出错。
如果该组键足够小,您可以将其存储在memcached中并使用它来确定是否再次从源中检索数据。但是,如果它的值大或者更大,那么这个方法就更差了,只需从memcached中获取整个值。
然后你可以通过使用索引将你的密钥分成更小的集合来解决新问题(当然这是一种分析这些数据的好方法,因此每个存储桶都是一定的大小,然后就这么说了。)
实现将包括使用memcached append或prepend来维护与某些主密钥绑定的密钥列表或主密钥,这些密钥指向一组指向密钥本身的子密钥:)
无论哪种方式,你都会使应用程序变得越来越复杂,所以我只建议在确实存在瓶颈的情况下执行此操作(如果需要经常通过网络检查密钥存在),或者如果关注的可用性(延迟)。
在我的情况下,我不会这样做,因为我只会通过localhost访问memcached并将其用作我的应用程序的更多扩展,以缓存需要花费几秒钟才能正常加载的资源。
答案 5 :(得分:1)
根本不可能,不可能只检查密钥是否存在。 最好使用true / false值创建一个单独的键来检查键的存在
答案 6 :(得分:1)
<div class="main">
<div class="inside"></div>
</div>
在上面的记录中,我首先使用set命令设置值为12345的密钥hello。然后将其取回,这也返回了一个cas唯一的6743。 然后我尝试使用cas命令替换没有任何值,但因为我使用的cas唯一是0,我得到了EXISTS错误。
最后我尝试使用cas设置一个不存在的密钥foo并返回NOT_FOUND错误。
因为memcached对cas unique使用全局递增值,所以使用0是安全的,它对您尝试设置的项无效,如果它存在,您将收到EXISTS错误。
抱歉,不熟悉php的memcache客户端,将其放入php代码中。
答案 7 :(得分:0)
从Memcached的角度来看,这没有任何意义。如果你想避免缓慢的数据源(通过预定的作业,我推测?),将数据保存到预定作业中更快但仍然稳定的数据源(例如文件)。当您需要数据时,首先尝试从Memcached读取,如果失败则读取文件并将其保存到Memcached中。
Memcached无法给你一个好的答案,因为pakore已经回答了。该架构并不意味着是一个稳定的数据源。
答案 8 :(得分:0)
最简单的方法是获取给定的密钥并将其转换为布尔值。
(bool) Memcache::get(string $key)
答案 9 :(得分:0)
(讨论稍晚,但是)实际上你可以访问存储在memcache中的所有键/值,按:
$allSlabs = $memcache->getExtendedStats('slabs');
$items = $memcache->getExtendedStats('items');
foreach ($allSlabs as $server => $slabs)
foreach ($slabs as $slabId => $slabMeta)
foreach ($memcache->getExtendedStats('cachedump', (int) $slabId) as $entries)
if (!empty($entries))
foreach ($entries as $key => $entry)
答案 10 :(得分:0)
我需要一个可靠的测试来知道使用memcache Set或memcache替换。
这就是我最终的结果。
另一个选择是设置一个到memcache查询的网络套接字,但最后它会最终做同样的事情并且这个连接已经存在,这节省了制作和维护另一个连接的开销,就像Joel Chen和# 39;答案。
$key = 'test';
$value = 'foobarbaz';
/**
* Intricate dance to test if key exists.
* If it doesn't exist flags will remain a boolean and we need to use the method set.
* If it does exist it'll be set to integer indicating the compression and what not, then we need to use replace.
*/
$storageFlag = (is_null($value) || is_bool($value) || is_int($value) || is_float($value) ? false : MEMCACHE_COMPRESSED);
$flags = false;
$memcache->get($key, $flags);
if(false === $flags) {
$memcache->set($key, $value, storageFlag , $minutes);
}
else {
$memcache->replace($key, $value, storageFlag, $minutes);
}
现在,如果你有&#34;大数据&#34;解决方案相当简单。在cojoin中使用第二个键,它包含一个像整数一样简单的东西来检查。总是一起使用它们,你没有问题。
$key = 'test';
$value = 'foobarbaz';
$storageFlag = (is_null($value) || is_bool($value) || is_int($value) || is_float($value) ? false : MEMCACHE_COMPRESSED);
$flags = false;
$exist_key = $key.'_exists';
$memcache->get($exist_key, $flags);
if(false === $flags) {
$memcache->set($key, $value, storageFlag , $minutes);
$memcache->set($exist_key, 42, false , $minutes);
}
else {
$memcache->replace($key, $value, storageFlag, $minutes);
$memcache->replace($exist_key, 42, false , $minutes);
}