ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

数据库和缓存数据双写一致性问题

2022-01-28 12:00:08  阅读:159  来源: 互联网

标签:缓存 删除 数据库 更新 查询 缓存数据 一致性 数据 双写


参考:https://blog.csdn.net/qq_33135813/article/details/91352093?utm_medium=distribute.wap_relevant.none-task-blog-2~default~baidujs_title~default-0.wap_blog_relevant_pic

https://blog.csdn.net/wenlin_xie/article/details/87652240

1、什么是缓存-数据库双写一致性问题?

应用设计中,如果为了提高查询性能,将一些数据库查询到的数据放入了缓存中,那么就会出现一种情况,更新数据库某些数据的时候,由于需要将缓存中的数据和数据库的数据做同步,那么高并发场景下,就会受到其他更新操作或者查询操作的影响。

2、使用到缓存的情况下,更新数据库的数据,数据库和缓存应该怎么更新?

正常情况,对于数据实时性要求不高的系统,可以设置缓存有效期,可以保证缓存数据最终的一致性。如果对数据实时性要求高,就需要选择更好的方案。如下:

如果选择了更新数据库然后更新缓存这种设计,就会导致每次更新库表都要去查询最新的数据然后更新到缓存,假如这条数据客户实际访问的很少,就会导致浪费资源;

所以一般我们可以进行优化,选择删除缓存,那么只有当客户第一次用到这条数据的时候才去数据库查询,后续查询都会先去缓存获取,未命中才去数据库获取;

3、先删除缓存,后更新数据库的方案:(先更新库,后删除缓存,如果第一步成功了,第二部失败了会导致两边数据不一致的情况)

理论上,如果删除缓存失败,那么数据库也不会去更新,可以保持两边数据一致;缓存删除成功,数据库更新失败,那么客户查询这条数据的时候会去数据库获取,然后更新缓存,两边数据可以保持一致;

缺陷:假如删除缓存成功了,但是还未更新数据库,这时线程切换,切换到另一个查询任务线程,查询会走到去数据库获取数据然后更新缓存,那么缓存保存的就是旧数据,再切换回去更新数据库,这时两边数据就不一致了。

解决“线程切换干扰更新”的方案:

a、双删除策略,删除缓存-更新数据库-等待几百ms再删除缓存;可以保证上面那种线程切换导致读取旧数据到缓存的情形下,将旧数据及时删除。

如果还担心第二次删除会失败,那就再给缓存设置有效期,保证数据最终一致性。

b、引入阻塞队列。更新时,利用这条数据的唯一标识,创建一个与之对应的任务队列,保存到Map<唯一标识id, Queue<String>>,更新完数据库和缓存后,移除队列的这个元素,后续有读操作的时候,利用唯一标识获取相应队列,然后判断队列内是否有其他操作,是的话进入队列等候,后续再来一个查询请求时,判断如果队列中已经存在一个相同的查询等待请求任务在等待了,就不需要进入队列,直接阻塞等待更新操作完成再往下走。

 

标签:缓存,删除,数据库,更新,查询,缓存数据,一致性,数据,双写
来源: https://www.cnblogs.com/dust-to-dust/p/15387166.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有