1. 程式人生 > >分散式多活的異地多活設計四大誤區

分散式多活的異地多活設計四大誤區

其實大部分問題我們之前也遇到過,這些問題當時也困擾著我們,後來我們經過討論和思考,發現其實很多時候我們困擾的主要原因是過於“追求完美的異地多活方案”,這樣導致“異地多活”設計中出現很多了的思維誤區,而如果不意識到這些思維誤區,就會陷入死衚衕,導致無法實現真正的“異地多活”方案。

接下來我將總結常見的思維誤區,看看你踩中了哪個坑?

1所有業務異地多活

“異地多活”是為了保證業務的高可用,但很多朋友在考慮這個“業務”的時候,會不自覺的陷入一個思維誤區:我要保證所有業務的“異地多活”!

比如說假設我們需要做一個“使用者子系統”,這個子系統負責“註冊”、“登入”、“使用者資訊”三個業務。為了支援海量使用者,我們設計了一個“使用者分割槽”的架構,即:正常情況下使用者屬於某個主分割槽,每個分割槽都有其它資料的備份,使用者用郵箱或者手機號註冊,路由層拿到郵箱或者手機號後,通過hash計算屬於哪個中心,然後請求對應的業務中心。基本的架構如下:

考慮這樣一個系統,如果3個業務要同時實現異地多活,我們會發現如下一些難以解決的問題:

註冊

A中心註冊了使用者,資料還未同步到B中心,此時A中心宕機,為了支援註冊業務多活,那我們可以挑選B中心讓使用者去重新註冊。看起來很容易就支援多活了,但仔細思考一下會發現這樣做會有問題:一個手機號只能註冊一個賬號,A中心的資料沒有同步過來,B中心無法判斷這個手機號是否重複,如果B中心讓使用者註冊,後來A中心恢復了,發現數據有衝突,怎麼解決?

實際上是無法解決的,因為註冊賬號不能說挑選最後一個生效;而如果B中心不支援本來屬於A中心的業務進行註冊,註冊業務的雙活又成了空談。

有的朋友可能會說:那我修改業務規則,允許一個手機號註冊多個賬號不就可以了麼?

這樣做是不可行的,類似一個手機號只能註冊一個賬號這種規則,是核心業務規則,修改核心業務規則的代價非常大,幾乎所有的業務都要重新設計,為了架構設計去改變業務規則,而且是這麼核心的業務規則是得不償失的。

使用者資訊

使用者資訊的修改和註冊有類似的問題,即:A、B兩個中心在異常的情況下都修改了使用者資訊,如何處理衝突?

由於使用者資訊並沒有賬號那麼關鍵,一種簡單的處理方式是按照時間合併,即:最後修改的生效。業務邏輯上沒問題,但實際操作也有一個很關鍵的坑:怎麼保證多箇中心所有機器時間絕對一致?在異地多中心的網路下,這個是無法保證的,即使有時間同步也無法完全保證,只要兩個中心的時間誤差超過1s,資料就可能出現混亂,即:先修改的反而生效。

還有一種方式是生成全域性唯一遞增ID,這個方案的成本很高,因為這個全域性唯一遞增ID的系統本身又要考慮異地多活,同樣涉及資料一致性和衝突的問題。

綜合上面的簡單分析,我們可以發現,如果“註冊”“登入”、“使用者資訊”全部都要支援異地多活的話,實際上是挺難的,有的問題甚至是無解的。那這種情況下我們應該如何考慮“異地多活”的方案設計呢?答案其實很簡單:優先實現核心業務的異地多活方案!

對於我們的這個模擬案例來說,“登入”才是最核心的業務,“註冊”和“使用者資訊”雖然也是主要業務,但並不一定要實現異地多活。主要原因在於業務影響。對於一個日活1000萬的業務來說,每天註冊使用者可能是幾萬,修改使用者資訊的可能還不到1萬,但登入使用者是1000萬,很明顯我們應該保證登入的異地多活。

