0%

redis缓存穿透和缓存雪崩问题

redis缓存穿透和缓存雪崩问题

缓存穿透

请求缓存中不存在的数据,导致所有的请求都到数据库中去查询,导致数据库压力过大

解决:

  • 如果数据库不存在,也设置一个默认值放入缓存,这样第二次到缓存中获取就有值了,不会继续访问数据库

  • 利用互斥锁,缓存中没有,先获取锁,再去请求数据库,没有获取到锁的,先等待在进行重试

  • 利用布隆过滤器,类似于一种哈希表,用所有可能的值生成一个bitmap,内部维护一系列合法有效的key进行拦截,如果不合法直接返回,guava中有实现BloomFilter

缓存雪崩

缓存同一时间大量失效,导致大量请求直接访问数据库,从而导致数据库压力倍增

  • 在设置缓存时间时,加上一个随机值,避免集体失效[无法解决热点数据问题(同一时刻访问同一条数据)]
  • 只让一个线程构建缓存,其他线程等待构建缓存的线程执行完,重新从缓存中获取数据,保证了每个时刻只有一个线程在执行请求,但是会导致很多线程在等待一个线程,降低了系统的qps
  • 双缓存,缓存1中设置过期时间,缓存2中在启动时加载,进行缓存预热,先访问缓存1,如果有值则返回;缓存1没有值,则访问缓存2,返回数据,并启动异步更新线程来同时更新缓存1和缓存2的数据,如果value特别大的话会占用很多内存,内存利用率低
  • 在缓存失效后,加锁来限制访问数据库,只允许一个线程去查询数据和写缓存,双重检查,减少数据库访问次数,但是会造成部分请求等待