面试题答案
一键面试常见缓存过期策略及其工作原理
- 定时过期
- 原理:为每个缓存设置一个固定的过期时间,当到达该时间点时,缓存项就会被标记为过期。例如,在Memcached中,使用
set key value exptime
命令设置缓存时,exptime
就是过期时间(以秒为单位)。当系统检查到缓存项的过期时间已到,会将其从缓存中删除或标记为不可用。
- 原理:为每个缓存设置一个固定的过期时间,当到达该时间点时,缓存项就会被标记为过期。例如,在Memcached中,使用
- 惰性过期
- 原理:缓存项在设置时同样有过期时间,但系统不会主动去检查是否过期。只有当客户端尝试访问该缓存项时,系统才会检查其是否过期。如果过期了,就从缓存中删除该项,并返回空值或错误信息给客户端。比如在Memcached中,当客户端执行
get key
操作时,如果缓存项已过期,Memcached会先删除该过期项,然后告知客户端没有找到对应的值。
- 原理:缓存项在设置时同样有过期时间,但系统不会主动去检查是否过期。只有当客户端尝试访问该缓存项时,系统才会检查其是否过期。如果过期了,就从缓存中删除该项,并返回空值或错误信息给客户端。比如在Memcached中,当客户端执行
- 定期过期
- 原理:系统每隔一定的时间间隔,随机从缓存中取出一定数量的缓存项进行过期检查。对于过期的缓存项,将其从缓存中删除。这种方式不需要对每个缓存项进行实时监控,降低了系统开销。在Memcached实现中,虽然没有明确提到定期过期策略,但类似机制可能存在于其内部管理逻辑中,以控制内存使用和过期项清理。
避免缓存雪崩问题的方法
- 设置随机过期时间
- 方法:在设置缓存过期时间时,不使用固定的过期时间,而是在一个合理的时间范围内设置随机的过期时间。例如,原本所有缓存都设置为1小时过期,现在可以设置为50分钟到70分钟之间随机的过期时间。这样可以避免大量缓存项在同一时间过期,减少缓存雪崩发生的概率。
- 使用二级缓存
- 方法:主缓存使用Memcached,二级缓存可以使用本地缓存(如Guava Cache等)。当主缓存过期时,先从二级缓存获取数据。如果二级缓存中有数据,则直接返回给客户端,同时启动一个异步任务去更新主缓存。这样可以在一定程度上缓解大量请求直接冲击后端数据源的压力。
- 加锁排队
- 方法:当缓存过期后,大量请求同时访问时,使用分布式锁(如Redis的SETNX命令实现的锁)。只有获取到锁的请求可以去后端数据源获取数据并更新缓存,其他请求则等待。获取锁失败的请求可以睡眠一段时间后重试,直到获取到数据。这种方式可以避免过多请求同时访问后端数据源,防止数据库压力过大而崩溃。
- 缓存预热
- 方法:在系统上线前或缓存大量过期前,提前将部分热点数据加载到缓存中,并设置合理的过期时间。这样可以避免系统刚启动或缓存过期后,因大量数据未在缓存中而导致的缓存雪崩。例如,在应用启动时,通过批量查询数据库,将热点数据预先加载到Memcached中。