對於新使用者來說,註冊不了影響並不很明顯,因為他還沒有真正開始業務;使用者資訊修改也類似,使用者暫時修改不了使用者資訊,對於其業務不會有很大影響,而如果有幾百萬使用者登入不了,就相當於幾百萬使用者無法使用業務,對業務的影響就非常大了:公司的客服熱線很快就被打爆了,微博微信上到處都在傳業務宕機,論壇裡面到處是在罵孃的使用者,那就是網際網路大事件了!

而登入實現“異地多活”恰恰是最簡單的,因為每個中心都有所有使用者的賬號和密碼資訊,使用者在哪個中心都可以登入。使用者在A中心登入,A中心宕機後,使用者到B中心重新登入即可。

有的朋友可能會問,如果某個使用者在A中心修改了密碼,此時資料還沒有同步到B中心,使用者到B中心登入是無法登入的,這個怎麼處理?這個問題其實就涉及另外一個思維誤區了,我們稍後再談。

2實時一致性

異地多活本質上是通過異地的資料冗餘,來保證在極端異常的情況下業務也能夠正常提供給使用者,因此資料同步是異地多活設計方案的核心,但我們大部分人在考慮資料同步方案的時候,也會不知不覺的陷入完美主義誤區:我要所有資料都實時同步!

資料冗餘就要將資料從A地同步到B地,從業務的角度來看是越快越好,最好和本地機房一樣的速度最好,但讓人頭疼的問題正在這裡:異地多活理論上就不可能很快,因為這是物理定律決定的,即:光速真空傳播是每秒30萬公里,在光纖中傳輸的速度大約是每秒20萬公里,再加上傳輸中的各種網路裝置的處理,實際還遠遠達不到光速的速度。

除了距離上的限制外,中間傳輸各種不可控的因素也非常多,例如挖掘機把光纖挖斷,中美海底電纜被拖船扯斷、骨幹網故障等,這些故障是第三方維護,我們根本無能為力也無法預知。例如廣州機房到北京機房,正常情況下RTT大約是50ms左右,遇到網路波動之類的情況,RTT可能飆升到500ms甚至1s,更不用說經常發生的線路丟包問題,那延遲可能就是幾秒幾十秒了。

因此異地多活方案面臨一個無法徹底解決的矛盾:業務上要求資料快速同步,物理上正好做不到資料快速同步,因此所有資料都實時同步,實際上是一個無法達到的目標。

既然是無法徹底解決的矛盾,那就只能想辦法儘量減少影響。有幾種方法可以參考:

  1. 儘量減少異地多活機房的距離,搭建高速網路;

  2. 儘量減少資料同步;

  3. 保證最終一致性,不保證實時一致性;

減少距離:同城多中心

為了減少兩個業務中心的距離,選擇在同一個城市不同的區搭建機房,機房間通過高速網路連通,例如在北京的海定區和通州區各搭建一個機房,兩個機房間採用高速光纖網路連通,能夠達到近似在一個機房的效能。

這個方案的優勢在於對業務幾乎沒有影響,業務可以無縫的切換到同城多中心方案;缺點就是無法應對例如新奧爾良全城被水淹,或者2003美加大停電這種極端情況。所以即使採用這種方案,也還必須有一個其它城市的業務中心作為備份,最終的方案同樣還是要考慮遠距離的資料傳輸問題。

減少資料同步

另外一種方式就是減少需要同步的資料。簡單來說就是不重要的資料不要同步,同步後沒用的資料不同步。

以前面的“使用者子系統”為例,使用者登入所產生的token或者session資訊,資料量很大,但其實並不需要同步到其它業務中心,因為這些資料丟失後重新登入就可以了。

有的朋友會問:這些資料丟失後要求使用者重新登入,影響使用者體驗的呀!

確實如此,畢竟需要使用者重新輸入賬戶和密碼資訊,或者至少要彈出登入介面讓使用者點選一次,但相比為了同步所有資料帶來的代價,這個影響完全可以接受,其實這個問題也涉及了一個異地多活設計的典型思維誤區,後面我們會詳細講到。

保證最終一致性

