目录
什么是缓存
使用redis作为mysql的缓存
缓存的更新策略
定期生成
实时生成
缓存预热
缓存穿透
缓存雪崩
缓存击穿(瘫痪)
缓存的核新思路就是把⼀些常用的数据放到触手可及(访问速度更快)的地方,方便随时读取。
比如我们一般都把钱存在银行,并且会拿出一部分出来放在自己的钱包里用来日常开销,那么这个钱包就相当于银行的缓存,我们为了不每次用钱的时候都去银行取,所以用个钱包在钱包里放一部分钱要使用的时候直接从钱包里拿(不考虑电子支付)。
对计算机来说,速度往往和存储空间是成反比的,访问速度越快存储空间越小,redis是读内存的访问速度要比Mysql快但空间也比mysql小很多,所以一般缓存里只会放一些(热点数据)会频繁访问的数据。虽然只放一些热点数据,但是也已经能应付大部分的情况了。
二八定律
这是一个经验规律,就是20%的热点数据能够应付80%的访问场景,所以只需要把少量热点数据用缓存存储起来,就可以应对大多数场景了。
像mysql这样的关系型数据库,虽然功能强大但是效率一般不高,处理并发能力也较弱因为
如果某一时刻并发量太大超过了数据库所能承担的极限,那么数据库的压力就会很大就容易出问题。想要提高数据库的并发量有两种方法
而redis就具有很好的处理缓存的功能因为,redis的数据保存在内存上访问速度较快,而且redis只是简单的键值对存储,不会涉及复杂的查询规则,将redis用作mysql的缓存就可以很好的帮助mysql分担很大一部分并发量。
策略:每隔一定的周期(一天/一周/...),对于访问的数据的频率进行一个统计,挑选出前N%频率的数据作为热点数据保存在缓存中。
可以使用shell或python写一个脚本通过定时任务来触发
- 完成统计热热点数据
- 根据热点数据,找到对应的结果
- 把得到的缓存同步到缓存服务器上
- 控制这些缓存服务器重启
这种方法的优点就是,操作比较简单过程更为可控(缓存中有什么是比较固定的),方便排查问题
缺点就是,实时性不够,如果遇到一些突发事件,有一些数据突然变成热点数据,那么新的热点数据就有可能给数据库造成较大压力。
策略:如果在redis中查到了就直接返回,如果没有查到,就从数据库中查,然后再把查到的结果也写入redis中。
虽然这种方法的实时性比定期生成好,但是不断的向redis中写入数据,就会让内存空间越来越小最后达到上限(redis的空间上限不一定就是内存空间,可以通过设置maxmemory属性来决定给redis分配多少内存空间)。
所以针对上述问题,就需要进行内存空间的淘汰给一些不需要的数据淘汰掉。
淘汰的策略有以下几种:
这些淘汰策略并不局限于redis,其他缓存也可以这样展开
下面是redis内置的淘汰策略:
整体来说Redis提供的策略和我们上述介绍的通策略是基本⼀致的,只不过Redis这里会针对过期
key和全部key做分别处理。
如果缓存中的数据是实时更新,那么当redis服务器首次接入后,里面是没有数据的,所以此时所有请求都会发送给mysql,可能会给mysql带来很大的压力。
缓存预热就是用来解决上述问题
通过把定期生成和实时生成结合,先通过离线的方式,统计一批热点数据,然后导入redis中,这是导入的热点数据就可以帮助mysql承担很多压力了,最后随着时间的推移,刚开始的热点数据慢慢被新的热点数据替代。
当请求查询某个key时,redis和mysql中都没有,那么这个key也不会被更新到缓存中,所以这种请求都会被打给mysql,如果存在很多这样的请求,就会给mysql带来很大的压力。
引起这种问题的原因可能是:
解决方法
更改业务逻辑,加强监控捕捉
由于在短时间内redis上的key大规模失效,或者redis直接宕机,导致缓存命中率下降,导致大量请求到达数据库,带来巨大压力。
key大规模失效的原因可能时之前短时间内给大量的key设置了相同的过期时间
解决方法
缓存击穿也叫热点key问题,相当于缓存雪崩的特殊情况,就是正对热点key突然过期了,而且此时又有大量的请求过来,就会导致这些请求都直接访问到mysql上,给mysql产生极大压力甚至宕机。
解决方法