本文为转载整
1. 缓存命中
缓存命中(cache hit):当应用程序或软件请求数据时,会首先发生缓存命中。首先,中央处理单元(CPU)在其最近的内存位置(通常是主缓存)中查找数据。如果在缓存中找到请求的数据,则将其视为缓存命中。
而在Redis中的缓存命中为:
用户的数据一般都是存储于数据库,数据库的数据是落在磁盘上的,磁盘的读写速度可以说是计算机里最慢的硬件了。
当用户的请求,都访问数据库的话,请求数量一上来,数据库很容易就奔溃的了,所以为了避免用户直接访问数据库,会用 Redis 作为缓存层。
因为 Redis 是内存数据库,我们可以将数据库的数据缓存在 Redis 里,相当于数据缓存在内存,内存的读写速度比硬盘快好几个数量级,这样大大提高了系统性能。
2. 缓存穿透
指查询一个数据库一定不存在的数据。
正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。
假如有恶意攻击,就可以利用这个漏洞,对数据库造成压力,甚至压垮数据库。
2.1. 解决方案
2.1.1. 缓存空对象
- 如果数据库查询对象为空,就缓存空对象,再次访问这个数据,就会从缓存中获取,以此保护后端数据源。
- 如果缓存NULL,是做无用功,还是会造成缓存穿透。
- 缓存空对象遇到的两个问题:
- 如果是网络恶意攻击(每次key不一样,且数据库不存在)
- 缓存占用了更多的内存。
2.1.2. 使用布隆过滤器
3. 缓存击穿
是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。
4. 缓存雪崩
指在某一个时间段,缓存集中过期失效。
当某一个时刻出现大规模的缓存失效的情况,那么就会导致大量的请求直接打在数据库上面,导致数据库压力巨大,如果在高并发的情况下,可能瞬间就会导致数据库宕机。这时候如果运维马上又重启数据库,马上又会有新的流量把数据库打死。这就是缓存雪崩。
4.1. 造成缓存雪崩的原因是什么?
造成缓存雪崩的关键在于在同一时间大规模的key失效。
为什么会出现这个问题呢,有下面几种可能:
- 第一种可能是Redis宕机,
- 第二种可能是采用了相同的过期时间。
4.2. 解决方法
4.2.1. 过期时间设置随机值
在原有的失效时间上加上一个随机值,比如,1-5分钟随机。这样就避免了同一时间大量数据过期现象的发生而导致缓存雪崩。
4.2.2. 分布式部署且均匀分布热点数据
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。同时,分布式集群可以防止Redis宕机导致缓存雪崩的问题。
4.2.3. 热点数据永不过期
设置热点数据永远不过期。
5. 总结
缓存雪崩和缓存击穿主要是数据不在缓存上,而缓存穿透是数据既不在缓存上,也不在数据上。
5.1. 缓存穿透的解决方法:
- 入口进行合法性验证
- 缓存空值或者缺省值
- 使用布隆过滤器快速判断
5.2. 缓存击穿的解决方法:
- 不设置过期时间
- 加互斥锁
5.3. 缓存雪崩的解决方法:
- 给过期时间加上小的随机数
- redis 设置主从集群