自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

字節(jié)終面:為什么在系統(tǒng)中不推薦雙寫?

開發(fā) 前端 開發(fā)工具
去某大廠面試,到了終面,面試官問我:為什么在系統(tǒng)中不推薦雙寫?我竟然沒答上來(lái)......

[[422466]]

圖片來(lái)自 包圖網(wǎng)

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

  • 面試官:"阿雄是吧,做做自我介紹!"
  • 阿雄:"我叫阿雄,來(lái)自某 a 國(guó)際電商公司!"
  • 面試官:"我看你項(xiàng)目里用了 Elasticsearch,你是怎么同步數(shù)據(jù)的呢?"
  • 阿雄:"在代碼里寫入數(shù)據(jù)庫(kù)的時(shí)候,同時(shí)再寫入 Elasticsearch!"
  • 面試官:"那你如何保證寫入數(shù)據(jù)庫(kù),和寫入 Elasticsearch 原子性問題呢?萬(wàn)一寫入數(shù)據(jù)庫(kù)成功了,寫入 Elasticsearch 失敗了怎么處理?"
  • 阿雄:"我還是回去等通知吧!"

其實(shí)這篇文章所探討的數(shù)據(jù)同步策略并不限于某兩種固定的存儲(chǔ)系統(tǒng)之間,而想去探討一種通用的數(shù)據(jù)同步策略。

主要分為以下三個(gè)部分:

  • 背景介紹
  • 雙寫缺點(diǎn)
  • 改良方案

背景介紹

話說阿雄在加入某 a 國(guó)際電商公司的時(shí)候,業(yè)務(wù)系統(tǒng)十分簡(jiǎn)單,一個(gè) DataBase 就能搞定一切!

可是某 a 國(guó)際電商公司在產(chǎn)品韓的領(lǐng)導(dǎo)下,業(yè)務(wù)增長(zhǎng)迅速,阿雄發(fā)現(xiàn)了數(shù)據(jù)庫(kù)越來(lái)越慢,于是乎阿雄加入了一些緩存,如 Redis 來(lái)緩存一些數(shù)據(jù),提高系統(tǒng)的響應(yīng)能力。

又過了一段時(shí)間,產(chǎn)品韓發(fā)現(xiàn)搜索的速度灰常慢,讓阿雄去改。阿雄在網(wǎng)上發(fā)現(xiàn),現(xiàn)在業(yè)內(nèi)都用一些 Elasticsearch 做一些全文檢索的操作,于是乎阿雄將一些需要全文檢索的數(shù)據(jù)放入 Elasticsearch,提高了系統(tǒng)的搜索能力!

隨著數(shù)據(jù)的膨脹,阿雄慢慢的發(fā)現(xiàn)了,對(duì)數(shù)據(jù)庫(kù)做一些數(shù)據(jù)分析操作,性能明顯的跟不上了。于是乎阿雄將數(shù)據(jù)庫(kù)里的數(shù)據(jù),導(dǎo)入 Hadoop,然后進(jìn)行數(shù)據(jù)分析。

省略一萬(wàn)字….最后,阿雄和產(chǎn)品韓幸福的在一起了。OK,好,現(xiàn)在分析上面的場(chǎng)景!思考第一個(gè)問題。

①在 DataBase,Redis,Elasticsearch,Hadoop 中的數(shù)據(jù)是有關(guān)系的,還是彼此獨(dú)立的?

顯然是有關(guān)系的,在這幾個(gè)數(shù)據(jù)源中的數(shù)據(jù)都是相關(guān)的。只是格式不一樣而已!

例如,對(duì)于一條 Product 數(shù)據(jù),在數(shù)據(jù)庫(kù)里是:

