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 相关文章推荐
分页显示Oracle数据库记录的类之二
Oct 09 PHP
php各种编码集详解和以及在什么情况下进行使用
Sep 11 PHP
深入PHP autoload机制的详解
Jun 09 PHP
smarty模板引擎中内建函数if、elseif和else的使用方法
Jan 22 PHP
CodeIgniter删除和设置Cookie的方法
Apr 07 PHP
PHP session会话操作技巧小结
Sep 27 PHP
thinkPHP中volist标签用法示例
Dec 06 PHP
php获取客户端IP及URL的方法示例
Feb 03 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
May 05 PHP
PHP实现合并两个排序链表的方法
Jan 19 PHP
php生成HTML文件的类方法
Oct 11 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
Mar 26 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
合作指挥官:孟斯克
2020/03/16 星际争霸
成本8450万,票房仅2亿,口碑两极分化,又一部DC电影扑街了
2020/04/09 欧美动漫
PHP安装问题
2006/10/09 PHP
PHP中使用Imagick操作PSD文件实例
2015/01/26 PHP
php生成二维码
2015/08/10 PHP
PHP使用finfo_file()函数检测上传图片类型的实现方法
2017/04/18 PHP
Javascript基础教程之函数对象和属性
2015/01/18 Javascript
javascript中字体浮动效果的简单实例演示
2015/11/18 Javascript
javascript如何创建对象
2016/08/29 Javascript
vue-cli的工程模板与构建工具详解
2018/09/27 Javascript
webpack开发环境和生产环境的深入理解
2018/11/08 Javascript
前端vue-cli项目中使用img图片和background背景图的几种方法
2019/11/13 Javascript
vue项目中锚点定位替代方式
2019/11/13 Javascript
编写一个javascript元循环求值器的方法
2020/04/14 Javascript
python中日期和时间格式化输出的方法小结
2015/03/19 Python
基于Python实现文件大小输出
2016/01/11 Python
python3实现暴力穷举博客园密码
2016/06/19 Python
对numpy和pandas中数组的合并和拆分详解
2018/04/11 Python
Pandas 数据处理,数据清洗详解
2018/07/10 Python
使用Python获取并处理IP的类型及格式方法
2018/11/01 Python
实例详解Python装饰器与闭包
2019/07/29 Python
Django QuerySet查询集原理及代码实例
2020/06/13 Python
详解通过focusout事件解决IOS键盘收起时界面不归位的问题
2019/07/18 HTML / CSS
CHARLES & KEITH台湾官网:新加坡时尚品牌
2019/07/30 全球购物
在职人员函授期间自我评价分享
2013/11/08 职场文书
办公室文书岗位职责
2013/12/16 职场文书
广告设计应届生求职信
2014/03/01 职场文书
假面舞会策划方案
2014/05/29 职场文书
建筑结构施工求职信
2014/07/11 职场文书
党员民主生活会对照检查材料思想汇报
2014/09/28 职场文书
政府班子四风问题整改措施
2014/10/04 职场文书
小学英语复习计划
2015/01/19 职场文书
看古人们是如何赞美老师的?
2019/07/08 职场文书
解析CSS 提取图片主题色功能(小技巧)
2021/05/12 HTML / CSS
Pygame Time时间控制的具体使用详解
2021/11/17 Python
HTML中link标签属性的具体用法
2023/05/07 HTML / CSS