Redis三大问题
缓存穿透:(数据不存在)
缓存和数据库都没有的数据,每次查询都到数据库去查,造成数据库性能浪费。
(加入缓存记得要添加过期时间)
解决:
缓存空对象 (实现简单,效果不好)
布隆过滤器 (实现复杂,效果好)
1.缓存空对象实现:
一.空对象:
没查到加入空对象到缓存中
效果:
不好,第一次访问还是会去查询数据库,更换了id去查的话也还是会去查询数据库,只能解决一个key多次访问的问题,多个key就不行。其次还会导致redis存在大量的空数据,浪费空间。
二.布隆过滤器:
应用:
导入依赖:(谷歌的)
然后就可以创建布隆过滤器对象了:(理解为java集合)
用例:
项目使用:
刚开始容器启动时初始化就将一个表中所有的数据加入到布隆过滤器上
布隆过滤器其实是一个集合对象,它只有两个方法:put()和mightContain()方法。被put()进布隆过滤器中的数据不可修改,不可删除,但是也有可能会被误判,误判概率可以自己设定的,fpp不可定为0.但是误判率越低,内存消耗就越高,反之越低。
原理:
布隆过滤器底层实现是依赖于bit数组,里面的value只有0和1.起初bit数组全为0,添加数据会经过Hash就会变成1,如:hash(“wdeh”)=56632356%len=3,所以index=3的数组位置为1.查找时也是通过hash去寻找位置知道的,如下:
误判:
所以布隆过滤器不是保存数据真正的值的,而是拿指进行hash获取到一个bit数组而已,所以没有get的方法,也不能删除,因为一个位置可能被多条数据占用。
出现误判的概率跟什么有关?
1.数组长度(影响hash冲突)
2.hash函数的个数(越多越准确,因为对应的index返回更多,一个为0则绝对不存在)
(二者相辅相成,函数越多,则数组要求更长)
redis存储字符串value就是通过bit数组存储的,二进制。
手写布隆过滤器:
@ConfigurationProperties()自动装配了值。
。。。。。
维护不好,如果表添加了数据,则同时也要添加到布隆过滤器上,删除也是,这样就要重新初始化了,所以要用定时任务进行重建。谷歌框架的布隆过滤器是使用JVM内存的,断电就会造成数据丢失。而用redis实现的是使用redis自己的内存,不会造成数据丢失。
缓存击穿:(某一条数据失效)
对于热点数据的访问:
数据库有这个数据,但是缓存没有。数据过期时间刚好过期了。所有的请求都打在数据库上了,造成数据库的瘫痪。
解决:
1.使用分布式锁
模板模式
缓存雪崩:(大部分数据统一时间失效了/redis挂了)
规避雪崩: redis搭建高可用集群(cluster)错开数据过期时间
出现雪崩: 降级 熔断
数据一致性问题
1.什么时候会出现数据不一致?更新数据的时候
两种情况:
解决1:
延时队列实现:
redis6.0后是多线程了。
集群:
哨兵模式:转移故障是选举主机,但是再这期间不可用。
高可用集群:可以让一大部分可用,一部分不可用而已。