在网上看到有用其他语言实现的例子,这里用php写下,以加深理解。

用php具体代码实现

首先设计一个访问数据库的模型类

class model

{

function getlist($catid)

{

}

}

方法一:

$cache = new cache(); //实例化一个已封装过的memcache类

function getnewlist($catid)

{

global $cache;

$key = "newslist-catid=".$catid; //设置一个cache key

$value = $cache->get($key); //获取key对应的cache

if($value == null) //key 对应的cache过期

{

//按说过期的时候就应读取数据库 用getlist($catid)方法了。在小流量小并发时不会出现什么问题,当大并发时,可能会有几千个人同时访问到了cache失效,如果都去读取db的话,会造成db资源浪费甚至崩溃

并发读取数据库势必会造成很慢的情况,如果还没有从数据库中读取出来并写入到cache中。这时候再有人访问过来,就又进入读取db的操作了。

//因此增加锁

$mutex_key = $key."-mutex"; //设置mutex key,用于支持本key的一个锁

if($cache->add($mutex_key, 1) == true ) //对mutex_key 设置一个整数为1 的缓存,不计算马上存储。add方法就是第一次存储时返回true,如果已经存在返回false。这就相当于一个锁,避免了再次被执行

{

$model = new model(); //实例化模型

$value = $model->getlist($catid); //读取数据库获得catid的列表信息,数据库设置中应为catid建立索引

$cache->set($key, $value);//刷新缓存

$cache->delete($mutex_key);//释放锁缓存

}

else//如果有并发访问过来,等待处理

{

sleep(2); //设置2秒的锁等待

getnewlist($catid);//尝试去读取结果

}

}

return $value;

}

方法二:

$cache = new cache(); //实例化一个memcache类

function getnewlist($catid)

{

global $cache;

$expiretime = 360; //过期时间6分钟

$key = 'newlist-catid='.$catid;

$value = $cache->get($key);

if($value == null) //缓存失效

{

//设置一个锁等待

$mutex_key = $key.'-mutex';

if($cache->add($mutex_key, 1) == true) //设置一个锁

{

$model = new model(); //实例化模型

$value = $model->getlist($catid); //读取数据库获得catid的列表信息,数据库设置中应为catid建立索引

$cache->set($key, array('timeout' => time() + $expiretime, 'value' => $value), $expiretime*2);//刷新缓存,这步可以在cache类中封装

//这里有个问题,就是可能每个cache服务器会出现时间不一致,造成不是你预想的时间。对timeout赋值,如果只设置 $expiretime,如何获取时间节点问题。

$cache->delete($mutex_key);//释放锁缓存

}

else

{

sleep(2); //设置2秒的锁等待

getnewlist($catid);//尝试去读取结果

}

}

else//如果还没有过期

{

//如果timeout已经过期,因为timeout设置的时间短,此时$key还没有到期,实际上是个伪过期时间点,timeout作为一个真正的到期时间点

if($value['timeout'] < time())

{

//设置锁

$mutex_key = $key.'-mutex';

if($cache->add($mutex_key, 1) == true)//首先捕获到并设置个锁

{

$value['timeout'] = time() + $expiretime ; //马上延长过期时间

$cache->set($key, $value, $expiretime*2); //延长时间并保存,防止在高并发状态下,数据库读取时间长,而缓存已失效。

$model = new model(); //实例化模型

$value = $model->getlist($catid); //读取数据库获得catid的列表信息,数据库设置中应为catid建立索引

$cache->set($key, array('timeout' => time() + $expiretime, 'value' => $value), $expiretime*2);//刷新缓存,这步可以在cache类中封装

$cache->delete($mutex_key);//释放锁缓存

}

}

return $value['value'];

}

}

相比于方法一, 优点:避免cache失效时刻,大量请求无法执行add(key_mutex)而进入sleep锁定等待 缺点:代码复杂性增加,前台数据要求不那么严格时可以使用这里输入代码

