为了提升性能,缓存在系统开发中具有普遍的应用。常见的模式是先查询/更新db后再去更新缓存,那么如何保证db和缓存的数据一致性的问题是实际开发中经常遇到的问题。这种场景下容易造成数据不一致的问题主要是缓存双写。
一、缓存双写问题
先查询或者更新db,然后再更新缓存,这里可能出现的一种不一致的情况是db更新或查询成功,但是缓存更新失败了,这个不一致的问题可以通过重试更新缓存的方式来解决,保证最终一致性。但是这个方案只适用于只有一个更新缓存的线程的场景。
如果有多个线程同时更新缓存呢,也就是双写,比如查询线程A查询到数据后要更新缓存,此时另一个更新线程B在完成db的更新后也要更新缓存,这个时候,线程A可能在查询时db还没有完成更新,查到的是老数据,如果最终线程A后于B更新缓存,则缓存中最终的数据则是旧的数据,就会出现db和缓存数据不一致的情况。
二、解决方案
解决这个问题的关键是如何保证多个线程更新有序性,化并行为串行是解决这个问题的基本思路。在这里我们可以考虑引入队列的方式来解决,通过队列来保证线程更新的有序性。
mq的选型比较建议使用消息队列,比如rabbitmq,rocketmq等,消费端保证只有一个线程顺序消费消息即可。如果要增大吞吐量,可以使用多个队列,每个队列对应一个消费者。使用消息队列可以充分利用其特性,比如消息的持久化,消息消费失败后的重试等,可以更好的保证数据的最终一致性。
更多内容欢迎关注个人微信公众号,一起成长!