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版
Oct 09 PHP
Array of country list in PHP with Zend Framework
Oct 17 PHP
php提示Call-time pass-by-reference has been deprecated in的解决方法[已测]
May 06 PHP
分享一下贝贝成长进度的php代码
Sep 14 PHP
php中获取主机名、协议及IP地址的方法
Nov 18 PHP
PHP中require和include路径问题详解
Dec 25 PHP
如何使用jQuery+PHP+MySQL来实现一个在线测试项目
Apr 26 PHP
PHP将Excel导入数据库及数据库数据导出至Excel的方法
Jun 24 PHP
php session实现多级目录存放实现代码
Feb 03 PHP
Yii 2.0在Grid中格式化时间方法示例
Jun 06 PHP
在 Laravel 6 中缓存数据库查询结果的方法
Dec 11 PHP
php7 新增功能实例总结
May 25 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文件操作实现代码分享
2011/09/01 PHP
php使用反射插入对象示例分享
2014/03/11 PHP
php利用cookies实现购物车的方法
2014/12/10 PHP
php使用GD库创建图片缩略图的方法
2015/06/10 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
2015/11/04 PHP
功能强大的PHP发邮件类
2016/08/29 PHP
Javascript string 扩展库代码
2010/04/09 Javascript
JSCode all of Brower 全局屏蔽网页右键功能 具体实现
2013/06/05 Javascript
如何通过javascript操作web控件的自定义属性
2013/11/25 Javascript
jQuery中bind,live,delegate与one方法的用法及区别解析
2013/12/30 Javascript
JavaScript数组随机排列实现随机洗牌功能
2015/03/19 Javascript
jQuery EasyUi实战教程之布局篇
2016/01/26 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
解析jquery easyui tree异步加载子节点问题
2017/03/08 Javascript
swiper动态改变滑动内容的实现方法
2018/01/17 Javascript
Vue router传递参数并解决刷新页面参数丢失问题
2020/12/02 Vue.js
[45:56]Ti4正赛第一天 VG vs NEWBEE 3
2014/07/19 DOTA
Python中对象迭代与反迭代的技巧总结
2016/09/17 Python
Python实现的生成格雷码功能示例
2018/01/24 Python
Python递归及尾递归优化操作实例分析
2020/02/01 Python
python中提高pip install速度
2020/02/14 Python
Python模块相关知识点小结
2020/03/09 Python
Python中BeautifulSoup通过查找Id获取元素信息
2020/12/07 Python
纯CSS3实现滚动的齿轮动画效果
2014/06/05 HTML / CSS
Java如何获得ResultSet的总行数
2016/09/03 面试题
网络信息管理员岗位职责
2014/01/05 职场文书
道路交通安全实施方案
2014/03/12 职场文书
环保建议书500字
2014/05/14 职场文书
2014第二批党员干部对照“四风”找差距检查材料思想汇报
2014/09/18 职场文书
机关副主任个人四风问题整改措施
2014/09/26 职场文书
教师党的群众路线学习心得体会
2014/11/04 职场文书
本科毕业答辩开场白
2015/05/27 职场文书
2015年国庆放假通知范文
2015/08/18 职场文书
周一早安温馨问候祝福语!
2019/07/15 职场文书
人生一定要学会的三样东西:放下、忘记、珍惜
2019/08/21 职场文书
Spring Bean的实例化之属性注入源码剖析过程
2021/06/13 Java/Android