客户端请求数据时,服务端先在缓存中查询数据,缓存中存在时直接返回数据。缓存中不存在时,去数据库中查询数据,数据库中存在时,更新缓存并返回数据;数据库中不存在时,直接返回空数据。
Redis 是一个不错的缓存数据库。
缓存穿透
穿透意为每次请求跳过缓存直接在数据库中查询。当客户端请求的数据在缓存和数据库中都不存在时,会出现“穿透”现象。
由于每次请求不存在的数据都会查询数据库,数据库每次都需要遍历整个表才能确定数据不存在,这实际上是一种无意义的行为,当短时间内有大量这种请求时数据库可能就会挂掉。
解决方案
- 接口层增加校验,如用户鉴权、对字段做基本的检验和拦截;
- 缓存数据库中不存在的数据,但是需要注意缓存有效时间应该短一点,以避免影响正常使用;
- 布隆过滤器:快速确定大型集合中是否包含某个值,概率型过滤器;
- ……
缓存击穿
对于热点数据,如果缓存数据意外 过期,此时会直接在数据库中查询,引起数据库压力瞬间增大。
击穿的往往是某一个点,出现在大量并发查询某一个或者某几个数据时。
解决方案
- 延长热点数据过期时间,或者设置为永不过期;
- 限流:短时间内某个请求速度达到阈值进行拒绝、排队等待或者降级等处理
- 熔断:当服务出现问题时,需要暂时屏蔽掉接口,等到高峰或者问题解决后再启用;
- 降级:切换到更简单、对性能影响更小的备用接口;
- 加锁:根据情况限制并发访问数据库的线程;
- ……
缓存雪崩
出现在缓存中 大量数据同时到期 后造成的大量数据需要到数据库中查询,从而引起数据库压力过大。
缓存雪崩发生在大量不同数据到期但是被查询时,缓存击穿发生了某个或者某几个数据到期但是被大量并发查询时。
解决方案
- 缓存过期时间设置随机,防止大量数据同时过期;
- 如果是分布式数据库,将热点数据均匀分布到不同机器上;
- 设置热点数据永不过期;
- ……
评论区