PHP使用Memcache时模拟命名空间及缓存失效问题的解决
发布:smiling 来源: PHP粉丝网 添加日期:2021-07-12 10:28:19 浏览: 评论:0
这篇文章主要介绍了PHP使用Memcache时模拟命名空间及缓存失效问题的解决,这里谈到的缓存失效主要针对高并发场景下取不到缓存的情况,需要的朋友可以参考下
缓存命名空间
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();
- }
- }
- }
Tags: Memcache PHP命名空间
相关文章
- ·php memcached 扩展 timeout 问题(2013-12-06)
- ·php中Memcached连接超时问题解决办法(2013-12-07)
- ·memcached启动和关闭的方法(2014-02-10)
- ·php memcache和memcached的区别(2014-02-21)
- ·PHP连接Memcache程序代码(2014-06-10)
- ·emlog中使用memcache缓存配置修改方法(2014-06-17)
- ·php memcached安装与使用(2014-08-05)
- ·Memcache php提高mysql负载有效方法(2014-08-18)
- ·php实现memcache缓存实例详解(2014-08-27)
- ·php MemCache内存缓存学习笔记(2014-08-27)
- ·memcache构建简单的内存消息队列(2014-08-27)
- ·解决memcache中使用session_start启动慢(2014-08-27)
- ·清除memcache中的缓存一些方法总结(2014-08-27)
- ·PHP memcache实现消息队列实例(2014-08-27)
- ·PHP利用memcache缓存技术简单介绍(2014-08-28)
- ·php内存缓存实现程序代码(2014-08-28)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)