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


Posted in PHP onFebruary 27, 2016

缓存命名空间

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 相关文章推荐
php+javascript的日历控件
Nov 19 PHP
PHP 采集程序原理分析篇
Mar 05 PHP
PHP foreach循环使用详解与实例代码
May 08 PHP
php中使用parse_url()对网址进行解析的实现代码(parse_url详解)
Jan 03 PHP
php+iframe实现隐藏无刷新上传文件
Feb 10 PHP
php 删除一个数组中的某个值.兼容多维数组!
Feb 18 PHP
Function eregi is deprecated (解决方法)
Jun 21 PHP
php sybase_fetch_array使用方法
Apr 15 PHP
IIS下PHP的三种配置方式对比
Nov 20 PHP
什么是PEAR?什么是PECL?PHP中两个容易混淆的概念解释
Jul 01 PHP
twig里使用js变量的方法
Feb 05 PHP
PHP架构及原理知识点详解
Dec 22 PHP
简单谈谈PHP中strlen 函数
Feb 27 #PHP
详解PHP的Laravel框架中Eloquent对象关系映射使用
Feb 26 #PHP
PHP文件缓存smarty模板应用实例分析
Feb 26 #PHP
PHP计算当前坐标3公里内4个角落的最大最小经纬度实例
Feb 26 #PHP
PHP实现根据时间戳获取周几的方法
Feb 26 #PHP
PHP将二维数组某一个字段相同的数组合并起来的方法
Feb 26 #PHP
关于PHP 如何用 curl 读取 HTTP chunked 数据
Feb 26 #PHP
You might like
php输出xml必须header的解决方法
2014/10/17 PHP
php通过function_exists检测函数是否存在的方法
2015/03/18 PHP
php校验表单检测字段是否为空的方法
2015/03/20 PHP
PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析
2017/02/04 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
JS与框架页的操作代码
2010/01/17 Javascript
jQuery实现表头固定效果的实例代码
2013/05/24 Javascript
js中浮点型运算BUG的解决方法说明
2014/01/06 Javascript
JS实现根据当前文字选择返回被选中的文字
2014/05/21 Javascript
jQuery将多条数据插入模态框的示例代码
2014/09/25 Javascript
简介JavaScript中toTimeString()方法的使用
2015/06/12 Javascript
浏览器兼容的JS写法总结
2016/04/27 Javascript
使用jquery给指定的table动态添加一行、删除一行
2016/10/13 Javascript
深入学习jQuery中的data()
2016/12/22 Javascript
nodejs入门教程六:express模块用法示例
2017/04/24 NodeJs
Bootstrap Tree View简单而优雅的树结构组件实例解析
2017/06/15 Javascript
angular6.0开发教程之如何安装angular6.0框架
2018/06/29 Javascript
Canvas实现微信红包照片效果
2018/08/21 Javascript
基于vue实现移动端圆形旋钮插件效果
2018/11/28 Javascript
解决node终端下运行js文件不支持ES6语法
2020/04/04 Javascript
python实现斐波那契递归函数的方法
2014/09/08 Python
编写Python小程序来统计测试脚本的关键字
2016/03/12 Python
Python3中的f-Strings增强版字符串格式化方法
2020/03/04 Python
python对XML文件的操作实现代码
2020/03/27 Python
Django CBV模型源码运行流程详解
2020/08/17 Python
python+selenium 简易地疫情信息自动打卡签到功能的实现代码
2020/08/22 Python
荷兰家电购物网站:Expert.nl
2020/01/18 全球购物
纬创Java面试题笔试题
2014/10/02 面试题
营销专业应届生求职信
2013/11/26 职场文书
学生会部长竞聘书
2014/03/31 职场文书
小学美术兴趣小组活动总结
2014/07/07 职场文书
萤火虫之墓观后感
2015/06/05 职场文书
爱国主义影片观后感
2015/06/18 职场文书
SQL实战演练之网上商城数据库商品类别数据操作
2021/10/24 MySQL
《异世界四重奏》剧场版6月10日上映 PV视觉图原创角色发表
2022/03/20 日漫
Nginx如何配置根据路径转发详解
2022/07/23 Servers