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+Tidy-完美的XHTML纠错+过滤
Apr 10 PHP
Php Cookie的一个使用注意点
Nov 08 PHP
探讨:如何使用PhpDocumentor生成文档
Jun 25 PHP
基于PHP中的常用函数回顾
Jul 11 PHP
php缩小png图片不损失透明色的解决方法
Dec 25 PHP
zf框架db类的分页示例分享
Mar 14 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
Aug 21 PHP
php防止用户重复提交表单
Nov 02 PHP
PHP微信红包API接口
Dec 05 PHP
理解PHP中的Session及对Session有效期的控制
Jan 08 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
Jan 29 PHP
如何在PHP中使用数组
Jun 09 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中使用循环实现的金字塔图形
2014/11/08 PHP
详解WordPress开发中的get_post与get_posts函数使用
2016/01/04 PHP
CI框架常用经典操作类总结(路由,伪静态,分页,session,验证码等)
2016/11/21 PHP
php+redis实现商城秒杀功能
2020/11/19 PHP
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
2014/03/20 Javascript
JavaScript编程中容易出BUG的几点小知识
2015/01/31 Javascript
基于jQuery实现仿百度首页换肤背景图片切换代码
2015/08/25 Javascript
javascript回到顶部特效
2016/07/30 Javascript
js中用cssText设置css样式的简单方法
2016/09/19 Javascript
jQuery动态增减行的实例代码解析(推荐)
2016/12/05 Javascript
javascript流程控制语句集合
2017/09/18 Javascript
微信小程序项目实践之验证码倒计时功能
2018/07/18 Javascript
JavaScript树的深度优先遍历和广度优先遍历算法示例
2018/07/30 Javascript
vue 使用vue-i18n做全局中英文切换的方法
2018/10/29 Javascript
Node.js API详解之 console模块用法详解
2020/05/12 Javascript
[00:12]DAC2018 no[o]ne亮相SOLO赛 他是否如他的id一样无人可挡?
2018/04/06 DOTA
python通过ssh-powershell监控windows的方法
2015/06/02 Python
python matlibplot绘制3D图形
2018/07/02 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
2019/10/18 Python
将pytorch转成longtensor的简单方法
2020/02/18 Python
Python自动化xpath实现自动抢票抢货
2020/09/19 Python
HTML5离线缓存Manifest是什么
2016/03/09 HTML / CSS
使用layui框架实现点击左侧导航切换右侧内容且右侧选项卡跟随变化的效果
2020/11/10 HTML / CSS
法国在线宠物店:zooplus.fr
2018/02/23 全球购物
美国摩托车头盔、零件、齿轮及配件商店:Cycle Gear
2019/06/12 全球购物
Shell如何接收变量输入
2012/09/24 面试题
怎样自定义一个异常类
2016/09/27 面试题
采购文员岗位职责
2013/11/20 职场文书
交通事故和解协议书
2014/09/25 职场文书
运动会宣传语
2015/07/13 职场文书
2016年暑假学生家长评语
2015/12/01 职场文书
2016七夕情人节感言
2015/12/09 职场文书
2016廉洁教育心得体会
2016/01/20 职场文书
高中班主任寄语
2019/06/21 职场文书
通过feDisplacementMap和feImage实现水波特效
2022/04/24 HTML / CSS
输入框跟随文字内容适配宽实现示例
2022/08/14 Javascript