博客
关于我
Redis 缓存击穿
阅读量:335 次
发布时间:2019-03-04

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

Redis 缓存击穿,失效以及维度划分

图左侧为客户端直接调用存储层的架构,右侧为比较典型的缓存层+存储层架构。

在这里插入图片描述
收益:

①加速读写:因为缓存通常都是全内存的,而存储层通常读写性能不够强悍(例如MySQL),通过缓存的使用可以有效地加速读写,优化用户体验。

②降低后端负载:帮助后端减少访问量和复杂计算(例如很复杂的SQL语句),在很大程度降低了后端的负载。

成本:

①数据不一致性:缓存层和存储层的数据存在着一定时间窗口的不一致性,时间窗口跟更新策略有关。

②代码维护成本:加入缓存后,需要同时处理缓存层和存储层的逻辑,增大了开发者维护代码的成本。

③运维成本:以Redis Cluster为例,加入后无形中增加了运维成本。

缓存的使用场景基本包含如下两种:

①开销大的复杂计算:以MySQL为例子,一些复杂的操作或者计算(例如大量联表操作、一些分组计算),如果不加缓存,不但无法满足高并发量,同时也会给MySQL带来巨大的负担。

②加速请求响应:即使查询单条后端数据足够快(例如select*from tablewhere id=),那么依然可以使用缓存,以Redis为例子,每秒可以完成数万次读写,并且提供的批量操作可以优化整个IO链的响应时间。

缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。

在这里插入图片描述


为什么会出现缓存击穿?

一般在使用缓存去缓存数据时,会使用“缓存+过期时间”的策略既可以加速数据读写,又可以保证数据的定期更新,这个模式在一般情况的业务都是可以满足的。

但是这样也会出现两个致命问题:

  1. 当前key是一个热点数据(比如:某个热门的文章,新闻),并发量非常大。
  2. 重建缓存不能在短时间完成,可能是一个复杂的计算,例如复杂的sql,多次IO,多个依赖等。

在缓存失效的瞬间,有大量线程来重建缓存,造成后端负载加大,甚至可能让应用崩溃,如果要解决这个问题至少是遵循如下:

减少重建缓存的次数

数据尽可能一致
较少的潜在威胁

缓存击穿问题解决

1 互斥锁

input("user_id"); dd(json_decode($this->getArticle(1))); } public function lock($key,$random) { $lock = Redis::set($key,$random,"nx","ex",10); return $lock; } public function unlock($key,$random) { if (Redis::get($key) == $random){ Redis::del($key); } } public function getArticle($id) { $key = "article_content_".$id; $ret = Redis::get($key); if ($ret === null) { //生成锁的key $lockKey = $key . '_lock'; //生成随机数,用于设置锁的值,后面释放锁时会用到 $random = mt_rand(); //拿到互斥锁 if ($this->lock($lockKey, $random)) { //这里是伪代码,表示从数据库中获取文章数据 $ret = json_encode(DB::table("article")->where("id",$id)->first()); //更新缓存,过期时间可以根据情况自已调整 Redis::set($key, json_encode($ret)); //释放锁 $this->unLock($lockKey, $random); } else { //等待200毫秒,然后重新获取缓存值,让其他获取到锁的进程取得数据并设置缓存 usleep(200); return $this->getArticle($id); } }else{ $ret = json_decode($ret); } return $ret; }}?>

在这里插入图片描述

2 key设置永不过期

在一定时间内进行数据更新

转载地址:http://inbe.baihongyu.com/

你可能感兴趣的文章
后缀树
查看>>
Java高性能编程之CAS与ABA及解决方法
查看>>
从BIO到Netty的演变
查看>>
《算法导论》第二章笔记
查看>>
HTML `capture` 属性
查看>>
CSS盒子模型
查看>>
HTML节点操作
查看>>
浏览器页面呈现过程
查看>>
HTML5新特性
查看>>
async/await剖析
查看>>
cmp命令
查看>>
一次编辑
查看>>
简单工厂模式
查看>>
代理模式
查看>>
Js中Currying的应用
查看>>
长按键入
查看>>
Vuex和普通全局对象
查看>>
上升下降字符串
查看>>
JavaScript中的链式调用
查看>>
day-04-列表
查看>>