[Redis] 02-缓存和数据库数据一致性问题

经过一番排查,确认服务器的性能瓶颈是在数据库。给服务器加上Redis,让其作为数据库的缓存。
这样,在客户端请求数据时,如果能在缓存中命中数据,那就查询缓存,不用再去查询数据库,从而减轻数据库的压力,提高服务器的性能。

一、缓存模型

二、数据库和缓存的数据不一致问题

更新数据时,数据库的数据时客户端第二次更新操作的数据,而缓存确还是第一次更新操作的数据,也就是出现了数据库和缓存不一致的问题
造成缓存和数据库的数据不一致的现象,是因为并发问题

先更新数据库,还是先更新缓存?(并发双写,不使用该方案)

并发双写:在并发双写中,当数据更新时,会同时更新缓存和数据库,以确保它们保持一致。
尽管并发双写可以减少数据不一致性的可能性,但它并不能完全消除这种风险。

先更新数据库,再更新缓存:

先更新缓存,再更新数据库:

所以,无论是「先更新数据库,再更新缓存」,还是「先更新缓存,再更新数据库」,这两个方案都存在并发问题,当两个请求并发更新同一条数据的时候,可能会出现缓存和数据库中的数据不一致的现象。

先更新数据库,还是先删除缓存?

不更新缓存,而是删除缓存中的数据。然后,到读取数据时,发现缓存中没了数据之后,再从数据库中读取数据,更新到缓存中。(即用删除缓存代替更新缓存)

写策略步骤:

  • 更新数据库中的数据
  • 删除缓存中的数据

读策略步骤:

  • 如果读取的数据命中了缓存,则直接返回数据
  • 如果读取的数据没有命中缓存,则从数据库中读取数据,然后将数据写入到缓存,并返回给用户

那问题又来了:在[写策略]的时候,到底选择哪种顺序呢?

  • 先删除Redis缓存中数据,再更新MySQL中的数据
  • 先更新MySQL中的数据,再删除Redis缓存中的数据

先删除缓存,再更新数据库:

可以看到,先删除缓存,再更新数据库,在「读 + 写」并发的时候,还是会出现缓存和数据库的数据不一致的问题

解决方案:双删

双删的问题:
如果重建缓存的时间比较长,线程1删除Redis缓存后,线程2才重建完缓存,这时会出现数据不一致问题。

延迟双删:
第二次删除操作具体延迟多久呢?

大于线程2重建缓存的时间。

先更新数据库,再删除缓存:

因为缓存的写入通常要远远快于数据库的写入,所以在实际中很难出现请求 B 已经更新了数据库并且删除了缓存,请求 A 才更新完缓存的情况。
而一旦请求 A 早于请求 B 删除缓存之前更新了缓存,那么接下来的请求就会因为缓存不命中而从数据库中重新读取数据,所以不会出现这种不一致的情况。
所以,「先更新数据库 + 再删除缓存」的方案,是可以保证数据一致性的。(也得承受几百毫秒的数据不一致性)

先删除缓存,数据不一致更加严重点。所以,我们一般选择使用后删除缓存。

但是后删除缓存也可能存在问题(当删除缓存失败的时候):
所以我们给key设置一个过期时间(兜底方案)。


最好的解决方案:

三、总结


本文作者:keyongkang

本文链接:https://www.cnblogs.com/keyongkang/p/18061643

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @ 2024-03-08 18:43  Ac_c0mpany丶  阅读(91)  评论(0编辑  收藏  举报
  1. 1 You Are My Sunshine REOL
You Are My Sunshine - REOL
00:00 / 00:00
An audio error has occurred.

作曲 : Traditional

You are my sunshine

My only sunshine.

You make me happy

When skies are gray.

You'll never know, dear,

How much I love you.

Please don't take my sunshine away

The other night, dear,

When I lay sleeping

I dreamed I held you in my arms.

When I awoke, dear,

I was mistaken

So I hung my head and cried.

You are my sunshine,

My only sunshine.

You make me happy

When skies are gray.

You'll never know, dear,

How much I love you.

Please don't take my sunshine away.

You are my sunshine,

My only sunshine

You make me happy

When skies are gray.

You'll never know, dear

How much I love you

Please don't take my sunshine away

Please don't take my sunshine away.

Please don't take my sunshine away.