缓存最终的目的是为减轻服务端压力,减少网络传输请求
- 页面缓存
- 浏览器缓存
- App客户端缓存
- 代理缓存
- CDN缓存
- 数据库缓存
- 平台缓存级缓存
设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩
- 锁
- 比如对某个key只允许一个线程数据库查询数据和写缓存,其他线程等待
- 但是这样就只能限制同一时间只能有一个线程访问数据库,吞吐量还是不行
- 消息中间件
- 缓存中间件没有命中的情况下,生产者将数据库查询请求通过消息中间件发送给消费者,消费者查询数据库后再返回给生产者,生产者再返回给客户端
- 使用多级缓存
- 分析用户的行为,尽量让缓存失效的时间均匀分布
指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空。这样就会导致每次查询不存在的数据都会绕过缓存去查询数据库
把空结果,也给缓存起来,这样下次同样的请求就可以直接返回空了,即可以避免当查询的值为空时引起的缓存穿透
对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题
- 锁
- 不设置过期时间,而将过期时间设置在数据中,如果检测到数据过期了,再清除掉