https://help.aliyun.com/knowledge_detail/72721.html
行業背景
異地多活指分布在異地的多個站點同時對外提供服務的業務場景。異地多活是高可用架構設計的一種,與傳統的災備設計的最主要區別在於“多活”,即所有站點都是同時在對外提供服務的。
以一個簡單的業務單元的IT系統為例,整個IT系統的異地多活方案如下圖所示。
整個方案將各站點分為:分流量層、應用層和數據層。
本文聚焦數據層的異地多活解決方案。目前針對數據層設計異地多活解決方案時,需遵循以下幾個原則:
-
單元封閉:
應用要走向異地,首先要面對的便是物理距離帶來的延時。如果某個應用請求需要在異地多個單元對同一行記錄進行修改,為滿足異地單元間數據庫數據的一致性和完整性,我們需要付出高昂的時間成本。此外,如果某個應用請求需要多次訪問異地單元,且各單元間服務再被服務調用,那物理延時將無法預估。因此,數據庫異地多活的問題轉移到了如何避免跨單元的問題,即要做到單元內數據讀寫封閉,不能出現不同單元對同一行數據進行修改,所以我們需要找到一個維度去划分單元,避免數據寫沖突。
-
數據拆分:
選擇什么維度來解決單點寫的問題,要從業務本身入手去分析。例如電商的業務,最重要的流程即下單交易流程,從下單業務對數據划分單元時,改造成本最低、用戶體驗相對好的便是買家維度,即通過買家ID進行下單業務拆分,如下圖所示。
買家的下單操作在買家所在的本單元內即可完成讀寫封閉。按照上述示例划分業務,就意味着非買家維度的就需要做一定的妥協。對於非買家維度的操作,比如賣家操作(例如商品數據的修改)就可能會跨單元,對於買家與賣家數據讀一致的問題, 可以接受“最終一致”的就通過讀寫分離的方案, 不能接受“最終一致”的則需要跨單元訪問。
-
數據同步:
將業務划分多個單元以后,對於數據庫來說,面臨的最大挑戰就是數據同步,因為對於單元封閉的買家維度的數據(unit類型)需要把單元的數據全部同步到中心,對於讀寫分離類型的(copy類型),我們要把中心的數據同步到單元。
原生的數據庫復制無法滿足單元化復雜的同步需求(例如,只同步部分的數據、庫表的過濾、雙向循環、API服務化等定制化的需求 ),在普通業務邏輯場景下,DTS的同步性能更高效、更穩定,DTS也成為多活的基礎設施。具體的數據同步如下圖所示。
-
緩存失效
實現數據層異地多活后,業務希望實時獲取數據庫變更消息,單元的緩存失效實現可通過數據訂閱實現。通過數據訂閱提供的消費 SDK,業務層可訂閱 RDS 增量數據然后觸發更新單元的緩存,通過這樣的方式,應用無需實現緩存更新邏輯,架構更加簡單。
核心產品
阿里雲數據庫異地多活解決方案使用以下阿里雲核心產品,按照架構設計原則提供數據層多活解決方案。
DRDS
按照之前說的業務數據拆分的維度,阿里雲DRDS有兩種集群分別支持買家維度與賣家維度:
- unit 模式的DRDS集群:多地用戶分別在本地域讀寫本地域的數據,且本地域的數據會和中心數據做雙向同步。
- copy 模式的DRDS集群:此集群數據在中心數據庫寫,完成后全量同步到各個單元。需要注意的是,DRDS層面需要增加對數據寫入路由的判斷:如果是跨單元的寫,則判斷為非法操作並拋出異常,確保數據不會跨單元寫。
更多DRDS的介紹請參考分布式關系型數據庫DRDS一文。
DTS
數據復制是數據庫多活設計關鍵的一環,其中數據復制的正確性是第一位,同時效率也很關鍵。阿里雲DTS支持多重的check ,避免循環復制(用事務表,或者thread_id方案), 采用並行復制(串行的分發,沖突檢測,並行的執行)、大事務切割來保證最終一致性。
數據校驗也是關鍵的一環,阿里雲DTS 通過全量校驗工具(TCP)和增量校驗工具(AMG)來保證實時/定時檢查中心和單元的數據准確性,確保線上數據的萬無一失。
更多的數據傳輸相關內容請參考數據傳輸服務一文。
HDM
阿里雲HDM提供了DRDS集群的搭建、同步鏈路的創建、多活的數據庫監控、數據校驗、集群擴縮容以及自動化的容災等服務,都可通過HDM完成,通過HDM實現了異地多活場景下數據庫的管理。
更多的數據管理請參考混合雲數據庫管理一文。
典型應用場景
兩地容災切換方案
容災是異地多活中最核心的一環, 以兩個城市異地多活部署架構圖為例:
- 在兩個城市(城市1位於華南1地域、城市2位於華東1地域)均部署一套完整的業務系統。
- 下單業務按照“user_id”% 100 進行分片,在正常情況下:
- [00~49]分片所有的讀寫都在城市1的數據庫實例主庫。
- [50~99]分片所有的讀寫都在城市2的數據庫實例主庫。
- “城市1的數據庫實例主庫”和 “城市2的數據庫實例主庫”建立DTS雙向復制
當出現異常時,需要進行容災切換。可能出現的場景有以下4種:
序號 | 異常情況 | 操作 |
---|---|---|
1 | 城市1數據庫主庫故障 | 1、數據庫引擎完成主備切換;2、DTS自動切換到城市1新主庫讀取新的增量更新,然后同步到城市2的數據庫實例 |
2 | 城市1所有APP Server故障 | 有兩種處理方案:方案1:數據庫層無任何操作,APP Server切換到城市2,並跨城市讀寫城市1的數據庫;方案2:APP Server和數據庫都切換到城市2 |
3 | 城市1所有數據庫故障 | 有兩種處理方案:方案1:數據庫層切換到城市2,APP Server跨城市讀寫城市2的數據庫;方案2:APP Server和數據庫都切換到城市2 |
4 | 城市1整體故障(包括所有APP Server +數據庫等) | 1、城市1的全部數庫流量切換到城市2;2、城市1數據庫到城市2數據庫的DTS數據同步鏈路停止3、在城市2中,DTS啟動,保存[00-49]分片的變更4、城市1故障恢復后,[00-49]的增量數據同步到城市1的數據庫實例。5、同步結束后,將[00-49]的數據庫流量從城市2切回到城市1啟動[00-49]分片從城市1到城市2的DTS同步 |
將第2種、第3種異常情況,全部采用第2種方案進行處理,那么不管是所有的APP Server異常、所有的數據庫異常、整個城市異常,就直接按照城市級容災方案處理,直接將APP Server、數據庫切換到到另一個城市。
多城異地多活
多城市異地多活模式指的是3個或者3個以上城市間部署異地多活。該模式下存在中心節點和單元節點:
- 中心節點:指單元節點的增量數據都需要實時的同步到中心節點,同時中心節點將所有分片的增量數據同步到其他單元節點。
- 單元節點:即對應分片讀寫的節點,該節點需要將該分片的增量同步到中心節點,並且接收來自於中心節點的其他分片的增量數據。
下圖是3城市異地多活架構圖,其中華東1就是中心節點,華南1和華北1是單元節點
單元城市級故障
當單元城市出現故障,業務需要切換時,以華南1城市級故障為例:
- 容災
- 華南1(單元)的全部數庫流量切換到華東1(中心);
- 華南1(單元)數據庫到華東1(中心)數據庫的DTS數據同步鏈路停止,並記錄同步位點
- 分片[00-29]的讀寫切換到華東1(中心)
- 恢復
- 重建華南1(單元);
- 華南1(單元)數據遷移和同步完成后,停止分片[00-29]在華東1(中心)的讀寫;
- 停止華東1(中心)到華南1(單元)分片[00-29]的數據同步;
- 創建華南1(單元)到華東1(中心)的數據同步;
- 將分片[00-29]的讀寫切換到華南1(單元);
- 華南1(單元)的數據庫主庫開啟寫入;
- 檢查;
中心城市級故障
當中心城市出現故障,業務需要切換時,以華東1城市級故障為例:
- 容災
- 華東1(中心)的全部數庫流量切換到華南1(單元);
- 華東1(中心)數據庫到華南1(單元)數據庫的DTS數據同步鏈路停止;
- 華東1(中心)數據庫到華北1(單元)數據庫的DTS數據同步鏈路停止;
- 華南1(單元)數據庫到華東1(中心)數據庫的DTS數據同步鏈路停止;
- 華北1(單元)數據庫到華東1(中心)數據庫的DTS數據同步鏈路停止;
- 新增華南1(單元)數據庫到華北1(單元)分片[30~99]的DTS數據同步鏈路;
- 恢復
- 重建華東1(中心);
- 華東1(中心)數據遷移和同步完成后,停止分片[30-69]在華南1(單元)的讀寫;
- 停止華東1(中心)到華南1(單元)分片[00-29]的數據同步;
- 創建華東1(中心)到華南1(單元)的數據同步;
- 創建華東1(中心)到華北1(單元)的數據同步;
- 將分片[00-29]的讀寫切換到華南1(單元);
- 華南1(單元)的數據庫主庫開啟寫入;
- 檢查;