作者:微信小助手
发布时间:2024-11-08T00:34:59
对于读多写少并且要求高性能的业务逻辑,我们通常在应用服务器访问MySQL数据库的中间加上一层Redis缓存层,以提高数据的查询效率,减轻MySQL数据库的压力,避免在MySQL出现性能瓶颈。 该问题,如果在数据存储后,只读场景下是不会出现MySQL与Redis缓存的一致性问题的,所以真正需要考虑的是并发读写场景下的数据一致性问题。 如果我们不加分析,单独利用MySQL和Redis的知识进行回答并发场景下如何保证MySQL与Redis缓存一致性?很难把这个问题回答好,因为看起来很简单的方案实际上是漏洞百出的。 我们先看下简单的更新数据库、删除缓存和更新缓存方案下,会出现什么问题? 先说结论: 原因是更新缓存成功后,数据库可能更新失败,出现数据库为旧值,缓存为新值。导致后续的所有的读请求,在缓存未过期或缓存未重新正确更新的情况下,会一直保持了数据的完全不一致!并且当前数据库中的值为旧值,而业务数据的正确性应该以数据库的为准。 那么如果更新缓存成功后,数据库可能更新失败,我们重新更新缓存是不是可以了? 抛开需要重新更新缓存时,要单表或多表重新查询数据,再更新数据带来的性能问题,还可能期间有数据变更再次陷入脏数据的情况。实际上仍然还是会出现并发一致性问题。 只要缓存进行了更新,后续的读请求在更新数据库前、更新数据库失败并准备更新缓存前,基本上都能命中缓存情况,而这时返回的数据都是未落库的脏数据。 不考虑。 原因是当数据库更新成功后,缓存更新失败,出现数据库为最新值,缓存为旧值。导致后续的所有的读请求,在缓存未过期或缓存未重新正确更新的情况下,会一直保持了数据的完全不一致! 该方案就算在更新数据库、更新缓存都成功的情况下,还是会存在并发引发的一致性问题,如下图所示(点击图片查看大图): 可以看到在并发多写多读的场景下数据存在的不一致性问题。 不考虑,但是通过使用延时双删策略后可以考虑。 采用“先删除缓存,再更新数据库”的方案是一种常见的方法来尝试解决这个问题的策略。 这种方法逻辑较为简单,易于理解和实现,理论上删除旧缓存后,下次读取时将从数据库获取最新数据。 但在并发的极端情况下,删除缓存成功后,如果再有大量的并发请求进来,那么便会直接请求到数据库中,对数据库造成巨大的压力。而且此方案还是可能会发生数据不一致性问�
简单方案下的漏洞百出
更新缓存,再更新数据库
不考虑
。
更新数据库,再更新缓存
先删除缓存,再更新数据库