面试官: 为什么在系统中不推荐双写?

沙海 2021年4月15日01:38:42杂谈 Java评论27字数 3000阅读10分0秒阅读模式
摘要

速读摘要

速读摘要文章源自JAVA秀-https://www.javaxiu.com/12387.html

*万一写入数据库成功了,写入elasticsearch失败了怎么处理?阿雄在网上发现,现在业内都用一些elasticsearch做一些全文检索的操作,于是乎阿雄将一些需要全文检索的数据放入elasticsearch,提高了系统的搜索能力!在该架构下,所有的数据变更写入一个消息队列里去。因为写入顺序已经在消息队列中定义好,各数据源按照消息队列中的消息顺序,恢复数据即可,并不存在竞争现象。文章源自JAVA秀-https://www.javaxiu.com/12387.html

原文约 3543 | 图片 10 | 建议阅读 8 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?

芋道源码 文章源自JAVA秀-https://www.javaxiu.com/12387.html

以下文章来源于孤独烟,作者孤独烟文章源自JAVA秀-https://www.javaxiu.com/12387.html

文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

孤独烟文章源自JAVA秀-https://www.javaxiu.com/12387.html

孤独烟说java,用来分享行业内的java技术和架构!文章源自JAVA秀-https://www.javaxiu.com/12387.html

文章源自JAVA秀-https://www.javaxiu.com/12387.html

点击上方“芋道源码”,选择“设为星标文章源自JAVA秀-https://www.javaxiu.com/12387.html

管她前浪,还是后浪?文章源自JAVA秀-https://www.javaxiu.com/12387.html

能浪的浪,才是好浪!文章源自JAVA秀-https://www.javaxiu.com/12387.html

每天 8:55 更新文章,每天掉亿点点头发...文章源自JAVA秀-https://www.javaxiu.com/12387.html

文章源自JAVA秀-https://www.javaxiu.com/12387.html

源码精品专栏文章源自JAVA秀-https://www.javaxiu.com/12387.html

 文章源自JAVA秀-https://www.javaxiu.com/12387.html

文章源自JAVA秀-https://www.javaxiu.com/12387.html

文章源自JAVA秀-https://www.javaxiu.com/12387.html

  • 引言文章源自JAVA秀-https://www.javaxiu.com/12387.html

  • 正文文章源自JAVA秀-https://www.javaxiu.com/12387.html

    • 背景介绍文章源自JAVA秀-https://www.javaxiu.com/12387.html

    • 双写缺点文章源自JAVA秀-https://www.javaxiu.com/12387.html

    • 改良方案文章源自JAVA秀-https://www.javaxiu.com/12387.html

  • 总结文章源自JAVA秀-https://www.javaxiu.com/12387.html

引言

某日,阿雄跑去面试!于是有如下情形文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官:"阿雄是吧,做做自我介绍!"文章源自JAVA秀-https://www.javaxiu.com/12387.html

阿 雄:"我叫阿雄,来自某a国际电商公司!"文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官:"我看你项目里用了elasticsearch,你是怎么同步数据的呢?" 文章源自JAVA秀-https://www.javaxiu.com/12387.html

阿 雄:"在代码里写入数据库的时候,同时再写入elasticsearch!" 文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官:"那你如何保证写入数据库,和写入elasticsearch原子性问题呢?文章源自JAVA秀-https://www.javaxiu.com/12387.html

** 万一写入数据库成功了,写入elasticsearch失败了怎么处理?"**文章源自JAVA秀-https://www.javaxiu.com/12387.html

阿 雄:"我还是回去等通知吧!"文章源自JAVA秀-https://www.javaxiu.com/12387.html

OK,以上情形纯属虚构,如有雷同,绝对巧合!文章源自JAVA秀-https://www.javaxiu.com/12387.html

其实这篇文章所探讨的数据同步策略并不限于某两种固定的存储系统之间,而想去探讨一种通用的数据同步策略。主要分为以下三个部分文章源自JAVA秀-https://www.javaxiu.com/12387.html

  • (1)背景介绍文章源自JAVA秀-https://www.javaxiu.com/12387.html

  • (2)双写缺点文章源自JAVA秀-https://www.javaxiu.com/12387.html

  • (3)改良方案文章源自JAVA秀-https://www.javaxiu.com/12387.html

正文

背景介绍

话说阿雄在加入某a国际电商公司的时候,业务系统十分简单,一个database就能搞定一切!文章源自JAVA秀-https://www.javaxiu.com/12387.html

可是某a国际电商公司在产品韩的领导下,业务增长迅速,阿雄发现了数据库越来越慢,于是乎阿雄加入了一些缓存,如redis来缓存一些数据,提高系统的响应能力。文章源自JAVA秀-https://www.javaxiu.com/12387.html

又过了一段时间,产品韩发现搜索的速度灰常慢,让阿雄去改。阿雄在网上发现,现在业内都用一些elasticsearch做一些全文检索的操作,于是乎阿雄将一些需要全文检索的数据放入elasticsearch,提高了系统的搜索能力!文章源自JAVA秀-https://www.javaxiu.com/12387.html

随着数据的膨胀,阿雄慢慢的发现了,对数据库做一些数据分析操作,性能明显的跟不上了。于是乎阿雄将数据库里的数据,导入hadoop,然后进行数据分析。文章源自JAVA秀-https://www.javaxiu.com/12387.html

