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

标签: tuicool | 发表时间:2020-08-03 00:00 | 作者:
出处:http://itindex.net/relian

引言

某日,阿雄跑去面试!于是有如下情形

面试官:"阿雄是吧,做做自我介绍!"

阿  雄:"我叫阿雄,来自某a国际电商公司!"

面试官:"我看你项目里用了elasticsearch,你是怎么同步数据的呢?"

阿  雄:"在代码里写入数据库的时候,同时再写入elasticsearch!"

面试官:"那你如何保证写入数据库,和写入elasticsearch原子性问题呢?

万一写入数据库成功了,写入elasticsearch失败了怎么处理?"

阿  雄:"我还是回去等通知吧!"

OK,以上情形纯属虚构,如有雷同,绝对巧合!

其实这篇文章所探讨的数据同步策略并不限于某两种固定的存储系统之间,而想去探讨一种通用的数据同步策略。主要分为以下三个部分

  • (1)背景介绍

  • (2)双写缺点

  • (3)改良方案

正文

背景介绍

话说阿雄在加入某a国际电商公司的时候,业务系统十分简单,一个database就能搞定一切!

可是某a国际电商公司在产品韩的领导下,业务增长迅速,阿雄发现了数据库越来越慢,于是乎阿雄加入了一些缓存,如redis来缓存一些数据,提高系统的响应能力。

又过了一段时间,产品韩发现搜索的速度灰常慢,让阿雄去改。阿雄在网上发现,现在业内都用一些elasticsearch做一些全文检索的操作,于是乎阿雄将一些需要全文检索的数据放入elasticsearch,提高了系统的搜索能力!

随着数据的膨胀,阿雄慢慢的发现了,对数据库做一些数据分析操作,性能明显的跟不上了。于是乎阿雄将数据库里的数据,导入hadoop,然后进行数据分析。

(省略一万字….)

最后, 阿雄和产品韩幸福的在一起了

OK,好,现在分析上面的场景!思考第一个问题

1、在database,redis,elasticsearch,hadoop中的数据是有关系的,还是彼此独立的?

显然是有关系的,在这几个数据源中的数据都是相关的。只是格式不一样而已!例如,对于一条Product数据,在数据库里是

在redis里就是key为 product:pId:1,value是

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

如上所示,只是数据格式不一样而已!

那好,现在思考第二个问题

2、既然这些数据源之间数据是相关的,如何保证这几个数据源之间数据一致性!

一种比较简单且容易想到的方案是,hardcode在程序中

例如现在有两个数据源DataSouce1和DataSource2,我们往里头写数据,代码如下

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

这就是我们标题中所提到的双写!那么,双写会带来什么坏处呢?OK,继续往下看!

双写缺点

一致性问题

打个比方我们现在有两个client,同时往两个DataSouce写数据。

  • 一个client往里头入X为1

  • 一个client往里头入X为5

那么会有如下情形出现

如图所示,两个DataSouce的数据就不一致了,一个为1,一个为5。除非接下来有一个新的请求,对x数据发生了变更,才能修正这种现象!否则,你可能永远都发现不了。

原子性问题

因为我们需要同时往DataSource1和DataSource2一起写数据,你需要保证

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

这两个操作一起成功,或者一起失败!如果采用双写的方法,是避不开这个问题的!

那么有没有通用的办法来解决这些问题呢?

有的,只要能按顺序记录数据的变更即可!那具体怎么做呢,我们继续往下看!

改良方案

假设,如果我们能将数据按顺序记录,写入某个消息队列,然后其他系统按消息顺序恢复数据,看看what happen?

此时架构图如下

在该架构下,所有的数据变更写入一个消息队列里去。其他各数据源从消息队列里恢复数据即可!

那么,此时还有一致性问题,和原子性问题么?

一致性问题

OK,这种情况下,各个数据源之间数据肯定是一致的。因为写入顺序已经在消息队列中定义好,各数据源按照消息队列中的消息顺序,恢复数据即可,并不存在竞争现象。因此,不会出现不一致的问题!

原子性问题

OK,这种情况下,如果写入DataSource失败会怎么样?例如出现了网络问题,这条消息恢复失败了。这个问题其实好解决,一般我们在顺序根据消息恢复数据的时候,会记录下坐标。如果写入失败,停止恢复数据。下次从该坐标处恢复数据即可。

但是在上面那张图中,写入DataBase是异步写入的。这样就不符合很多业务场景的"写后即读"的要求,因此,在实际落地中,做了一些变更!通用做法是去提取数据库的变化!

