数据一致性
redis与db的数据一致性
在本方案中,由于更新缓存,只是一个非常简单的数据加减操作.因此采用了先更新数据库,再更新缓存.
缓存和db的更新策略
主要有2种场景的解决,1是后执行的操作失败后的处理,即数据的同步问题.2是A,B操作第一步后,在第二步进行了乱序,导致B先执行,A后执行的影响的处理.即乱序问题.
先更新缓存,在更新数据库.
对于数据同步问题,更新缓存成功,更新db失败后,将失败的sql放进异步队列,异步不断的进行重试执行数据,进行数据补偿.
对于数据乱序,在第二步执行的sql不要求顺序的场景下,是没有问题的.比如扣减库存.对于需要严格的sql执行顺序的话,就会有问题.
优势:
数据以缓存中为最新.有效防止多卖超卖.
劣势
db更新失败后,会存在短暂时刻的少卖现象.
先更新数据库,在更新缓存
简单缓存的更新,对于更新数据库,基本上不会出现更新失败.因此将数据的同步问题,缩小到最新甚至没有.
数据的同步是不需要考虑.但是乱序问题,这种情况也需要保证sql的可乱序执行.
需要注意的是,更新db的时候需要通过添加版本控制,来保证并发下的库存击穿问题.
先删除缓存,再更新数据库
这种情况下,A在删除缓存,还没更新数据库的时候,B请求到来,发现缓存中没有数据,查询数据库,更新到缓存.
导致出现数据问题.
先更新数据库,在删除缓存
一款比较标准的设计方案,facebook在论文中也使用了这个方案.
https://www.usenix.org/system/files/conference/nsdi13/nsdi13-final170_update.pdf
这种后更新缓存的策略,对数据的同步有着天然的支持.
扩展
虽然说,更新缓存基本没有问题,但是为了提高数据同步,可以在更新缓存的时候,使用延时双删来加强.
删除缓存还是更新缓存?删除缓存势必会导致cache miss,但是好处是控制更便利一些.尤其是复杂的缓存内容.
但是相比简单的缓存内容,更新缓存会减少一些cache miss,这点会更好一些.
结论
在sql的执行上需要设计成无序的.
update set stock=stock-1优先修改db里面的数据,对于缓存失败的场景,进行延时再次执行来加强.
Last updated
Was this helpful?