第三種方式就是業務不依賴資料同步的實時性,只要資料最終能一致即可。例如:A機房註冊了一個使用者,業務上不要求能夠在50ms內就同步到所有機房,正常情況下要求5分鐘同步到所有機房即可,異常情況下甚至可以允許1小時或者1天后能夠一致。

最終一致性在具體實現的時候,還需要根據不同的資料特徵,進行差異化的處理,以滿足業務需要。例如對“賬號”資訊來說,如果在A機房新註冊的使用者5分鐘內正好跑到B機房了,此時B機房還沒有這個使用者的資訊,為了保證業務的正確,B機房就需要根據路由規則到A機房請求資料(這種處理方式其實就是後面講的“二次讀取”)。

而對“使用者資訊”來說,5分鐘後同步也沒有問題,也不需要採取其它措施來彌補,但還是會影響使用者體驗,即使用者看到了舊的使用者資訊,這個問題怎麼解決呢?這個問題實際上也涉及到了一個思維誤區,在最後我們統一分析。

3只使用儲存系統的同步功能

資料同步是異地多活方案設計的核心,幸運的是基本上儲存系統本身都會有同步的功能,例如MySQL的主備複製、Redis的Cluster功能、elasticsearch的叢集功能。這些系統本身的同步功能已經比較強大,能夠直接拿來就用,但這也無形中將我們引入了一個思維誤區:只使用儲存系統的同步功能!

既然說儲存系統本身就有同步功能,而且同步功能還很強大,為何說只使用儲存系統是一個思維誤區呢?因為雖然絕大部分場景下,儲存系統本身的同步功能基本上也夠用了,但在某些比較極端的情況下,儲存系統本身的同步功能可能難以滿足業務需求。

以MySQL為例,MySQL5.1版本的複製是單執行緒的複製,在網路抖動或者大量資料同步的時候,經常發生延遲較長的問題,短則延遲十幾秒,長則可能達到十幾分鍾。而且即使我們通過監控的手段知道了MySQL同步時延較長,也難以採取什麼措施,只能乾等。

Redis又是另外一個問題,Redis 3.0之前沒有Cluster功能,只有主從複製功能,而為了設計上的簡單,Redis主從複製有一個比較大的隱患:從機宕機或者和主機斷開連線都需要重新連線主機,重新連線主機都會觸發全量的主從複製,這時候主機會生成記憶體快照,主機依然可以對外提供服務,但是作為讀的從機,就無法提供對外服務了,如果資料量大,恢復的時間會相當的長。

綜合上述的案例可以看出,儲存系統本身自帶的同步功能,在某些場景下是無法滿足我們業務需要的。尤其是異地多機房這種部署,各種各樣的異常都可能出現,當我們只考慮儲存系統本身的同步功能時,就會發現無法做到真正的異地多活。

解決的方案就是拓開思路,避免只使用儲存系統的同步功能,可以將多種手段配合儲存系統的同步來使用,甚至可以不採用儲存系統的同步方案,改用自己的同步方案。

例如,還是以前面的“使用者子系統”為例,我們可以採用如下幾種方式同步資料:

  1. 訊息佇列方式:對於賬號資料,由於賬號只會建立,不會修改和刪除(假設我們不提供刪除功能),我們可以將賬號資料通過訊息佇列同步到其它業務中心。

  2. 二次讀取方式:某些情況下可能出現訊息佇列同步也延遲了,使用者在A中心註冊,然後訪問B中心的業務,此時B中心本地拿不到使用者的賬號資料。為了解決這個問題,B中心在讀取本地資料失敗的時候,可以根據路由規則,再去A中心訪問一次(這就是所謂的二次讀取,第一次讀取本地,本地失敗後第二次讀取對端),這樣就能夠解決異常情況下同步延遲的問題。

  3. 儲存系統同步方式:對於密碼資料,由於使用者改密碼頻率較低,而且使用者不可能在1s內連續改多次密碼,所以通過資料庫的同步機制將資料複製到其它業務中心即可,使用者資訊資料和密碼類似。

  4. 回源讀取方式:對於登入的session資料,由於資料量很大,我們可以不同步資料;但當用戶在A中心登入後,然後又在B中心登入,B中心拿到使用者上傳的session id後,根據路由判斷session屬於A中心,直接去A中心請求session資料即可,反之亦然,A中心也可以到B中心去拿取session資料。

  5. 重新生成資料方式:對於第4中場景,如果異常情況下,A中心宕機了,B中心請求session資料失敗,此時就只能登入失敗,讓使用者重新在B中心登入,生成新的session資料。

