A5下载 - 努力做内容最丰富最安全的下载站!

A5站长下载站

当前位置:A5下载 > 编程开发 > 网站开发 > PHP使用Memcache时模拟命名空间及缓存失效问题的解决

PHP使用Memcache时模拟命名空间及缓存失效问题的解决

时间:2016-02-29 11:15作者:fang人气:127

缓存命名空间

memcache本身不支持命名空间,但是我们可以利用 memcache本身的机制,来模拟命名空间。比如:你要清除一组数据,就需要用到命名空间,来看这样一个例子,说明写在了注释里:

class Action

{

public function index()

{

global $mc_wr;

// 获取命名空间

$ns_key = $mc_wr->get("foo_namespace_key");

// 如果命名空间不存在,则设置一个

if($ns_key===false) $mc_wr->set("foo_namespace_key",time());

$otherParms = 'select * from user LIMIT 1';

// 根据命名空间生成唯一的key

$my_key = "foo_".$ns_key.'_'.md5($otherParms);

// 获取当前key下的缓存

$val = $mc_wr->get($my_key);

if (!$val) {

$value = 'wangdekang_'.time();

// 缓存不存在则设置缓存 600秒, 0为随机失效时间, 为失效时间添加随机秒数,防止瞬间所有缓存同时失效

$mc_wr->set($my_key,$value,600, 0);

}

echo $val;

}

public function clear_ns()

{

global $mc_wr;

// 更新命名空间值,让当前命名空间的所有值失效, memcache自身的缓存失效机制,当缓存不在被访问,会通过LRU失效机制

$mc_wr->set('foo_namespace_key', time());

}

}

memcache缓存失效问题

在大并发的场合,当cache失效时,大量并发同时取不到cache,会同一瞬间去访问db并回设cache,可能会给系统带来潜在的超负荷风险。

解决方法:

方法一

在load db之前先add一个mutex key, mutex key add成功之后再去做加载db, 如果add失败则sleep之后重试读取原cache数据。为了防止死锁,mutex key也需要设置过期时间。伪代码如下

if (memcache.get(key) == null) {

// 3 min timeout to avoid mutex holder crash

if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {

value = db.get(key);

memcache.set(key, value);

memcache.delete(key_mutex);

} else {

sleep(50);

retry();

}

}

方法二

在value内部设置1个超时值(timeout1), timeout1比实际的memcache

timeout(timeout2)小。当从cache读取到timeout1发现它已经过期时候,马上延长timeout1并重新设置到cache。然

后再从数据库加载数据并设置到cache中。伪代码如下

v = memcache.get(key);

if (v == null) {

if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {

value = db.get(key);

memcache.set(key, value);

memcache.delete(key_mutex);

} else {

sleep(50);

retry();

}

} else {

if (v.timeout <= now()) {

if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {

// extend the timeout for other threads

v.timeout += 3 * 60 * 1000;

memcache.set(key, v, KEY_TIMEOUT * 2);

// load the latest value from db

v = db.get(key);

v.timeout = KEY_TIMEOUT;

memcache.set(key, value, KEY_TIMEOUT * 2);

memcache.delete(key_mutex);

} else {

sleep(50);

retry();

}

}

}

以上就是本文章的内容,希望对大家有所帮助

标签PHP,使用,Memcache,模拟,命名,空间,缓存,失效

相关下载

查看所有评论+

网友评论

网友
您的评论需要经过审核才能显示

公众号