一、前情提示


【資料圖】

這篇文章,咱們繼續(xù)來聊聊之前的億級流量架構(gòu)的演進(jìn)。老規(guī)矩!我們首先看一下這個復(fù)雜的系統(tǒng)架構(gòu)演進(jìn)到當(dāng)前階段,整體的架構(gòu)圖是什么樣子的。

筆者再次友情提醒,如果各位小伙伴對下面這個復(fù)雜的架構(gòu)圖還有什么不理解的地方,一定要先回看之前的文章,因為系列文必須對上下文有清晰的理解和認(rèn)識。

接著文本我們來聊聊一個核心系統(tǒng)每天承載百億流量的背景下,應(yīng)該如何來保證復(fù)雜系統(tǒng)中的數(shù)據(jù)一致性?

二、什么是數(shù)據(jù)一致性?

簡單來說,在一個復(fù)雜的系統(tǒng)中一定會對一些數(shù)據(jù)做出非常復(fù)雜的處理,而且可能是多個不同的子系統(tǒng),甚至是多個服務(wù)。

對一個數(shù)據(jù)按照一定的順序依次做出復(fù)雜的業(yè)務(wù)邏輯的執(zhí)行,最終可能就會生產(chǎn)出一份寶貴的系統(tǒng)核心數(shù)據(jù),落地到存儲里去,比如說在數(shù)據(jù)庫里存儲。

給大家來一張手繪彩圖,感受下這個現(xiàn)場的氛圍:

從上圖中我們就可以看到,多個系統(tǒng)如何對一個數(shù)據(jù)依次進(jìn)行處理,最終拿到一份核心數(shù)據(jù),并落地到存儲里去。

那么在這個過程中,就可能會產(chǎn)生所謂的數(shù)據(jù)不一致的問題。

什么意思呢?給大家舉一個最簡單的例子,我們本來期望數(shù)據(jù)的變化過程是:數(shù)據(jù)1 -> 數(shù)據(jù)2 -> 數(shù)據(jù)3 -> 數(shù)據(jù)4。

那么最后落地到數(shù)據(jù)庫里的應(yīng)該是數(shù)據(jù)4,對不對?

結(jié)果呢?不知道為啥,經(jīng)過上面那個復(fù)雜的分布式系統(tǒng)中的各個子系統(tǒng),或者是各個服務(wù)的協(xié)作處理,最后居然搞出來一個數(shù)據(jù)87。

搞了半天,搞了一個跟數(shù)據(jù)4風(fēng)馬牛不相及的一個東西,最后落地到了數(shù)據(jù)庫里。

然后啊,這套系統(tǒng)的最終用戶,可能通過前臺的界面看到了一個莫名其妙的數(shù)據(jù)87。

這就尷尬了,用戶明顯會覺得這個數(shù)據(jù)有錯誤,就會反饋給公司的客服,此時就會上報bug到工程師團(tuán)隊,大家就開始吭哧吭哧的找問題。

上面說的這個場景,其實就是一種數(shù)據(jù)不一致的問題,也是我們接下來幾篇文章要討論的一個問題。

實際上,在任何一個大規(guī)模分布式系統(tǒng)里,都會存在類似的問題。無論是電商,O2O,還是本文舉例的數(shù)據(jù)平臺系統(tǒng),都一樣。

三、一個數(shù)據(jù)計算鏈路的梳理

那么既然已經(jīng)明確了問題,接下來就來看看在數(shù)據(jù)平臺這個系統(tǒng)里,到底是什么問題可能會導(dǎo)致一個最終落地存儲的數(shù)據(jù)的異常呢?

要明白這個問題,咱們先回過頭看看,在之前提過的數(shù)據(jù)平臺這個項目里,一個最終落地的數(shù)據(jù)的計算鏈路是什么樣的?

大家看看下面的圖:

如上圖所示,其實從最簡單的一個角度來說,這個數(shù)據(jù)計算的鏈路大概也就是上面的那個樣子。

首先,通過MySQL binlog采集中間件獲取到數(shù)據(jù),轉(zhuǎn)發(fā)給數(shù)據(jù)接入層。然后,數(shù)據(jù)接入層會把原始數(shù)據(jù)落地到kv存儲里去接著,是實時計算平臺會從kv存儲里提取數(shù)據(jù)進(jìn)行計算最后,會將計算結(jié)果寫入到數(shù)據(jù)庫+緩存的集群里。數(shù)據(jù)查詢平臺會從數(shù)據(jù)庫 + 緩存的集群里提取數(shù)據(jù),提供用戶來進(jìn)行查詢

看起來很簡單,對吧?

但是哪怕是這個系統(tǒng)里,數(shù)據(jù)計算鏈路,也絕對不是這么簡單的。

如果大家看過之前的系列文章的話,就應(yīng)該知道,這個系統(tǒng)為了支撐高并發(fā)、高可用、高性能等場景,引入了大量的復(fù)雜機(jī)制。

所以實際上一條原始數(shù)據(jù)進(jìn)入到系統(tǒng),一直到最后落地到存儲里,計算鏈路還會包含下面的東西:

接入層的限流處理實時計算層的失敗重試實時計算層的本地內(nèi)存存儲的降級機(jī)制數(shù)據(jù)分片的聚合與計算,單條數(shù)據(jù)在這里可能會進(jìn)入一個數(shù)據(jù)分片里數(shù)據(jù)查詢層的多級緩存機(jī)制

