博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cache缓存失效高并发读数据库的问题
阅读量:6378 次
发布时间:2019-06-23

本文共 2769 字,大约阅读时间需要 9 分钟。

hot3.png

在网上看到有用其他语言实现的例子,这里用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对应的cacheif($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锁定等待 缺点:代码复杂性增加,前台数据要求不那么严格时可以使用这里输入代码

转载于:https://my.oschina.net/shilijun/blog/95019

你可能感兴趣的文章
==与===的区别
查看>>
不同工具查看代码分支diff的差异
查看>>
一文 | 跨域及其解决方案
查看>>
白话Java I/O模型
查看>>
[TsAdmin]--一款基于Vue.js+Element UI的单页无刷新(无iframe)多选项卡的后台管理系统模板...
查看>>
上传一张照片,让算法告诉你是否患有抑郁症
查看>>
VR厂商唯晶科技获2800万C+轮融资,曾开发过游戏《圣女之歌》
查看>>
Countly 19.02.1 发布,实时移动和 web 分析报告平台
查看>>
TCP连接中time_wait在开发中的影响-搜人以鱼不如授之以渔
查看>>
Oracle数据库机出新帮助不同规模企业迈向云端
查看>>
前端通信:ajax设计方案(六)--- 全局配置、请求格式拓展和优化、请求二进制类型、浏览器错误搜集以及npm打包发布...
查看>>
微服务分布式企业框架 Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis+KafKa
查看>>
被《时代周刊》选为年度最佳发明,PS VR靠的竟然是价格
查看>>
通用唯一标识码UUID的介绍及使用。
查看>>
spring笔记--依赖注入之针对不同类型变量的几种注入方式
查看>>
Java爬虫——网易云热评爬取
查看>>
Ajax的简单学习
查看>>
无华为,不智慧:智慧城市建设为何少不了华为?
查看>>
高性能网络通信框架Netty-基础概念篇
查看>>
为npm配置taobao源
查看>>