缓存更新之 Cache Aside Pattern

Cache Aside 模式可能是最常用的缓存更新方法。使用这种方法,你的应用程序直接与缓存和数据库打交道,也就说,你的代码负责协调缓存和真实数据源之间的数据流向。

读数据

读数据的具体逻辑如下:

  1. 应用程序首先检查缓存。
  2. 如果在缓存中找到数据『缓存命中』,数据被读取并返回给客户端。
  3. 如果在缓存中未找到数据『缓存未命中』,应用程序查询数据库以读取数据,并读取到的数据返回客户端,同时将数据存储在缓存中。这样一来,后续读取相同的数据就会命中缓存。

更新数据

更新数据(Update,Insert,Delete)时,应用程序会先把数据存储到数据库中,成功后,再让缓存失效。

思考:为什么在更新数据时,是让缓存失效,而不是直接更新缓存。主要是怕两个并发的更新操作导致脏数据。

问题和注意事项

在决定如何实现 Cache Aside 模式时,请仔细考虑以下几点:

已缓存数据的生命周期。要使 Cache Aside 模式有效,你需要确保数据的过期策略与访问模式匹配。如果过期时间太短,应用程序会不断地从数据存储中检索数据。同样,如果过期时间太长,并且更新时没有使缓存失效,缓存的数据很可能会变得陈旧。

驱逐数据。缓存通常没有数据存储那么大,因此只要空间不足,就必须逐出数据。大多数缓存采用最近最少使用策略来选择要逐出的数据,但这也可以自定义。将全局逐出策略应用于缓存中的每项数据并不适用于所有场景。例如,如果从数据存储检索某个已缓存数据的代价很高,则将该数据保留在缓存中是有益的。

``` 填充缓存。作为启动过程中的一部分,让应用程序预先填充缓存可能是有益的。当数据被逐出或过期时, Cache Aside 模式仍然十分有用。

一致性。实现 Cache Aside 模式并不能保证数据存储与缓存之间的一致性。外部进程可随时更改数据存储中的项,并且在下次加载该项之前,此更改不会反映在缓存中。在跨数据存储复制数据的系统中,如果经常发生同步,则此问题可能会变得更严重。

本地(内存中)缓存。缓存可能是应用程序实例的本地缓存,并且存储在内存中。因为本地缓存是专用的,因此不同的应用程序实例可各自拥有相同缓存数据的副本。缓存之间的数据可快速变得不一致,因此有必要使专用缓存中保存的数据过期并频繁地刷新该数据。在这种情况下,请考虑研究共享或分布式缓存机制的使用。