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 相关文章推荐
echo(),print(),print_r()之间的区别?
Nov 19 PHP
PHP程序员最常犯的11个MySQL错误小结
Nov 20 PHP
php max_execution_time执行时间问题
Jul 17 PHP
php的chr和ord函数实现字符加减乘除运算实现代码
Dec 05 PHP
PHP去掉从word直接粘贴过来的没有用格式的函数
Oct 29 PHP
46 个非常有用的 PHP 代码片段
Feb 16 PHP
php的laravel框架快速集成微信登录的方法
Dec 12 PHP
PHP中模糊查询并关联三个select框
Jun 19 PHP
php格式文件打开的四种方法
Feb 24 PHP
PHP实现基于状态的责任链审批模式详解
May 31 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
Nov 22 PHP
PHP笛卡尔积实现原理及代码实例
Dec 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中防止SQL注入实现代码
2011/02/19 PHP
修改destoon会员公司的伪静态中的com目录的方法
2014/08/21 PHP
19个Android常用工具类汇总
2014/12/30 PHP
ThinkPHP 框架实现的读取excel导入数据库操作示例
2020/04/14 PHP
JavaScript语言核心数据类型和变量使用介绍
2013/08/23 Javascript
节点的插入之append()和appendTo()的用法介绍
2014/01/13 Javascript
jquery实现倒计时代码分享
2014/06/13 Javascript
JavaScript实现自动对页面上敏感词进行屏蔽的方法
2015/07/27 Javascript
JS实现获取键盘按下的按键并显示在页面上的方法
2015/11/04 Javascript
jQuery基础知识点总结(必看)
2016/05/31 Javascript
AngularJS 路由详解和简单实例
2016/07/28 Javascript
微信小程序 ecshop地址三级联动实现实例代码
2017/02/28 Javascript
vue.js动态数据绑定学习笔记
2017/05/19 Javascript
详解vue嵌套路由-params传递参数
2017/05/23 Javascript
vue-router实现编程式导航的代码实例
2019/01/19 Javascript
js核心基础之闭包的应用实例分析
2019/05/11 Javascript
记录Django开发心得
2014/07/16 Python
Python中解析JSON并同时进行自定义编码处理实例
2015/02/08 Python
列举Python中吸引人的一些特性
2015/04/09 Python
在Python中操作字符串之rstrip()方法的使用
2015/05/19 Python
Python中import机制详解
2017/11/14 Python
python+matplotlib演示电偶极子实例代码
2018/01/12 Python
Python实现FM算法解析
2019/06/18 Python
Python学习笔记之lambda表达式用法详解
2019/08/08 Python
用CSS3来实现社交分享按钮
2014/11/11 HTML / CSS
MATCHESFASHION澳大利亚/亚太地区:英国时尚奢侈品电商
2020/01/14 全球购物
应届生煤化工求职信
2013/10/21 职场文书
最新党员的自我评价分享
2013/11/04 职场文书
工程师岗位职责规定
2014/02/26 职场文书
任命书格式
2014/06/05 职场文书
小班下学期个人总结
2015/02/12 职场文书
整改通知书
2015/04/20 职场文书
学雷锋献爱心活动总结
2015/05/11 职场文书
《鲁班学艺》读后感3篇
2019/11/27 职场文书
用几道面试题来看JavaScript执行机制
2021/04/30 Javascript
java多态注意项小结
2021/10/16 Java/Android