如下图所示

在该图中的中间件,例如oracle中的oracle golden gate可以提取数据变化。mysql中的canal能提取数据的变化。至于消息队列,可以选用kafka。直接提取数据变化到kafka中,其他数据源从kafka中获取数据,避免了直接双写从而导致一致性和原子性问题。

总结

本问讨论了在项目中常见的数据同步问题,希望大家有所收获。

相关 [面试 系统] 推荐:

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

- - IT瘾-tuicool
面试官:"阿雄是吧,做做自我介绍!". 阿  雄:"我叫阿雄,来自某a国际电商公司. 面试官:"我看你项目里用了elasticsearch,你是怎么同步数据的呢?". 阿  雄:"在代码里写入数据库的时候,同时再写入elasticsearch. 面试官:"那你如何保证写入数据库,和写入elasticsearch原子性问题呢.

高并发面试必问:分布式消息系统Kafka简介

- - ITeye博客
Kafka是分布式发布-订阅消息系统. 它最初由LinkedIn公司开发,之后成为Apache项目的一部分. Kafka是一个分布式的,可划分的,冗余备份的持久性的日志服务. 在大数据系统中,常常会碰到一个问题,整个大数据是由各个子系统组成,数据需要在各个子系统中高性能,低延迟的不停流转. 传统的企业消息系统并不是非常适合大规模的数据处理.

变态面试

- Tony - 叫兽与你同在

RoBa:Facebook 面试 Q&A

- - 博客 - 伯乐在线
前言:本文作者 RoBa ,据其个人博客中简绍是在腾讯北京搜索部门做后台开发工作. 他最近拿到 Facebook 入职 Offer 后,不少读者对此事有些提问. 本文是 Roba 做的问题答复总结. 说实话,其实我的眼界从来很狭窄,以前想的是,如果能在天朝帝都扎下脚跟,过上老婆孩子热炕头的日子,对我来说已很满足.

Hibernate面试题

- - ITeye博客
什么是Hibernate的并发机制. Hibernate并发机制:. a、Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个的工作单元(即单个事务,单个线程),它通常只使用一次,. 如果一个Session 实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用.

java面试题

- - Java - 编程语言 - ITeye博客
 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面. 抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节. 抽象包括两个方面,一是过程抽象,二是数据抽象.  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法. 对象的一个新类可以从现有的类中派生,这个过程称为类继承.

面试技巧

- - 非技术 - ITeye博客
问题一:“请你自我介绍一下” .   1、这是面试的必考题目.   2、介绍内容要与个人简历相一致.   3、表述方式上尽量口语化.   4、要切中要害,不谈无关、无用的内容.   5、条理要清晰,层次要分明.   6、事先最好以文字的形式写好背熟. 问题二:“谈谈你的家庭情况” .   1、 况对于了解应聘者的性格、观念、心态等有一定的作用,这是招聘单位问该问题的主要原因.

SQL Server 面试

- - SQL - 编程语言 - ITeye博客
在SQL语言中,一个SELECT…FROM…WHERE语句称为一个查询块,将一个查询块嵌套在另一个查询块的WHERE子句中的查询称为子查询. 子查询分为嵌套子查询和相关子查询两种. 嵌套子查询的求解方法是由里向外处理,即每个子查询在其上一级查询处理之前求解,子查询的结果作为其父查询的查询条件. 子查询只执行一次,且可以单独执行;.

面试总结

- - A programmer's life
最近我在找工作,面试了多家公司:百度、阿里、小米、美团、Yahoo、Symantec、Amazon. 其中Amazon面的是供应链(被HR忽悠的),fail了. 其它拿到了offer,但是都有些不如意. 很多公司给我的薪水和职级只相当于毕业1-2年的人的水平,而我已经毕业7年了,所以这些公司的尽管给我发了offer,在我看来他们不过是婉拒了我.

壳系统

- Vernsu - It Talks-魏武挥的blog
经常有人被我问到“你用什么浏览器”时的答案是:傲游啦360啦,但事实上,这些都不是真正的浏览器,从技术角度讲,充其量只是在IE浏览器上加一个壳罢了. 在国外,壳浏览器是以“皮肤”的形式存在,纯属为了美化浏览器而用. 但在中国,壳浏览器成了一门生意. 奇虎的主要收入来源并非来自那个由于一场商战而赫赫有名的安全卫士,而是来自于360浏览器(它有两个版本,分别以IE和Chrome为内核).