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小程序自动提交到自助友情连接
Nov 24 PHP
php站内搜索并高亮显示关键字的实现代码
Dec 29 PHP
解析Extjs与php数据交互(增删查改)
Jun 25 PHP
php strnatcmp()函数的用法总结
Nov 27 PHP
让PHP显示Facebook的粉丝数量方法
Jan 08 PHP
php使用codebase生成随机数
Mar 25 PHP
php检测url是否存在的方法
Apr 14 PHP
PHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIF
Feb 19 PHP
简单的自定义php模板引擎
Aug 26 PHP
PHP实现从PostgreSQL数据库检索数据分页显示及根据条件查找数据示例
Jun 09 PHP
详解PHP版本兼容之openssl调用参数
Jul 25 PHP
jQuery ajax+PHP实现的级联下拉列表框功能示例
Feb 12 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介绍篇
2010/10/26 PHP
PHP 实现explort() 功能的详解
2013/06/20 PHP
解析PHP函数array_flip()在重复数组元素删除中的作用
2013/06/27 PHP
php制作的简单验证码识别代码
2016/01/26 PHP
Composer设置忽略版本匹配的方法
2016/04/27 PHP
PHP基于SMTP协议实现邮件发送实例代码
2017/04/27 PHP
PHP 网站修改默认访问文件的nginx配置
2017/05/27 PHP
PHP使用观察者模式处理异常信息的方法详解
2019/09/24 PHP
Javascript 读书笔记索引贴
2010/01/11 Javascript
js 判断计算字符串长度/判断空的简单方法
2013/08/05 Javascript
JavaScript实现三阶幻方算法谜题解答
2014/12/29 Javascript
javascript实现dom元素可拖动
2016/03/21 Javascript
微信小程序 页面跳转和数据传递实例详解
2017/01/19 Javascript
Vue.js结合bootstrap实现分页控件
2017/03/10 Javascript
vue安装和使用scss及sass与scss的区别详解
2018/10/15 Javascript
Vue使用预渲染代替SSR的方法
2020/07/02 Javascript
JavaScript实现滚动加载更多
2020/12/27 Javascript
python 文件操作api(文件操作函数)
2016/08/28 Python
解决python3 urllib中urlopen报错的问题
2017/03/25 Python
Flask-Mail用法实例分析
2018/07/21 Python
浅谈PYTHON 关于文件的操作
2019/03/19 Python
python爬虫之验证码篇3-滑动验证码识别技术
2019/04/11 Python
python Pillow图像处理方法汇总
2019/10/16 Python
pytorch sampler对数据进行采样的实现
2019/12/31 Python
pytorch  网络参数 weight bias 初始化详解
2020/06/24 Python
html2canvas把div保存图片高清图的方法示例
2018/03/05 HTML / CSS
Becextech新西兰:数码单反相机和手机在线商店
2018/04/27 全球购物
中国双语服务优势的在线购票及活动平台:247tickets
2018/10/26 全球购物
Geekbuying波兰:购买中国电子产品
2019/10/20 全球购物
Berghaus官网:户外服装和设备,防水服
2020/01/17 全球购物
《挑山工》的教学反思
2014/02/16 职场文书
医学生求职信
2014/07/01 职场文书
2015年团队工作总结范文
2015/05/04 职场文书
2015年班组建设工作总结
2015/05/13 职场文书
女性健康知识讲座主持词
2015/07/04 职场文书
2016年父亲节寄语
2015/12/04 职场文书