程序員,你怎么對(duì)待常見的數(shù)據(jù)一致性問(wèn)題吼和?

現(xiàn)象

應(yīng)用系統(tǒng)中的關(guān)鍵服務(wù)絕大部分都會(huì)是對(duì)數(shù)據(jù)庫(kù)的依賴涨薪。

當(dāng)多個(gè)進(jìn)程同時(shí)操作同一個(gè)數(shù)據(jù),會(huì)產(chǎn)生資源爭(zhēng)搶炫乓,數(shù)據(jù)一致性的問(wèn)題刚夺。

如果只有一個(gè)數(shù)據(jù)庫(kù)服務(wù)器,數(shù)據(jù)一致性問(wèn)題也就不存在了末捣。

可是侠姑,隨著系統(tǒng)訪問(wèn)量、數(shù)據(jù)量的不斷增長(zhǎng)箩做,數(shù)據(jù)庫(kù)出現(xiàn)多個(gè)服務(wù)器莽红,又出現(xiàn)緩存服務(wù),又要拆分?jǐn)?shù)據(jù)庫(kù)邦邦,還要分拆到不同的子應(yīng)用等等安吁。

這樣一來(lái),數(shù)據(jù)一致性問(wèn)題就會(huì)變得越來(lái)越突出燃辖。

舉個(gè)栗子

我們來(lái)看這樣一個(gè)數(shù)據(jù)流程鬼店。

  • 用戶提交一個(gè)訂單(2個(gè)不同商家各一件商品)——數(shù)據(jù)源頭

  • 應(yīng)用服務(wù)器驗(yàn)證用戶信息、訂單信息黔龟、庫(kù)存信息等等薪韩,然后將這個(gè)訂單發(fā)送到訂單消息隊(duì)列——消息隊(duì)列

  • 訂單處理服務(wù)器從消息隊(duì)列中拿到新訂單,接下來(lái)的處理捌锭,可能做的數(shù)據(jù)操作有:

    1. 生成一個(gè)訂單/也可能會(huì)分拆為兩個(gè)訂單

    2. 更新兩個(gè)商品庫(kù)存數(shù)量

    3. 更新商家的銷售數(shù)據(jù)

    4. 生成訂單對(duì)應(yīng)的支付信息

    5. 生成用戶訂單成功的狀態(tài)信息

思路

上面的數(shù)據(jù)處理中俘陷,涉及到的數(shù)據(jù)有:訂單數(shù)據(jù)、商品數(shù)據(jù)观谦、商家數(shù)據(jù)拉盾、支付數(shù)據(jù)、用戶數(shù)據(jù)豁状。

涉及到的應(yīng)用和服務(wù)有:前端應(yīng)用系統(tǒng)捉偏,消息隊(duì)列倒得,后端應(yīng)用系統(tǒng),數(shù)據(jù)庫(kù)夭禽,緩存霞掺,甚至訂單、商品讹躯、商家菩彬、支付、用戶可能都是獨(dú)立的子應(yīng)用潮梯。

可能大部分系統(tǒng)不會(huì)像上面這么龐大骗灶。

如果前后端都是一起的,也就沒有消息隊(duì)列秉馏。

如果也沒有這些子系統(tǒng)耙旦,數(shù)據(jù)庫(kù)是集中的,那可能數(shù)據(jù)一致性問(wèn)題會(huì)稍微小些萝究。

這時(shí)候免都,只需要注意數(shù)據(jù)庫(kù)更新的一致性就好了,比較容易想到的應(yīng)對(duì)方法帆竹,就是用數(shù)據(jù)庫(kù)事務(wù)來(lái)保證琴昆。

如果這些數(shù)據(jù)不只是一份數(shù)據(jù)庫(kù),還有緩存中一份馆揉,又要考慮緩存數(shù)據(jù)的更新业舍,所以問(wèn)題還是復(fù)雜了。

數(shù)據(jù)庫(kù)更新升酣,怎么保證緩存也能正常更新呢舷暮?

  • 程序中處理,數(shù)據(jù)庫(kù)更新后噩茄,就要馬上更新緩存數(shù)據(jù)

  • 如果緩存更新失敗或者程序出現(xiàn)異常下面,要有異常處理方法

  • 異常處理方法可以是程序中實(shí)時(shí)的糾正或者重試

  • 異常處理方法也可以是針對(duì)數(shù)據(jù)庫(kù)的更新,二次檢查緩存數(shù)據(jù)的更新

這里還只是一個(gè)數(shù)據(jù)庫(kù)和一個(gè)緩存的情況绩聘,已經(jīng)要做出這么多事情沥割。

那這些工作帶來(lái)的影響有哪些呢?

  • 程序開發(fā)更加復(fù)雜凿菩,不能有些許的遺漏

  • 數(shù)據(jù)驗(yàn)證和重試帶來(lái)的性能下降

  • 數(shù)據(jù)庫(kù)事務(wù)帶來(lái)的數(shù)據(jù)庫(kù)瓶頸明顯

  • 二次檢查再次增加復(fù)雜度和額外開銷

本來(lái)一個(gè)訂單處理机杜,如果不考慮數(shù)據(jù)一致性問(wèn)題,數(shù)據(jù)庫(kù)寫入/更新510次衅谷,緩存寫入/更新510次椒拗,整個(gè)過(guò)程應(yīng)該在10ms內(nèi)完成。

但是加上數(shù)據(jù)庫(kù)事務(wù)之后,會(huì)把這些操作中涉及到的幾個(gè)表都加鎖蚀苛,意味著數(shù)據(jù)的讀在验、寫都串行化了,整個(gè)應(yīng)用系統(tǒng)的并發(fā)能力急劇下降堵未。

當(dāng)然腋舌,因?yàn)檫@里引入緩存,對(duì)數(shù)據(jù)庫(kù)的依賴會(huì)減少很多渗蟹,而且還有從庫(kù)可以提供讀的服務(wù)块饺,應(yīng)用系統(tǒng)的訪問(wèn)并發(fā)能力不至于下降太多。

但這些代價(jià)在交易處理中是難以避免的拙徽,為了解決數(shù)據(jù)一致性問(wèn)題刨沦,犧牲的是訂單處理的并發(fā)能力诗宣。

對(duì)于大部分商城膘怕、網(wǎng)站,訂單并發(fā)量也不高召庞,這類問(wèn)題不太常發(fā)生岛心,所以也就這么過(guò)去了。

但是在一些促銷活動(dòng)的時(shí)候篮灼,肯定還是會(huì)遇到下單等待太久的問(wèn)題忘古。

瓶頸

為了具備更大并發(fā)的訂單處理能力,單數(shù)據(jù)庫(kù)诅诱、緩存肯定是行不通了髓堪。

那么要在這么多的子應(yīng)用、大量的數(shù)據(jù)庫(kù)娘荡、緩存服務(wù)中保持?jǐn)?shù)據(jù)一致性又要怎么做呢干旁?

  • 每個(gè)子應(yīng)用都要支持分布式事務(wù),共同保證數(shù)據(jù)庫(kù)全部成功更新

  • 每個(gè)子應(yīng)用各自要保證自己的數(shù)據(jù)更新一致性(異常處理炮沐、重試争群、二次檢查等方法同上)

上面看上去只有兩條,但是要做的事情和困難會(huì)比上面要多十倍,難百倍大年。

看到這里换薄,是不是對(duì)于數(shù)據(jù)一致性的問(wèn)題都有點(diǎn)絕望了。

真相

正因如此翔试,大部分的分布式系統(tǒng),大部分應(yīng)用,是沒有做到數(shù)據(jù)一致性轻要,哪怕是弱一致性。

比如:論壇里面發(fā)帖垦缅,要更新10份左右的數(shù)據(jù)伦腐,出現(xiàn)臟數(shù)據(jù)是常有的,這就是沒有做到數(shù)據(jù)一致性失都。

比如:商城里面庫(kù)存超賣柏蘑,訂單狀態(tài)不一致等幸冻,也是因?yàn)闆]有做到數(shù)據(jù)一致性。

之所以會(huì)這樣咳焚,因?yàn)橥度氘a(chǎn)出嚴(yán)重不成比例洽损,是很無(wú)奈的選擇。

數(shù)據(jù)不一致的情況畢竟比例極低革半,但是投入的代價(jià)卻極大碑定。

數(shù)據(jù)不一致引發(fā)的后果,可以忍受和容忍又官,哪怕是發(fā)現(xiàn)后再修正延刘。

那么,還有什么辦法可以避免或減少出現(xiàn)數(shù)據(jù)一致性問(wèn)題呢六敬?

下面有幾個(gè)方法可以考慮:

  • 將系統(tǒng)規(guī)模和容量降低碘赖,保證系統(tǒng)的穩(wěn)定性和高效;

一個(gè)每秒鐘上百萬(wàn)請(qǐng)求的應(yīng)用系統(tǒng)能不能分拆為1000個(gè)每秒鐘1000請(qǐng)求的獨(dú)立集群呢外构?

一個(gè)上百萬(wàn)的商家普泡、商品、訂單庫(kù)审编,能不能分拆為1000個(gè)只有1000個(gè)商家撼班、商品、訂單的子庫(kù)呢垒酬?

  • 將數(shù)據(jù)關(guān)聯(lián)降低砰嘁,減少更新次數(shù),減少不一致問(wèn)題的出現(xiàn)概率勘究;

上面的訂單矮湘、庫(kù)存、商家乱顾、支付板祝、用戶幾個(gè)數(shù)據(jù),核心數(shù)據(jù)只有訂單走净,其他的幾個(gè)數(shù)據(jù)完全可以從訂單數(shù)據(jù)推導(dǎo)出來(lái)券时,減少訂單處理中的一致性要求。

  • 將應(yīng)用分拆伏伯,對(duì)性能和一致性要求高的應(yīng)用獨(dú)立實(shí)現(xiàn)橘洞;

減少業(yè)務(wù)耦合,集中資源重點(diǎn)投入说搅。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末炸枣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌适肠,老刑警劉巖霍衫,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異侯养,居然都是意外死亡敦跌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門逛揩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)柠傍,“玉大人,你說(shuō)我怎么就攤上這事辩稽【宓眩” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵逞泄,是天一觀的道長(zhǎng)患整。 經(jīng)常有香客問(wèn)我,道長(zhǎng)炭懊,這世上最難降的妖魔是什么并级? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任拂檩,我火速辦了婚禮侮腹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘稻励。我一直安慰自己父阻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布望抽。 她就那樣靜靜地躺著加矛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪煤篙。 梳的紋絲不亂的頭發(fā)上斟览,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音辑奈,去河邊找鬼苛茂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鸠窗,可吹牛的內(nèi)容都是我干的妓羊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼稍计,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼躁绸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤净刮,失蹤者是張志新(化名)和其女友劉穎剥哑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淹父,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡星持,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弹灭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片督暂。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖穷吮,靈堂內(nèi)的尸體忽然破棺而出逻翁,到底是詐尸還是另有隱情,我是刑警寧澤捡鱼,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布八回,位于F島的核電站,受9級(jí)特大地震影響驾诈,放射性物質(zhì)發(fā)生泄漏缠诅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一乍迄、第九天 我趴在偏房一處隱蔽的房頂上張望管引。 院中可真熱鬧,春花似錦闯两、人聲如沸僧家。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)今阳。三九已至,卻和暖如春逊躁,著一層夾襖步出監(jiān)牢的瞬間似踱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工稽煤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留核芽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓念脯,卻偏偏與公主長(zhǎng)得像狞洋,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子绿店,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容