2022-6月更文挑战28-redis缓存一致性问题

76 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

redis缓存一致性问题

前文

redis是一种常用的缓存中间件,而如何保证redis缓存的一致性是一个常见的问题。本文内容主要是对于redis缓存一致性问题的一些理解及笔记记录。

实现redis缓存一致性的几种方式

  • 更新数据库并更新缓存

    先更新数据库后更新缓存主要是会存在问题,当我们成功的更新数据库后,在更新缓存时操作失败,则会导致数据库数据为最新版的数据,而缓存中数据为历史数据,导致缓存数据不一致。另外就是当并发操作时,当线程a先进行操作,将数据库更新,准备更新缓存。此时线程b开始更新数据库,并将缓存更新为数据库的内容。而与此同时,线程a进行缓存的更新。就会导致数据库为最新值,而redis缓存中的内容为线程a的历史操作结果。

  • 更新缓存并更新数据库

    先更新缓存,会存在当缓存更新成功而数据库更新失败时,导致出现数据的不一致问题。同样的,当我们在并发环境中操作时,也可能存在由于两个线程的执行顺序导致的缓存不一致性问题。

  • 删除缓存并更新数据库

    先删除缓存再更新数据库,这种方式当更新数据库出现失败时,并不会产生意外的影响。由于只有删除缓存操作成功,数据库数据并未发生变化,因此后续的请求会根据数据库中的数据进行缓存重建。再考虑并发情况下的问题,只有当a线程访问时redis中没有缓存,此时查询历史数据。与此同时b线程先删除了缓存进行数据库的更新。a线程又将查到的历史数据写入到redis中造成缓存数据不一致。这种情况怎么处理呢?可以采用缓存延迟双删的方式,在一定时间后进行缓存的二次删除。

  • 更新数据库并删除缓存

    先更新数据库,那么当缓存删除失败时怎么处理?可以采用队列的方式,将删除命令通过队列下放,也就保证了缓存一定能成功删除。接下来再看并发问题。这种方式出现缓存不一致性,需要由线程a查询redis发现不存在数据,因此到数据库中进行历史数据查询。此时线程b写入数据库并删除缓存,线程a再进行缓存写入。由于写入的速度通常要慢于读取的速度,因此这种情况的发生概率非常低。

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。