缓存一致性的问题

随着数据量的不断提升,数据库的瓶颈达到最大的巅峰,对于用户的查询性能将受到很大的影响,因此引入了缓存,减轻数据库的压力,提高访问请求的速度。先读取缓存数据,缓存中有的话则立即返回结果,如果没有,则从数据库中读取数据,并且把读到的数据同步到缓存里,供下次请求使用。

虽说这样减轻了数据库的压力,但在多线程高并发的场景下,可能会导致缓存和数据库不一致的问题,这需要我们解决!!!

一、分析问题与解决方案

问题的根源其实是读数据与些数据请求同时并发时候,数据库与缓存数据已更新,但访问的数据还是老数据,出现了脏读数据

1、先更新缓存,再更新数据库

方案不行,原因是更新缓存成功吗,更新数据库出现了异常,导致缓存与数据库完全不一致

2、先更新数据库,再更新缓存

同样也不行,数据库更新成功了,但缓存更新失败,同样会出现数据不一致的问题

合理的方案是再遇到写请求的时候,可以先删除缓存数据,再更新数据库,这样不管数据库更新失败还是缓存删除失败,缓存与数据库始终一致,这种方案满足上万人的并发

虽说上述可以,但遇到一些极端的上亿的并发情况,上述显然不行,比方说双十一,A用户抢购该商品,数量减少,消费者A抢购成功,这时应该删除缓存,更新数据库商品数量,但再更新商品数量之前,又有一个消费者B来查看商品数量。因为缓存为空,则到数据库中查询,发现商品数量没变,还是原来一样,从而导致缓存与数据库不一致的问题

方案1:读写分离

读请求只访问缓存,写请求只修改数据库和缓存

写请求修改数据库和缓存是事务性动作,如果更新数据库成功,更新缓存失败,则回滚数据库,保证缓存与数据库强一致性,这样实现了读写分离。不仅提高了读的响应速度,由写请求负责缓存与数据库一致,只有写请求成功才会影响到缓存的内容

方案二:队列存储请求

沿用场景一的解决方案,为解决其缺陷,添加队列,凡是遇到写请求,则将写请求放入队列中,由队列对写请求统一管理,写请求处理成功,则从队列中删除。当有一个读请求过来时,到队列查询,是否有对应的写请求,如果有则放入队列中,等待写请求执行完之后再执行读请求。为防止某个请求阻塞情况,为其设置超时机制或者过期机制。

这种方案虽可行,但是倘若访问量大,处理器来不及处理,队列内的请求数量越来越高,则会影响查询效率。出现这种情况,就要加机器集群执行,帮忙分担压力

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章