目录
开场白-追命3连
-
看你项目中有说用到Redis,都是哪些场景使用了Redis呢?
-
如果发生了缓存穿透、击穿、雪崩如何应对呢?缓存中数据的持久化和双写一致怎么实现的呢?数据过期和淘汰策略了解么?
-
能说说Redis实现分布式锁的方案和原理么?
使用场景
01缓存穿透场景与方案
使用缓存是一种常见的性能优化和数据管理策略,它可以带来许多好处:
-
提高性能:缓存允许将常用或重复访问的数据存储在快速访问的位置,通常是内存中。这可以大大减少从慢速数据存储系统(如数据库)中读取数据的次数,从而显著提高应用程序的响应时间和性能。
-
减少资源消耗:读取和计算数据通常需要消耗计算资源和网络带宽。通过将结果缓存,可以减少这些资源的消耗,提高系统的效率。
-
降低数据库负载:数据库是许多应用程序的关键数据存储,频繁的数据库查询可以增加数据库的负载。通过缓存常用查询结果,可以减轻数据库的压力,提高数据库的可伸缩性。
-
减少网络延迟:从远程数据源(如云存储或远程API)获取数据通常需要较长的网络延迟。通过使用缓存,可以将数据放置在更接近应用程序的位置,从而降低网络延迟。
-
提高可伸缩性:使用缓存可以降低后端数据存储的压力,从而使应用程序更容易扩展,支持更多的用户和请求。
-
应对高并发:在高并发的情况下,数据库或其他数据源可能无法及时响应请求。缓存可以缓解这种情况,因为它可以快速提供响应,而不必等待慢速数据源的响应。
-
提高用户体验:快速加载和响应时间可以显著提高用户体验,减少等待时间,增加用户满意度。
-
实现断点恢复:在某些应用中,缓存可以用于存储临时状态或进度,以支持断点续传或恢复操作,如文件上传或长时间运行的任务。
-
保护后端资源:通过缓存来限制对某些资源的访问,可以防止滥用或意外的流量对后端资源的过度消耗。
-
离线访问:缓存可以支持离线访问,使应用程序在没有连接到主要数据源时仍能够提供基本功能。
缓存穿透是一种缓存相关的性能问题,指的是恶意请求,通过访问缓存中不存在的数据,大量频繁地请求数据库连接,消耗资源。缓存穿透的明显特征:恶意大量大规模地请求不存在的数据。
解决方案1:针对不存在的数据,使用null存入缓存。
-
优点:方案方便简单
-
缺点:会消耗大量的内存,有可能引起数据不一致的问题(缓存null的同时插入了真实值,数据就不一致了)
解决方案2:使用布隆过滤器拦截
-
优点:内存占用少,没有多余key
-
缺点:设计方案稍微复杂,存在误判
02布隆过滤器
布隆过滤器是一种用于快速检测某个元素是否存在于集合中的数据结构。在缓存层之前使用布隆过滤器,可以快速拦截那些明显不存在于数据源中的请求。在系统启动或数据更新后,就可以预热缓存,将热门数据加载到缓存中。
布隆过滤器实质上是一种位图(bitmap):相当于是一个以(bit)位为单位的数组,数组中每个单元只能存储二进制数0或者1。
-
存储数据:通过多个hash函数获取hash值,根据hash计算数组对应位置改为1
-
查询数据:使用相同hash函数获取hash值,判断对应位置是否都为1
误判:当查询并不存在的“武侯区”时,会返回错误的判断结果。
误判率:数组越小误判率越高,数组越大误判率越低,但越大的数组就带来了越多的内存消耗。(使用布隆过滤器的情况下默认允许误判率小于等于5%)
03缓存击穿场景与方案
缓存击穿是指:当一个缓存key设置了过期时间,而在过期的那一瞬间有大量并发请求同时访问这个key,导致请求穿透缓存直接访问数据库,而这个瞬间是有可能把数据库压垮的。
缓存没有命中查询数据库之后不是会写入缓存么?——缓存击穿的瞬间就是发生在这个写入的间隔时间内,哪怕只是10ms
解决方案1:互斥锁,在缓存中设置一个互斥锁,用于保护数据的加载过程,同时避免多个请求并发操作数据。
-
优点:强一致性
-
缺点:互斥锁导致资源消耗,性能差
解决方案2:逻辑过期,设置热门数据的缓存永不过期,或者设置一个很长的过期时间,以确保数据不会频繁失效。
-
优点:高可用性,性能好
-
缺点:不能保证保证数据绝对一直
04缓存雪崩场景与方案
缓存雪崩是指在某个时间点,缓存中的大量数据同时失效或过期,导致大量请求直接访问后端数据源,对后端系统造成巨大压力的情况。缓存雪崩通常发生在以下场景:
-
大规模数据同时过期:在某个时间点,大量缓存数据的过期时间到达,导致这些数据在短时间内同时失效。
-
系统重启:当系统重新启动或缓存服务重启时,所有缓存数据都会失效,导致大量请求访问后端数据源。
-
热门数据失效:缓存中的热门数据在某个时间点过期,因此大量请求同时访问这些数据。
解决方案1:针对过期时间->通过随机设置缓存数据的过期时间,避免大量数据同时过期。
解决方案2:针对Redis宕机->采用集群的方式部署Redis服务。
解决方案3:针对热门数据失效->在系统启动或低峰期,对热门数据进行预加载到缓存中,以降低高峰时段缓存失效的风险。
解决方案4:使用多级缓存方案,本地缓存+分布式缓存。
解决方案5:兜底策略->限流降级或者熔断,在高峰期对请求进行限流,确保不会过多请求直接访问后端。