编辑
2023-06-21
Redis
00
请注意,本文编写于 554 天前,最后修改于 549 天前,其中某些信息可能已经过时。

目录

redis常见问题
缓存穿透
缓存击穿
缓存雪崩

redis学习

  • 常见问题
  • 数据结构

redis常见问题

缓存穿透

查询一个不存在的key,数据库也查询不到,就会导致每次都去查询数据库

image.png

  • 情况:可以被人为的去请求不存在的id(如 id为0,id为不存在的数据)

解决方案

  1. 缓存空对象:当数据库也查询不到时,将null存入redis中(如:{key:-1,value:null})
    • 优点:简单
    • 缺点:可能会发生不一致的问题
  2. 布隆过滤器:将所有的key放入布隆过滤器中,查询时先查询过滤器,存在再查询redis
    • 布隆过滤器是一个bitmap(位图),利用位图检索元素是否存在集合中,先初始化一个大数组,全部都是0
    • 存储数据:将数据用多个hash函数获取hash值,将hash值计算数据对应位置改为1
    • 查询数据:利用相同的hash函数过去hash值,判断对应位置是否为1 image.png
    • 优点:内存占用少,没有多余key
    • 缺点:存在误判的情况,一般可以设置误判率不超过5%

缓存击穿

给key设置了过期时间,当key过期时有大量请求这个key,可能会把mysql压垮

image.png

解决方案

  1. 互斥锁

    线程1:请求redis,缓存中数据不存在,此时获取互斥锁(成功),然后去查询数据库重建缓存数据,写入缓存返回数据释放锁。

    线程2:请求redis,缓存中数据不存在,去获取互斥锁(此时被线程1已经获取成功获取,所以线程2获取失败),休眠一会再重试,重试过程中如果线程1已经写入,缓存命中。

  2. 逻辑过期

    线程1:查询缓存发现逻辑过期时间,获取互斥锁成功,此时开启新线程2,但是不会等待直接返回过期的数据。

    线程2:查询数据库重建缓存,写入缓存更新逻辑过期时间,释放锁。

    线程3:查询缓存,发现逻辑过期,获取互斥锁(此时线程1,已经获取互斥锁,所以此时线程3获取锁失败), 直接返回逻辑过期的数据。

互斥锁:保证数据的强一致,性能差 逻辑过期:高可用,性能优,不能保证数据同步的强一致性

image.png

image.png

缓存雪崩

大量的key再同一时段同时失效或者Redis服务宕机,导致大量请求到数据库,给数据库带来大量压力

解决方案

  • 给不同的key的失效时间添加随机值
  • 利用Redis的集群提高服务的可用性
  • 给缓存业务添加降级限流策略
  • 给业务添加多级缓存

《缓存顺口溜》

image.png