面试题答案
一键面试缓存更新策略
-
Cache-Aside(旁路缓存)策略
- 读操作:
- 首先从缓存中读取数据。如果缓存命中,直接返回数据。
- 如果缓存未命中,从数据库读取数据,将数据写入缓存,并返回数据。
- 写操作:
- 先更新数据库。
- 然后使缓存失效(删除缓存数据)。这样下次读取时,缓存未命中会重新从数据库加载最新数据到缓存。
- 优点:实现简单,应用程序只需要关注数据库的读写,缓存的维护相对清晰。
- 缺点:存在数据不一致的窗口期。在更新数据库后,删除缓存前,如果有读请求,会读到旧数据。
- 读操作:
-
Write-Through(直写式缓存)策略
- 写操作:
- 同时更新数据库和缓存。确保两者数据的一致性。
- 优点:数据一致性强,不存在明显的数据不一致窗口期。
- 缺点:写操作性能相对较低,因为每次写操作都需要同时操作数据库和缓存,增加了系统的负载。
- 写操作:
-
Write-Behind(异步写回)策略
- 写操作:
- 只更新缓存,将更新数据库的操作异步化。通常会使用队列等方式来批量处理数据库更新。
- 优点:写操作性能高,因为不需要等待数据库更新完成。
- 缺点:数据一致性最差,如果系统出现故障,缓存中的数据还未同步到数据库,可能会丢失数据。
- 写操作:
可能遇到的问题及解决方案
-
缓存雪崩
- 问题描述:大量的缓存数据在同一时间过期,导致大量请求直接打到数据库,使数据库压力骤增,甚至可能导致数据库崩溃。
- 解决方案:
- 为缓存设置不同的过期时间,避免集中过期。可以在设置过期时间时,加上一个随机值,例如原本过期时间为1小时,可设置为1小时加上0到10分钟的随机值。
- 使用热点数据永不过期的策略,但需要定期在后台更新缓存数据。
-
缓存穿透
- 问题描述:查询一个不存在的数据,每次都绕过缓存直接查询数据库,若有大量这种请求,会给数据库造成压力。
- 解决方案:
- 使用布隆过滤器(Bloom Filter)。在查询前,先通过布隆过滤器判断数据是否存在,如果不存在则直接返回,避免查询数据库。
- 对查询结果为空的数据也进行缓存,但设置较短的过期时间,这样下次查询同样的数据时,可直接从缓存返回空结果。
-
缓存击穿
- 问题描述:一个热点数据在缓存过期的瞬间,大量请求同时访问,这些请求全部打到数据库,导致数据库压力过大。
- 解决方案:
- 对于热点数据,使用互斥锁(如分布式锁)。在缓存过期时,只允许一个请求去更新缓存,其他请求等待,待缓存更新完成后,其他请求直接从缓存读取数据。
- 不设置热点数据的过期时间,通过后台定时任务或者数据变更时主动更新缓存。