上面只不過是隨便列舉了幾條。然而哪怕只是上述幾條,都可以把一個數(shù)據(jù)的計算鏈路變得復(fù)雜很多倍了。

四、數(shù)據(jù)計算鏈路的bug

既然大家已經(jīng)明白了,在一個復(fù)雜系統(tǒng)里,一份核心數(shù)據(jù)可能是經(jīng)過一個極為復(fù)雜的計算鏈路的處理,中間百轉(zhuǎn)千回,任何可能的情況都會發(fā)生。

那么就可以理解在大型分布式系統(tǒng)中,數(shù)據(jù)不一致的問題是如何產(chǎn)生的了。

其實原因非常的簡單,說白了,就是數(shù)據(jù)計算鏈路的bug。

也就是說,在數(shù)據(jù)的計算過程中,某個子系統(tǒng)出現(xiàn)了bug,并沒有按照我們預(yù)期的行為去處理,導(dǎo)致最終產(chǎn)出去的數(shù)據(jù)變得錯誤了。

那么,為什么會在數(shù)據(jù)計算鏈路中出現(xiàn)這種bug呢?

原因很簡單,如果大家曾經(jīng)參與過上百人協(xié)作的大型分布式系統(tǒng),或者是主導(dǎo)過上百人協(xié)作開發(fā)的大型分布式系統(tǒng)的架構(gòu)設(shè)計,應(yīng)該對核心數(shù)據(jù)的異常和錯誤非常熟悉,并且會感到頭疼不已。

大規(guī)模分布式系統(tǒng)中,動輒上百人協(xié)作開發(fā)。很可能某個子系統(tǒng)或者是某個服務(wù)的負(fù)責(zé)人,對數(shù)據(jù)的處理邏輯理解偏差了,代碼里寫了一個隱藏的bug。

而這個bug,輕易不會觸發(fā),并且在QA測試環(huán)境還沒測出來,結(jié)果帶著一顆定時炸彈,系統(tǒng)上線。

最后在線上某種特殊的場景下,觸發(fā)了這個bug,導(dǎo)致最終的數(shù)據(jù)出現(xiàn)問題。

五、電商庫存數(shù)據(jù)的不一致問題

接觸過電商的同學(xué),可能此時腦子里就可以快速的想到一個類似的經(jīng)典場景:電商中的庫存。

在大規(guī)模的電商系統(tǒng)中,庫存數(shù)據(jù)絕對是核心中的核心。但是實際上,在一個分布式系統(tǒng)中,很多系統(tǒng)可能都會采用一定的邏輯來更新庫存。

這就可能導(dǎo)致跟上述說的場景類似的問題,就是多個系統(tǒng)都更新庫存,但就是某個系統(tǒng)對庫存的更新出現(xiàn)了bug。

這可能是因為那個系統(tǒng)的負(fù)責(zé)人沒理解到底應(yīng)該如何更新庫存,也或者是他更新的時候采用的邏輯,沒有考慮到一些特殊情況。

這樣導(dǎo)致的結(jié)果就是,系統(tǒng)里的庫存和倉庫中實際的庫存,死活對不上。但就是不知道到底哪個環(huán)節(jié)出了問題,導(dǎo)致庫存數(shù)據(jù)出錯。

這個,其實就是一個典型的數(shù)據(jù)不一致的問題。

六、大型系統(tǒng)的數(shù)據(jù)不一致排查有多困難

當(dāng)面對一個大型分布式系統(tǒng)時,如果你之前壓根兒沒考慮過數(shù)據(jù)不一致的問題,那么我敢打賭,當(dāng)你負(fù)責(zé)的系統(tǒng)在線上被客服反饋有某個核心數(shù)據(jù)不一致的時候,你絕對會一臉蒙圈。

因為一個核心數(shù)據(jù)的處理,少則涉及幾個系統(tǒng)的協(xié)作處理,多則涉及十個以上的系統(tǒng)的協(xié)作處理。

如果你沒有留存任何日志、或者僅僅就是有部分日志,然后基本就只能所有人干瞪眼,大家大眼對小眼,都盯著自己的代碼看。

大家根據(jù)一個數(shù)據(jù)最后的錯誤結(jié)果,比如數(shù)據(jù)87。10多個人對著自己的代碼,反復(fù)的思考,冥思苦想。

然后每個人都在大腦中瘋狂的模擬自己代碼的運(yùn)行,但是就是想不明白,為什么本來應(yīng)該是數(shù)據(jù)4的,結(jié)果出來了一個數(shù)據(jù)87?

所以現(xiàn)實問題就是這樣,這種數(shù)據(jù)不一致的問題,大概有以下幾個痛點(diǎn):

自己基本無法主動提前感知到數(shù)據(jù)問題,要被動等待用戶發(fā)現(xiàn),反饋給客服,這很可能導(dǎo)致你的產(chǎn)品被大量投訴,老板很生氣,后果很嚴(yán)重。

即使客服告訴了你數(shù)據(jù)錯了,但是你們沒法還原現(xiàn)場,沒有留存證據(jù),基本就是一群工程師對著代碼想象,猜測。

即使你解決了一次數(shù)據(jù)不一致的問題,但是以后也許還有下一次,這樣搞下去,會導(dǎo)致團(tuán)隊里好幾個能干的小伙兒時間都搭在這種破事兒上。

標(biāo)簽: