高并发场景下数据库和缓存一致性问题

一般而言,我们在更新数据的时候会先删除缓存中对应的数据,再去更新数据库的数据。这就是所谓的Cache Aside Pattern。
但是这种模式在高并发场景下还是会出现数据不一致的问题: 一个线程A在修改数据,另外一个线程B读取数据,当A在删除缓存的数据还没来得及修改数据库的时候,B发现缓存没有数据,去数据库读取数据后将数据又存入缓存,这时候A完成了数据库的修改,最后数据库和缓存的数据就不一致了。
那么如何解决?
将读写数据请求做成异步串行化的。
在内存中搞若干个队列,将读写请求进行hash后进行取模分布到各个队列中,然后另起一些工作线程去对应的队列进行消费,这样读写请求就变成了串行化的了。当然还可以进行优化,比如队列中有多个读写请求并且中间没有写操作,可以进行一些“去重”的操作,当然不是直接删掉~
不过这样做后又会带来新的问题:
1.读请求阻塞的时间过长。
比如读请求前面阻塞了100个写操作,每个写操作要耗费10ms,那么这个读请求就要hang住1s,造成很大的延迟,那么这时候可以加机器,减少每个队列中写操作的数量。
2.多实例部署的请求路由问题
同一个数据的读写操作要路由到同一台机器上
解决:

  • 服务间按照某个请求hash路由
  • nginx进hash路由

3.热点数据的路由问题,导致请求的倾斜
很多请求都积压到同一台机器的同一个队列中。如果更新操作不多的话那也问题不大

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