共计 1008 个字符,预计需要花费 3 分钟才能阅读完成。
缓存三兄弟
缓存三兄弟一般指:缓存穿透
、缓存击穿
和缓存雪崩
。这三类问题一般在高并发
的场景上出现。
一、缓存穿透
介绍
缓存穿透是指查询一个数据库中不存在的数据,导致每次查询都会命中数据库而非 Redis,并且查询到的结果也不会写入到 Redis 中。如果黑客通过搜索大量不存在的数据时,就可能会对数据库直接造成压力从而使数据库瘫痪。
因为查询的数据在数据库中不能存在,自然而然的就无法将查询到的结果缓存到 Redis 中。
解决方案
方案一
缓存空数据,如果查询到的结果为空,则也将查询结果写入到 Redis 中,并设定一定的过期时间,避免下次查询再对数据库进行访问。
优缺点
- 优点:
- 实现简单
- 缺点:
- 消耗内存
- 可能出现数据不一致问题
方案二
使用布隆过滤器(Bloom Filter)。布隆过滤器是一种用于判断一个元素是否属于一个集合的数据结构。它通过使用多个哈希函数和一个位数组来实现这一目标。布隆过滤器的主要特点是可以快速地判断一个元素是否可能存在于集合中,但可能存在一定的误判率。
当进行查询时,会先判断查询的key
是否存在于布隆过滤器中,如果存在,则会访问缓存或数据库,否则直接返回空。
优缺点
- 优点:
- 内存占用较少,没有多余 Key
- 缺点:
- 实现复杂,存在误判
二、缓存击穿
介绍
缓存击穿是指:缓存中的数据在某个时间段过期了,与此同时有大量请求对该数据进行查询,导致所有的请求都打在数据库中使得数据库瞬间崩溃。
解决方案
方案一
查询缓存时若未命中,则获取互斥锁对缓存进行重建。
这种方案可以保证数据的强一致性,但同时会造成整个系统的性能低下。
方案二
在缓存中不设置过期时间,而是设置逻辑过期时间(添加一个字段来表示过期时间)。查询缓存时发现逻辑过期时间已过期,则获取互斥锁,并开启新线程(查询数据库,将数据写入缓存时重置逻辑过期时间,释放锁),并直接返回过期数据。
这种方案具有高可靠性并且性能较优。
三、缓存雪崩
介绍
缓存雪崩是指在某一时段大量的缓存 Key 失效或者 Redis 宕机,导致大量的请求直接打到数据库造成数据库压力剧增或崩溃。
解决方案
方案一(解决同一时段大量 Key 失效)
给不同 Key 设置不同的过期时间,降低某个时间段大量 Key 同时失效的可能性。
方案二(解决 Redis 宕机)
- 搭建 Redis 集群,提高服务的高可用性。哨兵模式、集群模式;
- 给缓存业务添加降级限流策略(保底策略)。
Nginx
、Gateway
. - 给业务添加多级缓存。
Guava
或Caffeine