面试准备
缓存模式首先要确保自己能够记住这些模式,其次要在公司内部收集一些信息:
公司有没有使用缓存模式,使用了哪些,有没有遇到过缓存一致性的问题,最后如何解决的?
业务使用了缓存后,是如何更新缓存和数据库中的数据的?有没有一致性问题?
缓存模式用的好可以有效缓解数据一致性问题,也可以用于解决缓存穿透、击穿和雪崩的问题。
缓存模式简单来说就是系统里有缓存和数据库,读写数据都要操作这两者。
基本思路
自我介绍的时候提起缓存模式的话题
我对缓存模式有比较深刻的理解,平时会用缓存模式来解决很多问题,比如缓存穿透、雪崩和击穿。
如果面试官问了解哪些缓存模式或用过哪些缓存模式
缓存模式有Cache Aside、Read Through、Write Through、Write Back、Singleflight。除此以外,我还用过删除缓存和延迟双删。
严格意义上,删除缓存和延迟双删不是缓存模式,但是在面试中比较常见,可以顺便提一下。
Cache Aside
什么都不做的时候就是Cache Aside,这个模式把缓存看作一个独立的数据源,当写入的时候,业务方来控制写入顺序。
当读取的时候也是由业务方来控制。
你先介绍读写的基本操作
Cache Aside是最基本的缓存模式,在这个模式下,业务代码就是把缓存看成是和数据库一样独立的数据源,然后业务代码控制怎么写入缓存,怎么写入数据库。一般情况下,都是优先写入数据库。
最后一句提到了优先写入数据库,那么面试官就会追问为什么先写入数据库
先写数据库是因为大多数业务场景下数据都是以数据库为准的,也就是如果写入数据库成功了,就可以认为这个操作成功了。即使写入缓存失败,但是缓存本身会有过期时间,过期后重新加载,数据就会恢复一致。
最后要加一句总结
不管是先写数据库还是先写缓存,Cache Aside都不能解决数据一致性问题。
如果面试官追问为什么都不能解决,或者有什么不一致的场景,按照图里面的内容来回答就可以。注意观察图里的线程2,是后面开始执行,但是先结束的。
Read Through
这个缓存模式叫做读穿透,核心是当缓存里没有数据的时候,缓存会代替你去数据库里面把数据加载出来,并且缓存起来。
而写入的时候,就和 Cache Aside 一样。
Read Through 也是一个很常用的缓存模式。Read Through 是指在读缓存的时候,如果缓存未命中,那么缓存会代替业务代码去数据库中加载数据。
这种模式有两个异步变种,一种是异步写回缓存,一种是完全异步加载数据,然后写回缓存。当然,不管是什么变种,Read Through 都不能解决缓存一致性的问题。
可以注意到,Read Through 只管了读的部分,而写的部分是完全没有管的,所以它的写过程和 Cache Aside 是一样的。因此,它一样有缓存一致性的问题。要是面试官追问,你就用 Cache Aside 中的分析来回答。
最后我们提到异步加载数据,也就是为了引出亮点。
亮点:异步方案
Read Through模式在发现缓存里面没有数据的时候,加载数据、缓存起来这两个步骤是可以考虑异步执行的。所以可以先回答第一个变种。
缓存可以在从数据库加载了数据之后,立刻把数据返回业务代码,然后开启一个线程异步更新缓存。
既然缓存数据这个步骤可以异步,那么从数据库中加载数据也可以异步。
第二个变种是直接让整个加载和回写缓存的过程都异步执行。也就是说,如果缓存未命中,那么就直接返回一个错误或者默认值,然后缓存异步地去数据库中加载,并且回写缓存。和第一个变种比起来,这种变种的缺陷是业务方在当次调用中只能拿到错误或者默认值。
然后你可以总结一下什么场景可以使用这两个变种。
如果业务方对响应时间的要求非常苛刻,那么就可以考虑使用变种二。代价就是业务方会收到错误响应或者默认值。而变种一其实收益很小,只有在缓存操作很慢的时候才会考虑。比如说缓存大对象,又或者要把一个大对象序列化之后再存储到缓存里面。