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&amp;&amp;mysql)六
Oct 09 PHP
用PHP读取超大文件的实例代码
Apr 01 PHP
PHP的一个完美GIF等比缩放类,附带去除缩放黑背景
Apr 01 PHP
php5.3以后的版本连接sqlserver2000的方法
Jul 28 PHP
php实现检查文章是否被百度收录
Jan 27 PHP
php使用MySQL保存session会话的方法
Jun 26 PHP
Zend Framework校验器Zend_Validate用法详解
Dec 09 PHP
Zend Framework过滤器Zend_Filter用法详解
Dec 09 PHP
PHP控制反转(IOC)和依赖注入(DI)
Mar 13 PHP
php封装db类连接sqlite3数据库的方法实例
Dec 19 PHP
PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作详解
Jun 14 PHP
php变量与字符串的增删改查操作示例
May 07 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/11/24 PHP
php中explode与split的区别介绍
2012/10/03 PHP
easyui的tabs update正确用法分享
2014/03/21 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
2014/07/25 PHP
PHP扩展开发入门教程
2015/02/26 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
2015/05/12 PHP
php多重接口的实现方法
2015/06/20 PHP
thinkPHP框架实现的简单计算器示例
2018/12/07 PHP
php文件后缀不强制为.php的实操方法
2019/09/18 PHP
翻译整理的jQuery使用查询手册
2007/03/07 Javascript
基于jquery的监控数据是否发生改变
2011/04/11 Javascript
《JavaScript高级程序设计》阅读笔记(一) ECMAScript基础
2012/02/27 Javascript
jquery 表格的增行删行实现思路
2013/03/21 Javascript
非常实用的12个jquery代码片段
2015/11/02 Javascript
微信小程序下拉框功能的实例代码
2018/11/06 Javascript
no-vnc和node.js实现web远程桌面的完整步骤
2019/08/11 Javascript
node.js实现http服务器与浏览器之间的内容缓存操作示例
2020/02/11 Javascript
JavaScript布尔运算符原理使用解析
2020/05/06 Javascript
JS+JQuery实现无缝连接轮播图
2020/12/30 jQuery
Python 操作文件的基本方法总结
2017/08/10 Python
Python requests获取网页常用方法解析
2020/02/20 Python
详解python实现可视化的MD5、sha256哈希加密小工具
2020/09/14 Python
image-set实现Retina屏幕下图片显示详细介绍
2012/12/24 HTML / CSS
什么是索引指示器
2012/08/20 面试题
大学生护理专业自荐信
2013/10/03 职场文书
群众路线教育实践活动方案
2014/02/02 职场文书
班主任新年寄语
2014/04/04 职场文书
竞选文艺委员演讲稿
2014/04/28 职场文书
环保建议书100字
2014/05/14 职场文书
药剂专业求职信
2014/06/20 职场文书
公司业务员管理制度
2015/08/05 职场文书
安全教育主题班会总结
2015/08/14 职场文书
大学生就业指导课心得体会
2016/01/15 职场文书
2019年圣诞节祝福语集锦
2019/12/25 职场文书
mybatis 获取无数据的字段不显示的问题
2021/07/15 Java/Android
Sql Server之数据类型详解
2022/02/28 SQL Server