1 Cache-aside
Cache-aside是一种常见的缓存一致性方案,也称为Cache-Through或Lazy-Load。下面是对Cache-aside方案的详细解释:
-
读取数据:当应用程序需要从数据库或其他持久性存储中读取数据时,它首先会检查缓存。如果数据存在于缓存中(命中),则应用程序直接从缓存中获取数据;如果数据不存在于缓存中(未命中),则应用程序从数据库中读取数据,然后将其添加到缓存中,以便将来的访问。
-
写入数据:在Cache-aside方案中,写入是由应用程序直接完成的,它首先将数据写入数据库,然后将其立即从缓存中删除,以便下一次读取该数据时能够获取最新的版本。
写入数据时有四种方案,请参阅文章https://mp.weixin.qq.com/s/OWuP66WxpciBAgm2mptUxw,Cache-aside方案中采用的是文章中的方案4——先更新数据库再删除缓存,理论上也存在脏缓存数据,但是发生的概率很低。
优点:
- 简单易实现:Cache-aside是一种相对简单的缓存策略,应用程序控制数据何时放入缓存以及何时从缓存中移除。这样可以确保数据的一致性和准确性。
- 灵活性:Cache-aside方案允许应用程序为每个数据项选择是否要缓存,以及缓存存储的方式和时间。这使得应用程序可以自由控制缓存行为。
缺点:
- 负载增加:在缓存未命中时,Cache-aside方案会增加对数据库的负载,因为每次未命中都需要从数据库中读取数据,并且每次数据更新也需要更新数据库和缓存。
- 数据不一致性:由于应用程序负责更新缓存,因此可能会出现数据在数据库中已经被更新但缓存中仍然是旧数据的情况。
2 写入数据操作失败
由于网络抖动,服务下线等原因,可能出现删除缓存失败情况,这也就导致redis一直存在脏数据。有两种方法解决该问题:
- 重试机制
- 消息订阅
请参阅文章https://mp.weixin.qq.com/s/OWuP66WxpciBAgm2mptUxw
3 总结
虽然说catch aside可以被称之为缓存使用的最佳实践,但与此同时,它引入了缓存的命中率降低的问题(因为每次写操作都会删除缓存,并没有再同时更新缓存,由读操作进行更新缓存),因此它更适用于对缓存命中率要求并不是特别高的场景。如果要求较高的缓存命中率,依然需要采用更新数据库后同时更新缓存的方案(文章https://mp.weixin.qq.com/s/OWuP66WxpciBAgm2mptUxw方案1)。
但是在更新数据库后同时更新缓存,会在并发的场景下出现数据不一致,解决方案也有两种:
在更新缓存之前尝试获取锁,如果已经被占用就先阻塞住线程,等待其他线程释放锁后再尝试更新。但这会影响并发操作的性能。
设置较短的缓存过期时间能够使得数据不一致问题存在的时间也比较长,对业务的影响相对较小。但是与此同时(其实这也使得缓存命中率降低)。