缓存一致性
当数据实时性要求很高时,需要保证缓存中的数据与数据库中的数据一致,缓存节点与副本中的数据一致,不能出现差异现象,这就比较依赖缓存的过期和更新策略了。一般会在数据发生更改的时候,主动跟新缓存中的数据或者移除对应的缓存,这时可能会出现缓存一致性的问题。
现象一:更新数据库成功,更新缓存失败,数据不一致。
现象二:更新缓存成功,更新数据库失败,数据不一致。
现象三:更新数据库成功,淘汰缓存失败,数据不一致。
现象四:淘汰缓存成功,更新数据库失败,查询缓存miss。
缓存并发问题
缓存过期后将尝试从后端的数据库获取数据,这时一个看似合理的流程,但是在高并发场景下,有可能有多个请求从数据库中请求数据,对后端数据库造成极大的冲击,甚至导致雪崩现象。此外当某个缓存的Key被更新时,同时也可能被大量请求获取,这也会导致一致性的问题。如何避免类似的问题?可以通过锁的机制来避免。在缓存更新或更新的情况下,先尝试获取锁,当更新或者从数据库获取数据完成后,在释放锁。其他请求只要牺牲一定的等待时间就可以从缓存中继续获取数据。
缓存穿透问题
在高并发场景下,如果某个Key被高并发访问,没有被命中,出于对容错性的考虑,会尝试从后端数据库中获取,从而导致大量的请求达到数据库,而该Key对应的数据本身就是空的情况下,就导致了数据库中并发的去执行了很多不必要的查询操作,从而导致了巨大的冲击和压力。这种情况下可以通过以下几种方式来避免缓存穿透问题:
- 缓存空对象:对查询结果为空的对象,也进行缓存,如果是集合的话,可以缓存一个空集合
- 单独过滤处理:对所有可能数据为空的Key,进行统一的存放。在请求前做拦截,这样避免请求穿透到后端数据库。这种方式实现起来相对复杂。比较适合命中不高但是更新频繁的数据
缓存的雪崩现象
请求都到后台数据库导致系统崩溃