29 | 異地多活設(shè)計4大技巧?

跨城異地多活是架構(gòu)設(shè)計復(fù)雜度最高的一種春塌,接下來我將介紹跨城異地多活架構(gòu)

技巧 1:保證核心業(yè)務(wù)的異地多活

“異地多活”是為了保證業(yè)務(wù)的高可用,但很多架構(gòu)師在考慮這個“業(yè)務(wù)”時,會不自覺地陷入一個思維誤區(qū):我要保證所有業(yè)務(wù)都能“異地多活”碘菜!

假設(shè)我們需要做一個“用戶子系統(tǒng)”律姨,這個子系統(tǒng)負(fù)責(zé)“注冊”“登錄”“用戶信息”三個業(yè)務(wù)。為了支持海量用戶公般,我們設(shè)計了一個“用戶分區(qū)”的架構(gòu)万搔,即正常情況下用戶屬于某個主分區(qū),每個分區(qū)都有其他數(shù)據(jù)的備份官帘,用戶用郵箱或者手機號注冊瞬雹,路由層拿到郵箱或者手機號后,通過 Hash 計算屬于哪個中心刽虹,然后請求對應(yīng)的業(yè)務(wù)中心酗捌。基本的架構(gòu)如下:

這樣一個系統(tǒng)涌哲,如果 3 個業(yè)務(wù)要同時實現(xiàn)異地多活胖缤,會發(fā)現(xiàn)這些難以解決的問題:

注冊問題

A 中心注冊了用戶,數(shù)據(jù)還未同步到 B 中心阀圾,此時 A 中心宕機哪廓,為了支持注冊業(yè)務(wù)多活,可以挑選 B 中心讓用戶去重新注冊稍刀×枚溃看起來很容易就支持多活了敞曹,但仔細(xì)思考一下會發(fā)現(xiàn)這樣做會有問題:一個手機號只能注冊一個賬號,A 中心的數(shù)據(jù)沒有同步過來综膀,B 中心無法判斷這個手機號是否重復(fù)澳迫,如果 B 中心讓用戶注冊,后來 A 中心恢復(fù)了剧劝,發(fā)現(xiàn)數(shù)據(jù)有沖突橄登,怎么解決?實際上是無法解決的讥此,因為同一個手機號注冊的賬號不能以后一次注冊為準(zhǔn)拢锹;而如果 B 中心不支持本來屬于 A 中心的業(yè)務(wù)進(jìn)行注冊,注冊業(yè)務(wù)的多活又成了空談萄喳。

如果我們修改業(yè)務(wù)規(guī)則卒稳,允許一個手機號注冊多個賬號不就可以了嗎?

這樣做是不可行的他巨,類似一個手機號只能注冊一個賬號這種規(guī)則充坑,是核心業(yè)務(wù)規(guī)則,修改核心業(yè)務(wù)規(guī)則的代價非常大染突,幾乎所有的業(yè)務(wù)都要重新設(shè)計捻爷,為了架構(gòu)設(shè)計去改變業(yè)務(wù)規(guī)則(而且是這么核心的業(yè)務(wù)規(guī)則)是得不償失的。

用戶信息問題

用戶信息的修改和注冊有類似的問題份企,即 A也榄、B 兩個中心在異常的情況下都修改了用戶信息如何處理沖突司志?

由于用戶信息并沒有賬號那么關(guān)鍵甜紫,一種簡單的處理方式是按照時間合并,即最后修改的生效俐芯。業(yè)務(wù)邏輯上沒問題棵介,但實際操作也有一個很關(guān)鍵的“坑”:怎么保證多個中心所有機器時間絕對一致?在異地多中心的網(wǎng)絡(luò)下吧史,這個是無法保證的邮辽,即使有時間同步也無法完全保證,只要兩個中心的時間誤差超過 1 秒贸营,數(shù)據(jù)就可能出現(xiàn)混亂吨述,即先修改的反而生效。

還有一種方式是生成全局唯一遞增 ID钞脂,這個方案的成本很高揣云,因為這個全局唯一遞增 ID 的系統(tǒng)本身又要考慮異地多活,同樣涉及數(shù)據(jù)一致性和沖突的問題冰啃。

優(yōu)先實現(xiàn)核心業(yè)務(wù)的異地多活架構(gòu)邓夕!

