13redis缓存的问题与解决方案
缓存有诸多问题,比如
- 数据库数据更新了,但是缓存中数据未更新,导致数据不一致
我们现在需要解决一下这些问题
1.缓存更新策略
缓存更新策略有以下几种

内存淘汰说白了就是等内存占满了,系统自动清除一些时间靠前的
超时剔除就是给数据加有效期,比如30分钟,30分钟过了,就自动销毁
主动更新是自己在代码中完成更新。
对于数据一致性要求不高的数据,使用内存淘汰、超时剔除就行,对于数据一致性要求高的数据才需要使用主动更新,但是实话实说,对于数据一致性比较高的服务,比如支付服务,不建议使用缓存。
主从更新又有三种实现方法

上面02就是直接有一个模块负责缓存和数据库的读写,02的问题是这个服务很复杂,难以实现。
上面03就是用户只读写缓存,然后每隔一段时间之后缓存异步更新到数据库,03的问题是如果缓存中的内容还未更新到数据库时,服务器宕机,会导致数据的丢失,这个影响很严重。
综上分析,还是01自己写代码靠谱
01自己写代码有个需要注意的点,就是对于并发情况下,先删除缓存、再操作数据库;先操作数据库,再删除缓存,这两种方法均有可能出现缓存和数据库的数据不一致的问题(如下图)。但是先更新数据库再删缓存出问题的可能性小。

2.缓存穿透问题
缓存穿透指的是有个不怀好意的人,故意请求一个根本不存在的数据,reids中查询后没有,就去查数据库,数据库也没有,就返回空,但是因为数据库没有,所以redis缓存中也就不存储了。然后这个人反复查询这个不存在的数据,就会一直能透过redis缓存,直接访问数据库,占用数据库性能。
常见解决方法:
1.缓存空对象,在redis中缓存一个值为null的键值对,设置ttl,一段时间后过期。
2.布隆过滤,使用布隆过滤器先判断数据是否存在。布隆过滤器中并不是把所有数据都存储了,而是基于哈希算法,每个数据1位,0表示不存储,1表示存在,这样就能方便地存储与查询,但是布隆过滤器不一定100%准确,所以建议使用缓存空对象,简单方便。

3.缓存雪崩

限流我们之前已经使用Sentinel做了,Redis集群、多级缓存都可以有效解决缓存雪崩,这些后边的项目会进行部署,这里暂时跳过
4.缓存击穿


