• Redis做缓存的几种模式以及缓存雪崩、缓存击穿、缓存穿透分别是什么,怎么解决


    怎么做

    缓存可以建立在客户端也可以建立在服务端(注意这里是广义的客户端、服务端,服务A向服务B发请求,那么A就是客户端

    理论上来将每个服务端都应该给自己建立缓存,因为微服务要有一定的互不信任原则(请求先到你,你做过校验了,我不一定信)

    四种模式

    cache aside(旁路缓存)

    最常用方式,就是先去看缓存有没有,有就返回,没有就去数据库读。
    写的话直接写数据库去,然后删除缓存。
    为啥不更新缓存而是删除缓存? 因为更新容易造成时序性问题:
    thread1更新mysql为4 -> thread2更新mysql为2 -> thread2更新缓存为2 -> thread1更新缓存为4

    read through

    起一个中间服务,客户端就查你这个代理,不知道查的是缓存还是数据库。一切和缓存、数据库的交道都由这个代理来做。

    write through

    也是起了一个中间服务,只要发起写请求,代理就直接写数据库,然后同步更新redis。一般和read through搭配使用。
    但这个对缓存压力比较大,只要更新了数据就得一同更新redis,对比旁路缓存是删除缓存数据的

    write behind

    和write through一样,只不过写完数据库不立即写缓存,而是异步的写缓存(找一个合适时间点,比如低负载时候;或者累计几个一并写入)。

    缓存穿透

    缓存和数据库都没有这个数据,一般是被攻击了,有人频繁查询不存在的key。
    解决方法:

    • 接口层设置校验,key异常的直接拦截
    • 缓存和数据库都没有的数据,在缓存里写key-null,然后设置一个较短的过期时间,比如30s(防止之后真有这个key写进数据库了,缓存数据还是null)
    • 布隆过滤器。一个key会被多个hash函数映射,假设这些位置都被点亮认为这个数据可能是存在的,可以去数据库查一下。要是有的hash位置没被点亮,就是拒绝。这样对时间空间都好,就是不完全准确。

    缓存击穿

    缓存没有,数据库有。通常是某一时刻,一个热点数据过期,恰好此时并发用户特别多来访问这个数据,结果都打到数据库上了。
    解决方法:

    • 被持续访问的数据适当延长过期时间
    • 加互斥锁,多线程来发现缓存没有,就会竞争去数据库查。只有一个线程去查了,查完更新缓存,其他线程直接查缓存了就。

    缓存雪崩

    缓存没有数据库有。通常是缓存中大批数据同时过期了,而这时候大量查询过来了,让数据库压力过大甚至宕机。
    解决方法:

    • 设置随机过期时间,别一起过期
    • 加互斥锁,多线程来发现缓存没有,就会竞争去数据库查。只有一个线程去查了,查完更新缓存,其他线程直接查缓存了就。

    缓存一致性问题

    就是redis和mysql数据不一致了,主要有三种方式。但其实兜兜转转说一堆假设产品对一致性要求极高,尽量别用缓存

    mysql更新后不管redis,靠过期时间兜底

    实现起来成本低,但是这就得容忍一段时间的数据库和缓存不一致问题了。

    mysql更新后,操作redis

    操作分为两种一种是更新另一种是删除,更倾向于使用后一种。假设删除失败了,会退化成第一种方案。

    异步将mysql的更新同步给redis

    redis作为mysql一个slave,订阅mysql的binlog日志,解析日志后更新回redis。这种方式要搭建一个同步服务,成本大一点,但是解耦了,更新mysql后不需要做额外的工作,比较适合数据过期时间长甚至是不过期的场景(这是原因,是因为这种场景,才会用到这种订阅binlog模式)

  • 相关阅读:
    谷氨酸三方突触丨SYSY谷氨酸GluA解决方案
    AAC 音频数据结构实例分析:
    论文解读(ValidUtil)《Rethinking the Setting of Semi-supervised Learning on Graphs》
    d唐的导入C的经验
    C认证笔记 - 计算机通识 - 多媒体基础参数
    C++ 提高编程
    模拟浏览器与服务器交互(简易TomCat框架)
    XML小讲
    Python 共享内存之 shared_memory
    身价翻 300 倍!4GB 的初代 iPhone 拍出 136 万天价!
  • 原文地址:https://blog.csdn.net/pige666/article/details/136249089