對于這個模擬案例來說刘莹,“登錄”才是最核心的業(yè)務(wù),“注冊”和“用戶信息”雖然也是主要業(yè)務(wù)焚刚,但并不一定要實現(xiàn)異地多活点弯,主要原因在于業(yè)務(wù)影響不同。對于一個日活 1000 萬的業(yè)務(wù)來說矿咕,每天注冊用戶可能是幾萬抢肛,修改用戶信息的可能還不到 1 萬,但登錄用戶是 1000 萬碳柱,很明顯我們應(yīng)該保證登錄的異地多活捡絮。

而登錄實現(xiàn)“異地多活”恰恰是最簡單的,因為每個中心都有所有用戶的賬號和密碼信息莲镣,用戶在哪個中心都可以登錄福稳。用戶在 A 中心登錄,A 中心宕機后剥悟,用戶到 B 中心重新登錄即可灵寺。

如果某個用戶在 A 中心修改了密碼,此時數(shù)據(jù)還沒有同步到 B 中心区岗,用戶到 B 中心登錄是無法登錄的這個怎么處理毁枯?

技巧 2:保證核心數(shù)據(jù)最終一致性

異地多活本質(zhì)上是通過異地的數(shù)據(jù)冗余慈缔,來保證在極端異常的情況下業(yè)務(wù)也能夠正常提供給用戶。

數(shù)據(jù)冗余是要將數(shù)據(jù)從 A 地同步到 B 地种玛,從業(yè)務(wù)的角度來看是越快越好藐鹤,但不可能很快,因為這是物理定律決定的赂韵,幾種方法可以參考:

盡量減少異地多活機房的距離娱节,搭建高速網(wǎng)絡(luò)

這和我上一期講到的同城異區(qū)架構(gòu)類似,但搭建跨城異地的高速網(wǎng)絡(luò)成本遠(yuǎn)遠(yuǎn)超過同城異區(qū)的高速網(wǎng)絡(luò)祭示,成本巨大肄满,一般只有巨頭公司才能承擔(dān)

盡量減少數(shù)據(jù)同步质涛,只同步核心業(yè)務(wù)相關(guān)的數(shù)據(jù)

簡單來說就是不重要的數(shù)據(jù)不同步稠歉,同步后沒用的數(shù)據(jù)不同步,只同步核心業(yè)務(wù)相關(guān)的數(shù)據(jù)汇陆。

以前面的“用戶子系統(tǒng)”為例怒炸,用戶登錄所產(chǎn)生的 token 或者 session 信息,數(shù)據(jù)量很大毡代,但其實并不需要同步到其他業(yè)務(wù)中心阅羹,因為這些數(shù)據(jù)丟失后重新登錄就可以再次獲取了勺疼。

保證最終一致性,不保證實時一致性

例如捏鱼,A 機房注冊了一個用戶执庐,業(yè)務(wù)上不要求能夠在 50 毫秒內(nèi)就同步到所有機房,正常情況下要求 5 分鐘同步到所有機房即可穷躁,異常情況下甚至可以允許 1 小時或者 1 天后能夠一致耕肩。

最終一致性在具體實現(xiàn)時,還需要根據(jù)不同的數(shù)據(jù)特征问潭,進(jìn)行差異化的處理猿诸,以滿足業(yè)務(wù)需要。例如狡忙,對“賬號”信息來說梳虽,如果在 A 機房新注冊的用戶 5 分鐘內(nèi)正好跑到 B 機房了,此時 B 機房還沒有這個用戶的信息灾茁,為了保證業(yè)務(wù)的正確窜觉,B 機房就需要根據(jù)路由規(guī)則到 A 機房請求數(shù)據(jù)。

而對“用戶信息”來說北专,5 分鐘后同步也沒有問題禀挫,也不需要采取其他措施來彌補,但還是會影響用戶體驗拓颓,即用戶看到了舊的用戶信息语婴,這個問題怎么解決呢?

技巧 3:采用多種手段同步數(shù)據(jù)