(注意:以上方案僅僅是示意,實際的設計方案要比這個複雜一些,還有很多細節要考慮)

綜合上述的各種措施,最後我們的“使用者子系統”同步方式整體如下:


4100%可用性

前面我們在給出每個思維誤區對應的解決方案的時候,其實都遺留了一些小尾巴:某些場景下我們無法保證100%的業務可用性,總是會有一定的損失。例如密碼不同步導致無法登入、使用者資訊不同步導致使用者看到舊的使用者資訊等等,這個問題怎麼解決?

其實這個問題涉及異地多活設計方案中一個典型的思維誤區:我要保證業務100%可用!但極端情況下就是會丟一部分資料,就是會有一部分資料不能同步,怎麼辦呢,有沒有什麼巧妙和神通的辦法能做到?

很遺憾,答案是沒有!異地多活也無法保證100%的業務可用,這是由物理規律決定的,光速和網路的傳播速度、硬碟的讀寫速度、極端異常情況的不可控等,都是無法100%解決的。所以針對這個思維誤區,我的答案是“忍”!也就是說我們要忍受這一小部分使用者或者業務上的損失,否則本來想為了保證最後的0.01%的使用者的可用性,做個完美方案,結果卻發現99.99%的使用者都保證不了了。

對於某些實時強一致性的業務,實際上受影響的使用者會更多,甚至可能達到1/3的使用者。以銀行轉賬這個業務為例,假設小明在北京XX銀行開了賬號,如果小明要轉賬,一定要北京的銀行業務中心是可用的,否則就不允許小明自己轉賬。

如果不這樣的話,假設在北京和上海兩個業務中心實現了實時轉賬的異地多活,某些異常情況下就可能出現小明只有1萬存款,他在北京轉給了張三1萬,然後又到上海轉給了李四1萬,兩次轉賬都成功了。這種漏洞如果被人利用,後果不堪設想。

當然,針對銀行轉賬這個業務,可以有很多特殊的業務手段來實現異地多活。例如分為“實時轉賬”和“轉賬申請”。

實時轉賬就是我們上述的案例,是無法做到“異地多活”的;但“轉賬申請”是可以做到“異地多活”的,即:小明在上海業務中心提交轉賬請求,但上海的業務中心並不立即轉賬,而是記錄這個轉賬請求,然後後臺非同步發起真正的轉賬操作,如果此時北京業務中心不可用,轉賬請求就可以繼續等待重試;假設等待2個小時後北京業務中心恢復了,此時上海業務中心去請求轉賬,發現餘額不夠,這個轉賬請求就失敗了。

小明再登入上來就會看到轉賬申請失敗,原因是“餘額不足”。不過需要注意的是“轉賬申請”的這種方式雖然有助於實現異地多活,但其實還是犧牲了使用者體驗的,對於小明來說,本來一次操作的事情,需要分為兩次:一次提交轉賬申請,另外一次要確認是否轉賬成功。

雖然我們無法做到100%可用性,但並不意味著我們什麼都不能做,為了讓使用者心裡更好受一些,我們可以採取一些措施進行安撫或者補償,例如:

  1. 掛公告:說明現在有問題和基本的問題原因,如果不明確原因或者不方便說出原因,可以說“技術哥哥正在緊急處理”比較輕鬆和有趣的公告。

  2. 事後對使用者進行補償:例如送一些業務上可用的代金券、小禮包等,降低使用者的抱怨。

  3. 補充體驗:對於為了做異地多活而帶來的體驗損失,可以想一些方法減少或者規避。以“轉賬申請”為例,為了讓使用者不用確認轉賬申請是否成功,我們可以在轉賬成功或者失敗後直接給使用者發個簡訊,告訴他轉賬結果,這樣使用者就不用不時的登入系統來確認轉賬是否成功了。

5一句話談“異地多活”

綜合前面的分析,異地多活設計的理念可以總結為一句話:採用多種手段,保證絕大部分使用者的核心業務異地多活!

相關推薦

分散式異地設計四大誤區

其實大部分問題我們之前也遇到過,這些問題當時也困擾著我們,後來我們經過討論和思考,發現其實很多時候我們困擾的主要原因是過於“追求完美的異地多活方案”,這樣導致“異地多活”設計中出現很多了的思維誤區,而如果不意識到這些思維誤區,就會陷入死衚衕,導致無法實現真正的“異地多活”

從github超24小時的故障看異地全域性設計的重要性

我們先來回顧一下github這次事故: 2018年10月21日,github 在更換網路裝置時,引發了美國東海岸網路中心和東海岸資料中心的網路連結發生了40秒的中斷,最終導致多個mysql的主叢集由Orchestrator 自動選舉切換到了美國西海岸資料中心對應的叢集,由此引發了資料不一致,直接導致了超過24

異地架構設計系列(一): Why and How

很多全球化的產品, 比如facebook、twitter, 它們的使用者遍佈世界各地。 工程師們往往會在全球設立多個數據中心(DC)供使用者訪問, 我們可以稱之為異地多活。在後續一段時間裡, 我會寫一系列的部落格,和大家一起探索異地多活架構。 這篇文章主要是討論

分散式系統技術難題--異地

什麼是異地多活? 為了保證系統能夠對機房級別的故障進行容錯,不會使系統不可用,這

不理解Zookeeper一致性原理,談何異地改造

還要 基於 cif 內存地址 很多 ren 為什麽 英文 比較 2017 年在餓了麽做異地多活建設之時,我的團隊承擔了 Zookeeper 的異地多活改造。 在此期間,我聽到了關於 Zookeeper 一致性的兩種不同說法: Zookeeper 是最終一致性的,由於多副本

專訪阿里巴巴畢玄:異地資料中心專案的來龍去脈

大資料時代,資料中心的異地容災變得非常重要。在去年雙十一之前,阿里巴巴上線了資料中心異地雙活專案。InfoQ就該專案採訪了阿里巴巴的林昊(花名畢玄)。 畢玄是阿里巴巴技術保障部的研究員,負責效能容量架構。資料中心異地多活專案就是他主導的。 InfoQ:首先請介紹一下資料中心異地多活這個專案。 畢玄:這個

專訪阿裏巴巴畢玄:異地數據中心項目的來龍去脈

期望 會有 做出 facebook 冗余 我會 設計 需要 功能 大數據時代,數據中心的異地容災變得非常重要。在去年雙十一之前,阿裏巴巴上線了數據中心異地雙活項目。InfoQ就該項目采訪了阿裏巴巴的林昊(花名畢玄)。 畢玄是阿裏巴巴技術保障部的研究員,負責性能容量架構。數據

螞蟻金服異地的微服務體系

螞蟻金服(當時還是支付寶)從 2013 年起就執行在單元化架構上,除了具備異地容災能力外,還能做到異地多活,可隨時在多城市、多資料中心調配流量。基於單元流量調配機制,可實現大規模叢集的藍綠髮布、灰度模擬環境,為充分驗證業務正確性、降低故障提供了基礎條件。相應地,微服務體系也必須具備單元內收斂、單元間可控路由等

資料庫-異地中心概念

資料庫-異地多活多中心概念 0x01 摘要 本文簡要談談我對異地多活多中心淺顯理解,以及互相產生的記錄不衝突的原因。 0x02 什麼是多活 多活就是指業務服務部署在N個機房,那麼可以容忍N-1個機房掛掉,還是能正常提供服務。 0x03 什麼是多中心 多中心指資料庫

阿里和微博的異地方案

