如何保证 redis 与数据库一致性
1.先删缓存,再写数据库。
问题:在高并发场景下,一个线程删了缓存,还没写数据库,另一个线程读数据发现缓存为空,就会将数据库里的旧值读出来并写入缓存(此时第一个线程已经将新的值写入缓存),这样就会将缓存中的新值覆盖。
解决方案:
(1)先操作缓存,但是不删除缓存,将缓存修改为一个特殊值(-1),客户端读缓存时发现是默认值,就休眠一会,再去查看一次 Redis。
弊端:特殊值对业务有侵入,休眠时间可能多次重复,对性能有影响。
(2)延时双删。先删除缓存,再写入数据库,休眠一会再删除缓存。
弊端:如果写操作比较频繁,还是会有脏数据的问题。
总结:在这种方式下,通常要求写操作不太频繁。
2.先写数据库,再删缓存。
问题:如果数据库写完之后,删除缓存失败,数据就会不一致。
解决方案:
(1)给缓存设置一个过期时间。但是在过期时间内,缓存数据不会更新。
(2)引入 MQ,保证原子操作。
(3)将热点数据缓存设置永不过期,但是在 value 当中写入一个逻辑上的过期时间,另外起一个线程,扫描这些 key,对于逻辑上已经过期的 key 进行删除。
总结:始终只能保证一定时间内的最终一致性。
评论