(省略一万字….)文章源自JAVA秀-https://www.javaxiu.com/12387.html

最后,阿雄和产品韩幸福的在一起了文章源自JAVA秀-https://www.javaxiu.com/12387.html

OK,好,现在分析上面的场景!思考第一个问题1、在database,redis,elasticsearch,hadoop中的数据是有关系的,还是彼此独立的?显然是有关系的,在这几个数据源中的数据都是相关的。只是格式不一样而已!例如,对于一条Product数据,在数据库里是文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

图片文章源自JAVA秀-https://www.javaxiu.com/12387.html

在redis里就是key为 product:pId:1,value是文章源自JAVA秀-https://www.javaxiu.com/12387.html

{       "pId": "1",    "productName": "macbook"}

如上所示,只是数据格式不一样而已!文章源自JAVA秀-https://www.javaxiu.com/12387.html

那好,现在思考第二个问题2、既然这些数据源之间数据是相关的,如何保证这几个数据源之间数据一致性!一种比较简单且容易想到的方案是,hardcode在程序中 例如现在有两个数据源DataSouce1和DataSource2,我们往里头写数据,代码如下文章源自JAVA秀-https://www.javaxiu.com/12387.html

ProductService{    \\省略    public void syncData(){        x1. writeDataSource1();        x2. writeDataSource2();    }}

这就是我们标题中所提到的双写!那么,双写会带来什么坏处呢?OK,继续往下看!文章源自JAVA秀-https://www.javaxiu.com/12387.html

双写缺点

一致性问题打个比方我们现在有两个client,同时往两个DataSouce写数据。文章源自JAVA秀-https://www.javaxiu.com/12387.html

  • 一个client往里头入X为1文章源自JAVA秀-https://www.javaxiu.com/12387.html

  • 一个client往里头入X为5文章源自JAVA秀-https://www.javaxiu.com/12387.html

那么会有如下情形出现文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

图片文章源自JAVA秀-https://www.javaxiu.com/12387.html

如图所示,两个DataSouce的数据就不一致了,一个为1,一个为5。除非接下来有一个新的请求,对x数据发生了变更,才能修正这种现象!否则,你可能永远都发现不了。文章源自JAVA秀-https://www.javaxiu.com/12387.html

原子性问题因为我们需要同时往DataSource1和DataSource2一起写数据,你需要保证文章源自JAVA秀-https://www.javaxiu.com/12387.html

x1. writeDataSource1();x2. writeDataSource2();

这两个操作一起成功,或者一起失败!如果采用双写的方法,是避不开这个问题的!文章源自JAVA秀-https://www.javaxiu.com/12387.html

那么有没有通用的办法来解决这些问题呢?有的,只要能按顺序记录数据的变更即可!那具体怎么做呢,我们继续往下看!文章源自JAVA秀-https://www.javaxiu.com/12387.html

改良方案

假设,如果我们能将数据按顺序记录,写入某个消息队列,然后其他系统按消息顺序恢复数据,看看what happen? 此时架构图如下文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

图片文章源自JAVA秀-https://www.javaxiu.com/12387.html

在该架构下,所有的数据变更写入一个消息队列里去。其他各数据源从消息队列里恢复数据即可!文章源自JAVA秀-https://www.javaxiu.com/12387.html

那么,此时还有一致性问题,和原子性问题么?一致性问题OK,这种情况下,各个数据源之间数据肯定是一致的。因为写入顺序已经在消息队列中定义好,各数据源按照消息队列中的消息顺序,恢复数据即可,并不存在竞争现象。因此,不会出现不一致的问题!原子性问题OK,这种情况下,如果写入DataSource失败会怎么样?例如出现了网络问题,这条消息恢复失败了。这个问题其实好解决,一般我们在顺序根据消息恢复数据的时候,会记录下坐标。如果写入失败,停止恢复数据。下次从该坐标处恢复数据即可。文章源自JAVA秀-https://www.javaxiu.com/12387.html

但是在上面那张图中,写入DataBase是异步写入的。这样就不符合很多业务场景的"写后即读"的要求,因此,在实际落地中,做了一些变更!通用做法是去提取数据库的变化!如下图所示文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

图片文章源自JAVA秀-https://www.javaxiu.com/12387.html

在该图中的中间件,例如oracle中的oracle golden gate可以提取数据变化。mysql中的canal能提取数据的变化。至于消息队列,可以选用kafka。直接提取数据变化到kafka中,其他数据源从kafka中获取数据,避免了直接双写从而导致一致性和原子性问题。文章源自JAVA秀-https://www.javaxiu.com/12387.html

总结

本问讨论了在项目中常见的数据同步问题,希望大家有所收获。引言文章源自JAVA秀-https://www.javaxiu.com/12387.html

欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

已在知识星球更新源码解析如下:文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

面试官: 为什么在系统中不推荐双写?文章源自JAVA秀-https://www.javaxiu.com/12387.html

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。文章源自JAVA秀-https://www.javaxiu.com/12387.html

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。文章源自JAVA秀-https://www.javaxiu.com/12387.html

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。文章源自JAVA秀-https://www.javaxiu.com/12387.html

文章源自JAVA秀-https://www.javaxiu.com/12387.html

文章有帮助的话,在看,转发吧。谢谢支持哟 (*^__^*)
文章源自JAVA秀-https://www.javaxiu.com/12387.html

阅读原文文章源自JAVA秀-https://www.javaxiu.com/12387.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定