送你一份大厂都这么解决Redis缓存问题,面试官必问!

一、 什么是缓存雪崩?如何避免和解决?

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

避免方法:

1.在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待。

2.做二级缓存,A1 为原始缓存,A2 为拷贝缓存,A1 失效时,可以访问 A2,A1 缓存失效时间设置为短期,A2 设置为长期。

3.不同的 key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

解决方案:

1.更新策略在时间上做到比较均匀

2.使用的热数据尽量分散到不同的机器上

3.多台机器做主从复制或者多副本,实现高可用

4.实现熔断限流机制,对系统进行负载能力控制

5.在原有失效时间基础上增加一个随机值,比如1~5分钟的随机,这样每个缓存的过期时间重复率就会降低,集体失效概率也会大大降低。

二、什么是缓存穿透?如何避免和解决?

一般的缓存系统,都是按照 key 去缓存查询,如果不存在对应的 value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的 key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

例如:访问id=-1的数据。可能出现绕过Redis依然频繁访问数据库,称为缓存穿透,多出现在查询为null的情况不被缓存时。

避免方法:

1.对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该 key 对应的数据 insert 了之后清理缓存。

2.对一定不存在的 key 进行过滤。可以把所有的可能存在的 key 放到一个大的 Bitmap 中,查询时通过该 bitmap 过滤。

解决方案:

1.缓存空值的KEY,这样第一次不存在也会被加载会记录,下次拿到有这个KEY

2.Bloom过滤或RoaringBitmap 判断KEY是否存在

最常见的布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

3.完全以缓存为准,使用 延迟异步加载 的策略2,这样就不会触发更新。更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过5min。

三、什么是缓存击穿?如何解决?

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

解决方案:

1.当数据库和redis中都不存在key,在数据库返回null时,在redis中插入当key再次请求时,redis直接返回null,而不用再次请求数据库。

2.可以设置一些过滤规则, 如布隆过滤器。将数据库中所有的查询条件,放入布隆过滤器中,当一个查询请求过来时,先经过布隆过滤器进行查,如果判断请求查询值存在,则继续查;如果判断请求查询不存在,直接丢弃。

猜你喜欢

转载自blog.csdn.net/sgw827/article/details/114306094