redis三大问题 终极解决方案

缓存失效

背景:通过key查询值,先查询缓存是否存在,如果存在返回,不存在查询数据库,然后更新缓存并返回,如果数据库不存在返回null
例如:订单号是从1自增开始,如果黑客或者其他服务传参为-1或者很大的参数

缓存穿透(db和缓存都没有)

问题:

当key为一个不符合业务场景的值,缓存和数据库都不存在,外部侵入者就可以一直请求,导致数据库和缓存压力大

解决:
1、业务判断,key值大小校验,不能为空或者大于0小于10000之类的;
2、缓存和数据库查询不出来时,设置key-value为null,设置超时时间为20秒(防止查询有效数据正常无法查询),可以防止某一用户通过key攻击
3、采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力

附加

对于空间的利用到达了一种极致,那就是Bitmap和布隆过滤器(Bloom Filter)。
Bitmap: 典型的就是哈希表
缺点是,Bitmap对于每个元素只能记录1bit信息,如果还想完成额外的功能,恐怕只能靠牺牲更多的空间、时间来完成了。

布隆过滤器(推荐)

就是引入了k(k>1)k(k>1)个相互独立的哈希函数,保证在给定的空间、误判率下,完成元素判重的过程。
它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
Bloom-Filter算法的核心思想就是利用多个不同的Hash函数来解决“冲突”。
Hash存在一个冲突(碰撞)的问题,用同一个Hash得到的两个URL的值有可能相同。为了减少冲突,我们可以多引入几个Hash,如果通过其中的一个Hash值我们得出某元素不在集合中,那么该元素肯定不在集合中。只有在所有的Hash函数告诉我们该元素在集合中时,才能确定该元素存在于集合中。这便是Bloom-Filter的基本思想。
Bloom-Filter一般用于在大数据量的集合中判定某元素是否存在。

缓存击穿(单个热点key失效)

问题
缓存中没有,数据库存在,并发时都去查询数据库,导致数据库压力太大

解决
1、查询频繁的数据设置不过期;
2、限流
3、nignx层限制单个ip访问超过多次后拉黑
3、根据key做互斥锁判断,多进程使用分布式锁,见实现

缓存雪崩(多个热点key失效)

问题

缓存中大量数据达到过期时间,同时查询量巨大,导致数据库压力太大而宕机,和击穿不同在于击穿是并发查询一条过期数据,雪崩是不同的大量数据都过期了

解决
1、均匀分配redis key失效时间,防止同一时间大量数据过期现象发生;
2、分布式缓存数据库情况下,将热点数据均匀分布在不同的缓存数据库中
3、设置热点数据不过期
4、可以使用应用的一级缓存优化缓存查询
5、使用分布式锁或者本地锁保证只有一个线程在查数据库,这个方案性能太差,不推荐,小项目可以使用,但是也作为一种方案。

备注
一般避免以上情况发生我们从三个时间段去分析下:
事前:Redis 高可用,主从+哨兵,Redis cluster,避免全盘崩溃
事中:本地 ehcache 缓存 + Hystrix 限流+降级,避免MySQL 被打死。
事后:Redis 持久化 RDB+AOF,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据
上面的几点我会在吊打系列Redis篇全部讲一下这个月应该可以吧Redis更完,限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?走降级!可以返回一些默认的值,或者友情提示,或者空白的值。

你可能感兴趣的:(redis)