數(shù)據(jù)同步是異地多活架構(gòu)設(shè)計的核心驶睦,幸運的是基本上存儲系統(tǒng)本身都會有同步的功能砰左。例如,MySQL 的主備復(fù)制场航、Redis 的 Cluster 功能缠导、Elasticsearch 的集群功能。這些系統(tǒng)本身的同步功能已經(jīng)比較強大溉痢,能夠直接拿來就用僻造,但這也無形中將我們引入了一個思維誤區(qū):只使用存儲系統(tǒng)的同步功能!

既然說存儲系統(tǒng)本身就有同步功能适室,而且同步功能還很強大嫡意,為何說只使用存儲系統(tǒng)是一個思維誤區(qū)呢?因為雖然絕大部分場景下捣辆,存儲系統(tǒng)本身的同步功能基本上也夠用了蔬螟,但在某些比較極端的情況下,存儲系統(tǒng)本身的同步功能可能難以滿足業(yè)務(wù)需求汽畴。

MySQL 為例旧巾,MySQL 5.1 版本的復(fù)制是單線程的復(fù)制耸序,在網(wǎng)絡(luò)抖動或者大量數(shù)據(jù)同步時,經(jīng)常發(fā)生延遲較長的問題鲁猩,短則延遲十幾秒坎怪,長則可能達(dá)到十幾分鐘。而且即使我們通過監(jiān)控的手段知道了 MySQL 同步時延較長廓握,也難以采取什么措施搅窿,只能干等。

Redis 又是另外一個問題隙券,Redis 3.0 之前沒有 Cluster 功能男应,只有主從復(fù)制功能,而為了設(shè)計上的簡單娱仔,Redis 2.8 之前的版本沐飘,主從復(fù)制有一個比較大的隱患:從機宕機或者和主機斷開連接都需要重新連接主機,重新連接主機都會觸發(fā)全量的主從復(fù)制牲迫。這時主機會生成內(nèi)存快照耐朴,主機依然可以對外提供服務(wù),但是作為讀的從機盹憎,就無法提供對外服務(wù)了筛峭,如果數(shù)據(jù)量大,恢復(fù)的時間會相當(dāng)長陪每。

可以將多種手段配合存儲系統(tǒng)的同步來使用蜒滩,甚至可以不采用存儲系統(tǒng)的同步方案,改用自己的同步方案奶稠。

還是以前面的“用戶子系統(tǒng)”為例,我們可以采用如下幾種方式同步數(shù)據(jù):

(1)消息隊列方式

對于賬號數(shù)據(jù)捡遍,由于賬號只會創(chuàng)建锌订,不會修改和刪除(假設(shè)我們不提供刪除功能),我們可以將賬號數(shù)據(jù)通過消息隊列同步到其他業(yè)務(wù)中心画株。

(2) 二次讀取方式

某些情況下可能出現(xiàn)消息隊列同步也延遲了辆飘,用戶在 A 中心注冊,然后訪問 B 中心的業(yè)務(wù)谓传,此時 B 中心本地拿不到用戶的賬號數(shù)據(jù)蜈项。為了解決這個問題,B 中心在讀取本地數(shù)據(jù)失敗時续挟,可以根據(jù)路由規(guī)則炬称,再去 A 中心訪問一次(這就是所謂的二次讀取肺素,第一次讀取本地,本地失敗后第二次讀取對端)戒劫,這樣就能夠解決異常情況下同步延遲的問題。

(3) 存儲系統(tǒng)同步方式

對于密碼數(shù)據(jù)禁悠,由于用戶改密碼頻率較低,而且用戶不可能在 1 秒內(nèi)連續(xù)改多次密碼,所以通過數(shù)據(jù)庫的同步機制將數(shù)據(jù)復(fù)制到其他業(yè)務(wù)中心即可怀樟,用戶信息數(shù)據(jù)和密碼類似。

(4) 回源讀取方式

對于登錄的 session 數(shù)據(jù)盆佣,由于數(shù)據(jù)量很大往堡,我們可以不同步數(shù)據(jù);但當(dāng)用戶在 A 中心登錄后共耍,然后又在 B 中心登錄虑灰,B 中心拿到用戶上傳的 session id 后,根據(jù)路由判斷 session 屬于 A 中心征堪,直接去 A 中心請求 session 數(shù)據(jù)即可瘩缆;反之亦然,A 中心也可以到 B 中心去獲取 session 數(shù)據(jù)佃蚜。