總結: 多活基本思路: 每個中心都是活的,可以實時承擔流量,任何一點出問題,都可以直接切掉,由另外一點直接接管,非傳統的兩地三中心冷備方式。挑戰及解決方法: 服務延時。 讓操作全部在同一中心內完成,單元化 比如使用者進入以後,比如說在淘寶上看商品,瀏覽商品,搜尋、下單

如何基於OceanBase構建應用和資料庫的異地

如何基於OceanBase構建應用和資料庫的異地多活 前言 OceanBase是一個通用的分散式的關係型資料庫,有很多獨特的特點。比如資料庫的多租戶、高可用、極致彈性伸縮能力。如果把OceanBase當作單庫使用,就沒有把OceanBase的分散式優勢發揮到極致。 本文主要分享一個

異地場景下的資料同步之道

田守枝的技術部落格

北漂程式設計師:年薪30萬,卻得如此狼狽

程式設計師應該算是很光鮮的行業了,也是其他職業人士所羨慕和嚮往的。然而生活就像圍城一樣,不在其中不知其滋味,特別是在北上廣深一帶打拼的程式設計師,其生活狀況可能沒有我們想象的那麼光鮮。有在北京打拼的程式設計師就上網感嘆了自己目前的生活境況,稱自己年薪30多萬,卻活得像乞丐一樣,省吃儉用,鞋子不敢買1

攜程:上萬坐席呼叫中心異地架構及系統設計

作者簡介: 沈強 攜程旅行網  通訊技術中心高階經理 擁有十幾年的呼叫中心繫統建設和運維管理經驗,經歷了攜程呼叫中心繫統架構的多次轉型設計,使之從單一系統逐步演進到異地冗災、異地雙活,從單品牌到多平臺的融合架構設計。目前負責攜程上萬座席呼叫中心的產品管理和架構設計工作。 序言 之前,我先拜讀了《G

北漂程式設計師的辛酸:年薪30萬,卻得像乞丐一樣

程式設計師應該算是很光鮮的行業了,也是其他職業人士所羨慕和嚮往的。然而生活就像圍城一樣,不在其中不知其滋味,特別是在北上廣深一帶打拼的程式設計師,其生活狀況可能沒有我們想象的那麼光鮮。有在北京打拼的程式設計師就上網感嘆了自己目前的生活境況,稱自己年薪30多萬,卻活得像乞丐一樣

系統電腦,界面,硬件的設計

界面 nbsp 配置 置1 硬件 電腦 最終 硬件配置 設計 電腦------硬件配置; 界面------硬件配置; 最終實現電腦上硬件界面的靈活配置; 實現方式(電腦------硬件): 電腦------硬件1------配置1

我的線程—線程與設計模式閱讀筆記

圖解java多線程與設計模式 多線程 設計模式 java多線程與設計模式1.Producer-Consumer模式 我來做,你來用 命名生產消費者模式. 生產者和消費者只有一個成為Pipe模式如何解決兩者之間處理速度差異的問題? data

面向對象之態,態性,反射,以及基於反射的可拔插設計

it is sat pass ict method func let HA strac 多態 什麽多態? 多態指的是一類事物有多種形態,比如 動物有多種形態:人,狗,豬 >>例如 import abc #創建抽象類 導入abc class Anima

室內設計很有前途嗎?為什麽那麽人轉行學室內設計

了解 適合 family 正在 再看 發展 專業 隨著 sns 為什麽那麽多人轉行學室內設計呢?室內設計很有前途嗎?零基礎能不能學會?最近很多人問小編這樣的問題,想小編為大家解答一下。 所以小編專門花時間去了解了室內設計的發展前景,接下來就來給大家解答一下問題,不過在解

基於極數雲舟Arkgate跨雲資料庫異地實戰

隨著O2O消費深入人心,我們公司的業務也迅速發展,目前已經服務了全國大部分城市裡面的近2000萬個家庭,家庭服務已經成為解決社會勞動力的一個重要渠道,也是方便千家萬戶的一項利國利民的大好事。在不斷髮展的過程中,公司對業務服務質量,以及資料安全,資料庫可用都非常重視,這是我們的核心資產。