一、redis在项目中的运用主要如下图:
:如果用户端发送key请求中在redis中能找到相应的key,就直接将redis中对应的value返回给客户端,如果在redis中没有相应的value就到mysql中找到相应的数据,再将这些数据写入redis缓存中,下次再遇见key请求时直接到redis中查找并返回。
二、这种方式就会出现缓存穿透、雪崩和击穿等问题
2.1、缓存穿透
缓存穿透:客户端大量请求key为null的请求。
产生原因:由于key为null,在redis中无法查找到,这些请求就会全部到MySQL,导致MySQL压力过大,导致MySQL卡死或者宕机。
解决方案:
1、当key请求到MySQL找不到数据时,我们可以将这个key,写入redis中,并将value设置为null,下次请求这个Key时,就会到redis中查找。减少MySQL的压力。
缺点:redis是基于内存的数据库,当向redis写入大量value为null时,浪费内存。
2、使用布隆过滤器。 使用BitMap作为布隆过滤器,将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中(哈希计算),当一个请求来临的时候先进行布隆过滤器的判断,如果有那么才进行放行,否则就直接拦截。
3、请求校验。对value为null的请求进行相应的拦截。不允许这个请求请求redis和MySQL中的资源。
4、实时监控。发现redis命中率在下降的请求,但还持续发出请求的客户端,查找相应的原因,并将这个这样客户端放到黑名单。
2.2、缓存雪崩
原因:redis中存在大量过期的key。
例子: 当redis中的大量key集体过期,可以理解为redis中的大部分数据都被清空了(失效了),那么这时候如果有大量并发的请求来到,那么redis就无法进行有效的响应(命中率急剧下降),请求就都打到MySQL上了,到时MySQL直接崩溃。
解决方案:
- 设置key的过期时间。
- 分布式锁(效率低下)
- 设置缓存标记,当发现key过期时在MySQL中刷新。
2.3、缓存击穿
原因:redis中一个热点key过期(大量用户访问该热点key,但是热点key过期)
和缓存穿透类似:原理都是在redis中找不到key,导致大量的请求到MySQL中,区别缓存穿透大多数是恶意攻击。而缓存击穿大多数是系统没有及时更新redis。
解决方案:
- 提前将热点数据,写入到redis中。
- 使用锁。
- 实时监控数据。查看热点词汇是否过期,