(5) 重新生成數(shù)據(jù)方式

對于“回源讀取”場景庸娱,如果異常情況下,A 中心宕機了谐算,B 中心請求 session 數(shù)據(jù)失敗熟尉,此時就只能登錄失敗,讓用戶重新在 B 中心登錄洲脂,生成新的 session 數(shù)據(jù)斤儿。

注意:以上方案僅僅是示意,實際的設(shè)計方案要比這個復(fù)雜一些恐锦,還有很多細(xì)節(jié)要考慮往果。

綜合上述的各種措施,最后“用戶子系統(tǒng)”同步方式整體如下:

技巧 4:只保證絕大部分用戶的異地多活

某些場景下我們無法保證 100% 的業(yè)務(wù)可用性一铅,總是會有一定的損失陕贮。例如,密碼不同步導(dǎo)致無法登錄潘飘、用戶信息不同步導(dǎo)致用戶看到舊的信息等肮之,這個問題怎么解決呢?

異地多活也無法保證 100% 的業(yè)務(wù)可用卜录,這是由物理規(guī)律決定的戈擒,光速和網(wǎng)絡(luò)的傳播速度、硬盤的讀寫速度艰毒、極端異常情況的不可控等筐高,都是無法 100% 解決的。所以針對這個思維誤區(qū),我的答案是“忍”凯傲!否則本來想為了保證最后的 0.01% 的用戶的可用性犬辰,做一個完美方案,結(jié)果卻發(fā)現(xiàn) 99.99% 的用戶都保證不了了冰单。

對于某些實時強一致性的業(yè)務(wù)幌缝,實際上受影響的用戶會更多,甚至可能達(dá)到 1/3 的用戶诫欠。以銀行轉(zhuǎn)賬這個業(yè)務(wù)為例涵卵,假設(shè)小明在北京 XX 銀行開了賬號,如果小明要轉(zhuǎn)賬荒叼,一定要北京的銀行業(yè)務(wù)中心才可用轿偎,否則就不允許小明自己轉(zhuǎn)賬。如果不這樣的話被廓,假設(shè)在北京和上海兩個業(yè)務(wù)中心實現(xiàn)了實時轉(zhuǎn)賬的異地多活坏晦,某些異常情況下就可能出現(xiàn)小明只有 1 萬元存款,他在北京轉(zhuǎn)給了張三 1 萬元嫁乘,然后又到上海轉(zhuǎn)給了李四 1 萬元昆婿,兩次轉(zhuǎn)賬都成功了。這種漏洞如果被人利用蜓斧,后果不堪設(shè)想仓蛆。

當(dāng)然,針對銀行轉(zhuǎn)賬這個業(yè)務(wù)挎春,雖然無法做到“實時轉(zhuǎn)賬”的異地多活看疙,但可以通過特殊的業(yè)務(wù)手段讓轉(zhuǎn)賬業(yè)務(wù)也能實現(xiàn)異地多活。例如直奋,轉(zhuǎn)賬業(yè)務(wù)除了“實時轉(zhuǎn)賬”外能庆,還提供“轉(zhuǎn)賬申請”業(yè)務(wù),即小明在上海業(yè)務(wù)中心提交轉(zhuǎn)賬請求脚线,但上海的業(yè)務(wù)中心并不立即轉(zhuǎn)賬相味,而是記錄這個轉(zhuǎn)賬請求,然后后臺異步發(fā)起真正的轉(zhuǎn)賬操作殉挽,如果此時北京業(yè)務(wù)中心不可用,轉(zhuǎn)賬請求就可以繼續(xù)等待重試拓巧;假設(shè)等待 2 個小時后北京業(yè)務(wù)中心恢復(fù)了斯碌,此時上海業(yè)務(wù)中心去請求轉(zhuǎn)賬,發(fā)現(xiàn)余額不夠肛度,這個轉(zhuǎn)賬請求就失敗了傻唾。小明再登錄上來就會看到轉(zhuǎn)賬申請失敗,原因是“余額不足”。

不過需要注意的是“轉(zhuǎn)賬申請”的這種方式雖然有助于實現(xiàn)異地多活冠骄,但其實還是犧牲了用戶體驗的伪煤,對于小明來說,本來一次操作的事情凛辣,需要分為兩次:一次提交轉(zhuǎn)賬申請抱既,另外一次是要確認(rèn)是否轉(zhuǎn)賬成功。

