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读取IMAP邮件
Oct 09 PHP
用php来检测proxy
Oct 09 PHP
PHP连接access数据库
Mar 27 PHP
rephactor 优秀的PHP的重构工具
Jun 09 PHP
php中批量替换文件名的实现代码
Jul 20 PHP
PHP中的按位与和按位或操作示例
Jan 27 PHP
php递归使用示例(php递归函数)
Feb 14 PHP
Parse正式发布开源PHP SDK
Aug 11 PHP
php生成图片验证码
Jun 09 PHP
PHP MPDF中文乱码的解决方式
Dec 08 PHP
php利用ffmpeg提取视频中音频与视频画面的方法详解
Jun 07 PHP
PHP流Streams、包装器wrapper概念与用法实例详解
Nov 17 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 页面编码声明方法详解(header或meta)
2010/03/12 PHP
php实现zip压缩文件解压缩代码分享(简单易懂)
2014/05/10 PHP
JQuery防止退格键网页后退的实现代码
2012/03/23 Javascript
Js 冒泡事件阻止实现代码
2013/01/27 Javascript
js如何获取file控件的完整路径具体实现代码
2013/05/15 Javascript
javascript使用call调用微信API
2014/12/15 Javascript
JavaScript数据类型检测代码分享
2015/01/26 Javascript
js实现选中复选框文字变色的方法
2015/08/14 Javascript
使用jQuery UI库开发Web界面的简单入门指引
2016/04/22 Javascript
易被忽视的js事件问题总结
2016/05/14 Javascript
利用纯Vue.js构建Bootstrap组件
2016/11/03 Javascript
js手机号批量滚动抽奖实现代码
2020/04/17 Javascript
从零学习node.js之搭建http服务器(二)
2017/02/21 Javascript
Express进阶之log4js实用入门指南
2018/02/10 Javascript
vue-cli项目根据线上环境分别打出测试包和生产包
2018/05/23 Javascript
vue自定义tap指令及tap事件的实现
2018/09/18 Javascript
vue开发环境配置跨域的方法步骤
2019/01/16 Javascript
M2实现Nodejs项目自动部署的方法步骤
2019/05/05 NodeJs
小程序实现悬浮搜索框
2019/07/12 Javascript
node实现爬虫的几种简易方式
2019/08/22 Javascript
Python中的列表生成式与生成器学习教程
2016/03/13 Python
Python 正则表达式入门(中级篇)
2016/12/07 Python
Python利用operator模块实现对象的多级排序详解
2017/05/09 Python
python学习必备知识汇总
2017/09/08 Python
Python实现XML文件解析的示例代码
2018/02/05 Python
Python cookbook(数据结构与算法)让字典保持有序的方法
2018/02/18 Python
Python列表(List)知识点总结
2019/02/18 Python
原生canvas制作画图小工具的踩坑和爬坑
2020/06/09 HTML / CSS
大一新生军训时的自我评价分享
2013/12/05 职场文书
煤矿安全协议书
2014/08/20 职场文书
端午节活动总结
2014/08/26 职场文书
无刑事犯罪记录证明
2014/09/18 职场文书
个人作风建设总结
2014/10/23 职场文书
商务考察邀请函模板
2015/02/02 职场文书
办公用品质量保证书
2015/05/11 职场文书
vue实现锚点定位功能
2021/06/29 Vue.js