• Redis缓存雪崩、穿透、击穿,布隆过滤器,分布式锁详解


    缓存雪崩
    在某一个时间存在大量的缓存key失效
    解决办法
    1.有效期一直————>给每一个数据加上水机有效期
    2.redis挂掉了—————>使用redis集群,分摊key的存储
    在这里插入图片描述

    引出redis集群的hash一致性算法
    看我的geecache里面有讲解,需要用到哈希环,传送门

    3.不设置缓存时间,不太建议
    4.使用定时任务刷新快要过期的缓存,进行重置


    缓存穿透
    访问redis内不存在的缓存,造成直接查询数据库。给数据库造成压力。比如id=-1,一般这种在非法访问场景。非正常数据请求(黑客)

    缓存穿透不能避免,因为数据缓存是无解问题(永远不能保证一致 )不怕低频率穿透,怕高频率的。

    解决办法
    1.使用布隆过滤器
    2.非法访问,业务直接抛出
    3.这种异常key,也进行缓存存储。防止后续频繁访问数据库
    4.ip拉黑

    布隆过滤器:

    在这里插入图片描述
    过滤器放在这个位置,讲道理放在越前面越好,但是可控性得不到保障。

    过滤器里面放所有的缓存吗???
    不是,因为过滤器的缓存也很紧张

    布隆算法:通过一定的错误率来换取空间
    这句话怎么理解
    在这里插入图片描述
    100亿个数据才1.1g左右

    原理
    用bit数组来标识数据

    在这里插入图片描述

    布隆算法是由于哈希冲突导致的错误,宁可错杀三千不可放过一个

    所以我们这里就是为了降低哈希碰撞的概率提出两个办法
    1.加大数组长度
    2.增加哈希函数的个数

    第二个方法解释:
    在这里插入图片描述
    假设我们一个碰撞的概率是百分之1,我们计算出三个地方的值都为1的概率就很低了,那么概率近乎是百分之一的三次方。大大降低了碰撞概率。

    但是并不是越多越好!!!!因为越来越多就会到最后错误率一定百分百!!!

    所以函数的个数需要参考数组的长度

    算法弊端:要是我们删除数据怎么办?

    一个位置上的1可能代表几个数的哈希值,那么我们解决办法就是搞一个计数器,在第二纬度

    在这里插入图片描述
    如果计数器的值为0,那么我们可以放心的把bit数组位置上面的值变为0


    缓存击穿
    业务并发量大时,访问单一缓存key。并发查询同一数据,单一缓存key,由于过期失效。造成大量请求直接访问数据库。(拍卖场景,一般公司不需要解决,因为没有那么热门的数据让他击穿!!!!!! )

    解决办法
    1.增加分布式
    2.根据业务,判断是否需要设置为永不失效

    分布式锁详解:

    背景,都抢一个厕所:
    在这里插入图片描述
    上锁三个条件:
    1.共享资源
    2.多任务请求
    3.共享资源互斥
    必须三个条件都满足才会上锁

    死锁:
    假设马老师在厕所,但是锁门后休克了,其他人就不能获取这个厕所,这就发生了死锁

    死锁怎么解决:
    搞一个监听,如果这把锁存在的时间超出设定的最大值,我们就会把他干掉(周老师一直不应答就打120)

    但是又引来新的问题:timeout(监听)时间设置多长??
    设置短了,导致没做完就被干掉了,厕所上一半就被拉出来。(现实场景:一票多卖)。设置长了,导致资源浪费

    所以一般基于zookeeper来实现分布式锁!!!
    暂时不讲,因为我也不太懂

    那么基于分布式锁我们怎么做?

    请求先给nginx,nginx根据分发策略分发,然后查询redis数据,如果失效了,那么我们就弄一把分布式锁,抢到了先缓存在redis中,其他的就直接查redis

    在这里插入图片描述

    假设又1000条请求,只需要缓存一条就够了,其他999条可以查询

  • 相关阅读:
    2024系统架构师---论软件系统架构风格
    X86-64 汇编学习1
    Linux-信号2
    数据结构之哈夫曼树
    Python构建学生信息管理系统:需求分析与规划
    优思学院|精益六西格玛对管理者有哪些帮助?
    找到 K 个最接近的元素
    【Linux】[gdb]Linux环境下如何调试代码
    常见的编码及哈希算法
    【笔试强训day02】倒置字符串 &&排序子序列
  • 原文地址:https://blog.csdn.net/qq_52563729/article/details/126034554