在 Redis 里就是 key 為 product:pId:1,value 是:

  1. {       "pId""1"
  2.     "productName""macbook" 

如上所示,只是數(shù)據(jù)格式不一樣而已!那好,現(xiàn)在思考第二個(gè)問題。

②既然這些數(shù)據(jù)源之間數(shù)據(jù)是相關(guān)的,如何保證這幾個(gè)數(shù)據(jù)源之間數(shù)據(jù)一致性?

一種比較簡(jiǎn)單且容易想到的方案是,hardcode 在程序中。例如現(xiàn)在有兩個(gè)數(shù)據(jù)源 DataSouce1 和 DataSource2,我們往里頭寫數(shù)據(jù)。

代碼如下:

  1. ProductService{ 
  2.     \\省略 
  3.     public void syncData(){ 
  4.         x1. writeDataSource1(); 
  5.         x2. writeDataSource2(); 
  6.     } 

這就是我們標(biāo)題中所提到的雙寫!那么,雙寫會(huì)帶來(lái)什么壞處呢?OK,繼續(xù)往下看!

雙寫缺點(diǎn)

①一致性問題

打個(gè)比方我們現(xiàn)在有兩個(gè) client,同時(shí)往兩個(gè) DataSouce 寫數(shù)據(jù):

  • 一個(gè) client 往里頭入 X 為 1
  • 一個(gè) client 往里頭入 X 為 5

那么會(huì)有如下情形出現(xiàn):

如圖所示,兩個(gè) DataSouce 的數(shù)據(jù)就不一致了,一個(gè)為 1,一個(gè)為 5。除非接下來(lái)有一個(gè)新的請(qǐng)求,對(duì) x 數(shù)據(jù)發(fā)生了變更,才能修正這種現(xiàn)象!否則,你可能永遠(yuǎn)都發(fā)現(xiàn)不了。

②原子性問題

因?yàn)槲覀冃枰瑫r(shí)往 DataSource1 和 DataSource2 一起寫數(shù)據(jù),你需要保證:

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

這兩個(gè)操作一起成功,或者一起失敗!如果采用雙寫的方法,是避不開這個(gè)問題的!

那么有沒有通用的辦法來(lái)解決這些問題呢?有的,只要能按順序記錄數(shù)據(jù)的變更即可!那具體怎么做呢,我們繼續(xù)往下看!

改良方案

假設(shè),如果我們能將數(shù)據(jù)按順序記錄,寫入某個(gè)消息隊(duì)列,然后其他系統(tǒng)按消息順序恢復(fù)數(shù)據(jù),看看 what happen?

此時(shí)架構(gòu)圖如下:

在該架構(gòu)下,所有的數(shù)據(jù)變更寫入一個(gè)消息隊(duì)列里去。其他各數(shù)據(jù)源從消息隊(duì)列里恢復(fù)數(shù)據(jù)即可!

那么,此時(shí)還有一致性問題,和原子性問題么?

①一致性問題

OK,這種情況下,各個(gè)數(shù)據(jù)源之間數(shù)據(jù)肯定是一致的。因?yàn)閷懭腠樞蛞呀?jīng)在消息隊(duì)列中定義好,各數(shù)據(jù)源按照消息隊(duì)列中的消息順序,恢復(fù)數(shù)據(jù)即可,并不存在競(jìng)爭(zhēng)現(xiàn)象。因此,不會(huì)出現(xiàn)不一致的問題!

②原子性問題

OK,這種情況下,如果寫入 DataSource 失敗會(huì)怎么樣?例如出現(xiàn)了網(wǎng)絡(luò)問題,這條消息恢復(fù)失敗了。

這個(gè)問題其實(shí)好解決,一般我們?cè)陧樞蚋鶕?jù)消息恢復(fù)數(shù)據(jù)的時(shí)候,會(huì)記錄下坐標(biāo)。如果寫入失敗,停止恢復(fù)數(shù)據(jù)。下次從該坐標(biāo)處恢復(fù)數(shù)據(jù)即可。

但是在上面那張圖中,寫入 DataBase 是異步寫入的。這樣就不符合很多業(yè)務(wù)場(chǎng)景的"寫后即讀"的要求,因此,在實(shí)際落地中,做了一些變更!通用做法是去提取數(shù)據(jù)庫(kù)的變化!

如下圖所示:

在該圖中的中間件,例如 Oracle 中的 oracle golden gate 可以提取數(shù)據(jù)變化。

MySQL 中的 Canal 能提取數(shù)據(jù)的變化。至于消息隊(duì)列,可以選用 Kafka。直接提取數(shù)據(jù)變化到 Kafka 中,其他數(shù)據(jù)源從 Kafka 中獲取數(shù)據(jù),避免了直接雙寫從而導(dǎo)致一致性和原子性問題。

總結(jié)

本文討論了在項(xiàng)目中常見的數(shù)據(jù)同步問題,希望大家有所收獲。

作者:孤獨(dú)煙

編輯:陶家龍

出處:轉(zhuǎn)載自公眾號(hào)孤獨(dú)煙(ID:zrj_guduyan)

責(zé)任編輯:武曉燕 來(lái)源: 孤獨(dú)煙
相關(guān)推薦

2020-08-24 10:55:41

數(shù)據(jù)庫(kù)雙寫代碼

2021-07-19 09:27:42

SSD內(nèi)存Linux

2024-11-29 08:20:22

Autowired場(chǎng)景項(xiàng)目

2022-01-11 10:29:32

Docker文件掛載

2024-11-26 08:52:34

SQL優(yōu)化Kafka

2024-11-12 10:30:54

Docker部署數(shù)據(jù)庫(kù)

2024-06-04 00:10:00

開發(fā)拷貝

2018-11-29 14:30:42

數(shù)據(jù)庫(kù)外鍵約束應(yīng)用程序

2024-09-12 08:32:42

2015-08-06 12:50:47

技術(shù)人員博客

2015-09-29 10:18:22

2022-01-17 14:24:09

共享字節(jié)面試

2024-04-03 09:01:34

SpringTomcat容器

2020-07-02 14:12:52

C++語(yǔ)言編程

2021-08-23 13:02:50

MySQLJOIN數(shù)據(jù)庫(kù)

2023-11-06 13:04:59

Python日志庫(kù)

2023-09-27 23:03:01

Java虛擬線程

2014-06-03 09:39:25

蘋果移動(dòng)操作系統(tǒng)

2024-10-10 14:34:49

2024-02-21 21:28:29

Linux系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)