雖然我們無法做到 100% 可用性扁誓,但并不意味著我們什么都不能做防泵,為了讓用戶心里更好受一些,我們可以采取一些措施進(jìn)行安撫或者補償蝗敢,例如:

掛公告

說明現(xiàn)在有問題和基本的問題原因捷泞,如果不明確原因或者不方便說出原因,可以發(fā)布“技術(shù)哥哥正在緊急處理”這類比較輕松和有趣的公告寿谴。

事后對用戶進(jìn)行補償

例如锁右,送一些業(yè)務(wù)上可用的代金券、小禮包等讶泰,減少用戶的抱怨咏瑟。

補充體驗

對于為了做異地多活而帶來的體驗損失,可以想一些方法減少或者規(guī)避峻厚。以“轉(zhuǎn)賬申請”為例响蕴,為了讓用戶不用確認(rèn)轉(zhuǎn)賬申請是否成功,我們可以在轉(zhuǎn)賬成功或者失敗后直接給用戶發(fā)個短信惠桃,告訴他轉(zhuǎn)賬結(jié)果浦夷,這樣用戶就不用時不時地登錄系統(tǒng)來確認(rèn)轉(zhuǎn)賬是否成功了。

核心思想

異地多活設(shè)計的理念可以總結(jié)為一句話:采用多種手段辜王,保證絕大部分用戶的核心業(yè)務(wù)異地多活劈狐!

小結(jié)

異地多活的 4 大技巧需要結(jié)合業(yè)務(wù)進(jìn)行分析取舍,這樣沒法通用呐馆,如果底層存儲采用 OceanBase 這種分布式強一致性的數(shù)據(jù)存儲系統(tǒng)肥缔,是否就可以做到和業(yè)務(wù)無關(guān)的異地多活?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汹来,一起剝皮案震驚了整個濱河市续膳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌收班,老刑警劉巖坟岔,帶你破解...
    沈念sama閱讀 211,423評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異摔桦,居然都是意外死亡社付,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸥咖,“玉大人燕鸽,你說我怎么就攤上這事√淅保” “怎么了啊研?”我有些...
    開封第一講書人閱讀 157,019評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熙兔。 經(jīng)常有香客問我悲伶,道長,這世上最難降的妖魔是什么住涉? 我笑而不...
    開封第一講書人閱讀 56,443評論 1 283
  • 正文 為了忘掉前任麸锉,我火速辦了婚禮,結(jié)果婚禮上舆声,老公的妹妹穿的比我還像新娘花沉。我一直安慰自己,他們只是感情好媳握,可當(dāng)我...
    茶點故事閱讀 65,535評論 6 385
  • 文/花漫 我一把揭開白布碱屁。 她就那樣靜靜地躺著,像睡著了一般蛾找。 火紅的嫁衣襯著肌膚如雪娩脾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,798評論 1 290
  • 那天打毛,我揣著相機與錄音柿赊,去河邊找鬼。 笑死幻枉,一個胖子當(dāng)著我的面吹牛碰声,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播熬甫,決...
    沈念sama閱讀 38,941評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼胰挑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了椿肩?” 一聲冷哼從身側(cè)響起瞻颂,我...
    開封第一講書人閱讀 37,704評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎郑象,沒想到半個月后蘸朋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,152評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡扣唱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,494評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片噪沙。...
    茶點故事閱讀 38,629評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡炼彪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出正歼,到底是詐尸還是另有隱情辐马,我是刑警寧澤,帶...
    沈念sama閱讀 34,295評論 4 329
  • 正文 年R本政府宣布局义,位于F島的核電站喜爷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏萄唇。R本人自食惡果不足惜檩帐,卻給世界環(huán)境...
    茶點故事閱讀 39,901評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望另萤。 院中可真熱鬧湃密,春花似錦、人聲如沸四敞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忿危。三九已至达箍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铺厨,已是汗流浹背缎玫。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留努释,地道東北人碘梢。 一個月前我還...
    沈念sama閱讀 46,333評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像伐蒂,于是被迫代替她去往敵國和親煞躬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,499評論 2 348

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