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制作简单的内容采集器的代码
Nov 28 PHP
CentOS 6.3下安装PHP xcache扩展模块笔记
Sep 10 PHP
Codeigniter框架实现获取分页数据和总条数的方法
Dec 05 PHP
PHP中使用正则表达式提取中文实现笔记
Jan 20 PHP
PHP计算指定日期所在周的开始和结束日期的方法
Mar 24 PHP
PHP类的封装与继承详解
Sep 29 PHP
Yii2实现多域名跨域同步登录退出
Feb 04 PHP
自制PHP框架之路由与控制器
May 07 PHP
php获取微信共享收货地址的方法
Dec 21 PHP
PHP基于phpqrcode类生成二维码的方法详解
Mar 14 PHP
PHP开发api接口安全验证操作实例详解
Mar 26 PHP
如何在PHP环境中使用ProtoBuf数据格式
Jun 19 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 获取远程网页内容的函数
2009/09/08 PHP
Warning: session_destroy() : Trying to destroy uninitialized sessionq错误
2011/06/16 PHP
php使用curl实现ftp文件下载功能
2017/05/16 PHP
cnblogs 代码高亮显示后的代码复制问题解决实现代码
2011/12/14 Javascript
阻止子元素继承父元素事件具体思路及实现
2013/05/02 Javascript
js中的前绑定和后绑定详解
2013/08/01 Javascript
JS图片切换的具体方法(带缩略图版)
2013/11/12 Javascript
javascript创建createXmlHttpRequest对象示例代码
2014/02/10 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
2014/08/12 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
2015/01/06 Javascript
JavaScript使用RegExp进行正则匹配的方法
2015/07/11 Javascript
localResizeIMG先压缩后使用ajax无刷新上传(移动端)
2015/08/11 Javascript
javascript RegExp 使用说明
2016/05/21 Javascript
JS模态窗口返回值兼容问题的完美解决方法
2016/05/28 Javascript
AngularJS控制器之间的通信方式详解
2016/11/03 Javascript
Mongoose经常返回e11000 error的原因分析
2017/03/29 Javascript
vue2.0开发入门笔记之.vue文件的生成和使用
2017/09/19 Javascript
Vue.js的动态组件模板的实现
2018/11/26 Javascript
Express结合Webpack的全栈自动刷新
2019/05/23 Javascript
JS立即执行的匿名函数用法分析
2019/11/04 Javascript
Javascript幻灯片播放功能实现过程解析
2020/05/07 Javascript
JS数据类型判断的几种常用方法
2020/07/07 Javascript
Python中的深拷贝和浅拷贝详解
2015/06/03 Python
python学生管理系统代码实现
2020/04/05 Python
django 开发忘记密码通过邮箱找回功能示例
2018/04/17 Python
python re模块的高级用法详解
2018/06/06 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
Python3.5 Pandas模块缺失值处理和层次索引实例详解
2019/04/23 Python
Python如何使用函数做字典的值
2019/11/30 Python
python3 xpath和requests应用详解
2020/03/06 Python
python 使用事件对象asyncio.Event来同步协程的操作
2020/05/04 Python
保加利亚服装和鞋类购物网站:Bibloo.bg
2020/11/08 全球购物
优秀实习自我鉴定
2013/12/04 职场文书
2015新学期家长寄语
2015/02/26 职场文书
2016年师德学习心得体会
2016/01/12 职场文书
解决jupyter notebook图片显示模糊和保存清晰图片的操作
2021/04/24 Python