php环境下cache失效,cache缓存失效高并发读数据库的问题相关推荐

  1. 项目总结10:通过反射解决springboot环境下从redis取缓存进行转换时出现ClassCastException异常问题...

    通过反射解决springboot环境下从redis取缓存进行转换时出现ClassCastException异常问题 关键字 springboot热部署  ClassCastException异常 反射 ...

  2. 高并发读场景下的利器:本地缓存+分布式缓存

    本地缓存和分布式缓存并不是二者取其一甚至对立的关系,而是要结合使用:常见的电商高并发读场景下下,本地缓存存放热点数据,分布式缓存存放全量数据:当然这里有一个很重要的点,即要结合业务,本地缓存中的数据一 ...

  3. java 高并发商城库存订单处理,下单减库存,如何解决高并发减库存问题

    下单减库存,如何解决高并发减库存问题 1. 减库存 一般下单减库存的流程大概是这样的: 1.查询商品库存.这里直接查的Redis中的库存. 2.Redis中的库存减1.这里用到的Redis命令是:in ...

  4. 本地缓存需要高时效性怎么办_缓存在高并发场景下的常见问题

    缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象.这就比较依赖缓存的过期和更新策略.一般会在数据发生更改 ...

  5. 并发经验八年架构师:带你轻松解决缓存在高并发场景下的问题

    缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象.这就比较依赖缓存的过期和更新策略.一般会在数据发生更改 ...

  6. 缓存在高并发场景下的常见问题

    缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象.这就比较依赖缓存的过期和更新策略.一般会在数据发生更改 ...

  7. 并发经验八年架构师:缓存在高并发场景下该如何问题

    缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象.这就比较依赖缓存的过期和更新策略.一般会在数据发生更改 ...

  8. LruCache在美团DSP系统中的应用演进(生动诠释了计算机三幻神(缓存,高并发,分布式))

    背景 DSP系统是互联网广告需求方平台,用于承接媒体流量,投放广告.业务特点是并发度高,平均响应低(百毫秒). 为了能够有效提高DSP系统的性能,美团平台引入了一种带有清退机制的缓存结构LruCach ...

  9. Linux下配置tomcat+apr+native应对高并发

    一.三种运行模式介绍 Tomcat 有三种(bio,nio.apr) 运行模式,首先来简单介绍下 bio  bio(blocking I/O),顾名思义,即阻塞式I/O操作,表示Tomcat使用的是传 ...

  10. java vanish 缓存_高并发基础、思路以及普遍的处理方式

    何为高并发 在同时或者极短时间内,有大量的请求到达服务端,每个请求都需要服务端消耗资源去进行处理.同时开启的进程数.能同时运行的线程数.网络连接数.cpu.io.内存均为服务端资源,由于服务端资源是有 ...

最新文章

  1. vim学习笔记(三)
  2. 【重磅】斯坦福李飞飞《注意力与Transformer》总结,84页ppt开放下载!
  3. c语言实参的默认存储类型,2016下半年软考程序员练习习题及答案解析(一)
  4. memcached java 多线程_springboot使用memcache缓存
  5. 图像处理之添加文字水印
  6. fastai学习——第二个问题
  7. swing中如何将jtable中的数据导入到excel中?
  8. 【树莓派】最常用的树莓派 Linux 命令及说明
  9. LINUX国产操作系统还缺少些什么?
  10. 浏览器js 获取手机标识信息_手机软件多次要求获取手机信息,习惯性让其通过有安全隐患?...
  11. 怎么判断我选了多少个复选框_7~8个月宝宝一天吃多少辅食,怎么安排?妈妈这样做,养出健康娃...
  12. linux系统的文件系统tmpfs,linux里tmpfs文件系统
  13. mysql安装开始报错_MYSQL安装报错 -- 出现Failed to find valid data directory.
  14. Collection 属性ArrayList.add方法内部调用过程
  15. cocos2d-x关于CCTableView的“乱序问题”的理解
  16. 微信小程序之去除抖音、快手等视频平台水印!
  17. 获取文件夹下所有tif图片,并将16位图转为8位图
  18. 微信小程序性能优化实用建议
  19. python中temp是什么意思_.temp(temp是什么意思?)
  20. 双曲函数奇偶性_[快乐数学]双曲函数(二)

热门文章

  1. HIVE存储(五)HIVE文件的性能测试
  2. asp.net 读取导入的project(mpp)文件
  3. RabbitMQ五种工作模式学习总结
  4. Java创建多线程的方法总结
  5. Java代码优化的一些方法(总结)
  6. Spring源码之事务(一)
  7. mayan 游戏真是毒瘤
  8. PHP Mysql-创建数据库
  9. Google App Engine CMS系统的搭建
  10. Oracle数据库出现“本地计算机上的OracleOraDB11g_homeTNSListener服务启动后停止.....”问题解决方案...