如何保证数据库与缓存中数据的一致性?

首先,我觉得只要用到了缓存,是没有办法达到强一致性的,尤其是在高并发场景下面。

当我们对数据进行修改的时候,到底是先删缓存,还是先写数据库?
1、如果先删缓存,再写数据库: 在高并发场景下,当第一个线程删除了缓存,还没有来得及写数据库,第二个线程来读取数据,会发现缓存中的数据为空,那就会去读数据库中的数据(旧值,脏数据),读完之后,把读到的结果写入缓存(此时,第一个线程已经将新的值写到缓存里面了),这样缓存中的值就会被覆盖为修改前的脏数据.
总结: 在这种方式下,通常要求写操作不会太频繁
解决方案:1》先操作缓存,但是不删除缓存。将缓存修改为一个特殊值(-999)。客户端读缓存时,发现是默认值,就休眠一小会,再去查一次Redis。-》 特殊值对业务有侵入。休眠时间,可能会多次重复,对性能有影响.
2》延时双删。 先删除缓存,然后再写数据库,休眠一小会,再次删除缓存。-》如果数据写操作很频繁,同样还是会有脏数据的问题。

 

2、先写数据库,再删缓存: 如果数据库写完了之后,缓存删除失败,数据就会不一致。
总结: 始终只能保证一定时间内的最终一致性。
解决方案: 1》给缓存设置一个过期时间 问题: 过期时间内,缓存数据不会更新2》引入MQ,保证原子操作。
解决方案:将热点数据缓存设置为永不过期,但是在value当中写入一个逻辑上的过期时间,另外起一个后台线程,扫描这些key,对于已逻辑上过期的缓存,进行删除。

posted @ 2023-02-05 20:12  君莫笑我十年游  阅读(95)  评论(0编辑  收藏  举报