如何保证Redis与数据库的数据一致?

如何保证Redis与数据库的数据一致?

当我们对数据进行修改的时候,到底是先删缓存,还是先写数据库?

1.如果是先删缓存,再写数据库:在高并发场景下,当第一个线程删了缓存,还没有来得及写数据库,第二个线程来读数据,会发现缓存中的数据为空, 那就会去读数据库中的数据(旧值/脏数据),读完之后,把读到的结果写入缓存(此时,第一个线程已经将新的值写到缓存里面了),这样缓存中的值就会被覆盖为修改前的脏数据。

总结:在这种方式下,通常要求写操作不会太频繁。
解决方案:
1)先操作缓存,但是不删缓存
将缓存修改为一个特殊值(如-999),客户端读缓存时,发现是默认值,就休眠一小会儿再去查一次Redis。存在的问题:特殊值对业务有侵入;如果数据写操作很频繁,则休眠时间可能会多次重复,对性能有影响。
2)延时双删:先删除缓存,再写数据库,休眠一小会儿,再次删数据库。存在的问题:如果数据写操作很频繁,同样还是会有脏数据。

2.先写数据库,再删缓存:如果数据库写完之后,缓存删除失败,数据就会不一致。

总结:始终只能保证一定时间内的最终一致性。
解决方案:
1)给缓存设置一个过期时间:存在的问题:过期时间内,缓存数据不会更新。
2)引入MQ(消息队列),保证原子性:存在的问题:MQ重试时间内,缓存数据不会更新。
3)将热点数据缓存设置为永不过期,但是在value当中写入一个逻辑上的过期时间,另起一个后台线程扫描这些key,对于逻辑上过期的缓存,进行删除

原文地址:https://www.cnblogs.com/pangqianjin/p/14616807.html