我试图理解一些关于该高速缓存的策略。如果找到(缓存命中),则从该高速缓存读取数据,如果没有找到(缓存未命中),则从数据库读取数据+在缓存中更新。
在写入时,它被放入主数据库,然后该高速缓存应该通过以下方式更新:
- A:删除该高速缓存中相应的条目(这样下一次读取会遇到缓存未命中,并更新缓存)
- 或B:更新该高速缓存中的对应条目(因此如果下一次读取发生在高速缓存条目TTL之前,则下一次读取将遇到高速缓存命中)
我不明白A和B两种方案的利弊。有了redis,这两个看起来都很容易实现,但我想还有其他的考虑。
1条答案
按热度按时间t9eec4r01#
这两种解决方案都试图使数据库更改尽快同步到高速缓存,即使数据库和缓存尽可能一致,以便应用程序代码可以读取(可能的)最新数据。
以下是每种解决方案的缺点。
方案A:删除缓存中的项目
如果该项更新非常频繁,则此解决方案会一直删除该高速缓存项,并且会导致大量缓存未命中。大多数请求都会命中数据库,该高速缓存变得无用。
方案B:更新缓存中的项目
此解决方案可能会将不频繁的项插入该高速缓存中,并降低缓存命中率。当一个项目在数据库中被更新时,你不知道它是否是一个热门项目。如果它是一个冷项,并且您将其插入缓存,那么可能会从该高速缓存中驱逐热项(因为缓存大小有限)。
缓存不一致问题依然存在
尽管这两种解决方案都试图使该高速缓存尽可能一致。他们不能保证。以下面的例子为例。
1.客户端A读取该高速缓存,发现它不存在。
1.客户端A读取数据库并获取值:* 旧值 *。
1.客户端B用新值更新数据库:new-value。
1.客户端B使用 new-value 更新缓存或删除缓存中的条目(尽管它可能不存在于缓存中)。
1.客户端A使用 old-value 该高速缓存。
在这种情况下,缓存仍然保存旧值。
方案C:与前后矛盾的人交朋友
由于使用缓存,因此无法避免与数据库的不一致。所以在大多数情况下,我们不需要更新/删除缓存项目时更新数据库。查看this和this以了解更多详细信息。