微衆銀行數據庫架構編年史

轉眼間,已在微衆工作近七載。這期間,一直負責微衆銀行數據庫平臺的建設和運營。微衆銀行在成立之初,IT 基礎建設就沒有選擇傳統的 IOE 集中式架構路線,轉而選擇採用了基於單元化的分佈式架構。在這種大的背景下,微衆銀行的數據庫的架構演進,也是走出了一條不同尋常的路線。

本文將以編年史的形式,和大家分享一下微衆數據庫架構的演進過程,既是對自身工作的一個總結,也希望可以爲同行業帶來一些價值和參考。

(一)

2014~2016,兩地三中心時代

在微衆銀行 IT 建設的第一階段,基於成本和效率的考慮,IDC 的建設採用了兩地三中心的架構(簡稱 IDC 1.0 架構)。兩個同城數據中心作爲生產中心,一個異地容災中心作爲災備。

IDC 1.0 架構

在 IDC 1.0 架構的基礎上,我行設計了基於 DCN 的單元化分佈式架構(DCN,即 Data Center Node 的簡稱)。一個 DCN,可以理解爲一個從應用層到中間件層,到數據庫層的完整的自包含的邏輯單位。

不同的業務產品被歸類到不同類型的產品 DCN;同一個業務產品,再通過一定的計算規則(比如客戶號的 hash),分配到每一個小的 DCN 產品單元中;每一個 DCN 單元會有一個核定的用戶承載量;當一個 DCN 的用戶承載量用滿時,便可以發起新的 DCN 單元擴容,以此來實現水平擴展的特性。

在實際兩地三中心的部署架構中,每個 DCN 都會有同城主 DCN、同城備 DCN、異地備 DCN 三種角色,即每個 DCN 也都實現了兩地三中心的架構。同時,不同的 DCN 主分片,在同城的兩個 IDC 之間是交叉部署的,以此可以實現 DCN 單元粒度上的同城雙活。

DCN 主備交叉部署架構

那麼,基於這種 IDC 和 DCN 架構的前提下,數據庫如何選型?架構如何設計呢?

客觀的講,在 2014 的時候,滿足金融級要求的國產分佈式數據庫產品並不多,可選範圍也非常有限。經過充分的調研也評估,微衆最終選擇了騰訊的數據庫產品 TDSQL,作爲 DCN 架構下的核心數據庫。

TDSQL 有以下幾個特性吸引了我們:

  1. TDSQL 基於 MySQL 內核做了定製優化,實現了主備強一致的數據同步,同時還保證了性能上的極小損失。數據的一致性保證是金融場景的最基本要求。

  2. TDSQL 全兼容 MySQL 協議,通用性強,適用面廣大,遷移難度低。

  3. TDSQL 已在騰訊內部的計費場景中大量實踐應用,並取得了較好的效果。

基於 TDSQL,我們設計瞭如下的數據庫部署架構:

兩地三中心的數據庫部署架構

可以看到,TDSQL 的部署架構也遵循了兩地三中心的原則,分爲同城主數據庫 SET,同城備數據庫 SET 和異地備數據庫 SET。同城主數據庫 SET 和同城備數據庫 SET 由三個數據副本構成(一主二備),異地備數據庫 SET 由兩個數據副本構成(一主一備)。

SET 內部基於 TDSQL 的主備強一致數據同步功能,可以實現數據的高可靠和零丟失。

(二)

2016~2018,同城多活架構改造

IDC 1.0 時代的架構基本滿足了我行的業務發展需求,但還是存在以下幾個問題:

  1. 同城雙中心之間的數據庫同步是準實時的,在極端場景下是有可能出現數據丟失的(同城 RPO 不爲 0)

  2. 只實現了 DCN 分片單元粒度的多活,還沒有實現真正意義上的應用跨同城數據中心多活;

  3. 在單個 DCN 或者 IDC 出現故障時,需要做人工的同城容災切換,耗時太久(RTO 約二小時)

  4. 同城有 6 份數據庫副本,資源成本較高。

既然有問題,那就得繼續優化架構。所以我們提出了第二階段的架構優化目標:

首先,我們在同城新增了一個數據中心,由同城的兩中心,變爲了同城三中心(IDC 2.0),這是實現同城應用多活架構的前提。

IDC 2.0 架構圖

基於 IDC2.0,我們設計了同城三中心多活方案,應用層和數據庫的架構都做了相應的調整。

同城多活架構

數據庫層面,由原來的雙中心主備 SET 的架構模式,調整爲單 SET 三副本跨三中心部署的模式,主節點可以進行讀寫,備節點只讀,通過 TDSQL 的數據強一致同步功能,保證三副本跨中心的數據一致性;通過 TDSQL 的高可用一致性秒級自動切換功能,保證了在數據庫主節點,甚至是一個數據中心宕機的情況,可以在秒級時間內,將數據庫主節點切換到另一個 IDC,繼續提供服務。

以上兩點,可以實現數據庫層面的同城跨 IDC 的 RPO=0,RTO 達到秒級。以此爲前提,應用層就可以實現真正的跨同城數據中心多活。也就是應用層可以在同城的三個數據中心內各部署一套對等的應用系統,接入業務流量,經過接入層轉發,最終到數據庫的主節點上(開啓讀寫分離的情況下,讀流量可以轉發到備節點上)。

細心的同學可能會發現,這個同城多活會帶來兩個跨數據中心流量的問題:

  1. 應用層到數據庫主節點之間會產生跨數據中心流量(當應用層和數據庫主節點不在同一個數據中心時)

  2. 數據庫的主備節點之間也會產生跨數據中心流量(TDSQL 主備強一致同步)

跨數據中心流量首先對數據中心間的網絡質量要求很高,同時也會帶來業務整體響應時間上的增加。

針對這些問題,我們在數據中心和網絡建設方面,確立了一些原則,比如儘量保證數據中心之間的距離在 20~50 公里之間;數據中心之間採用專線互聯,並且進行多路徑備份;數據中心進行萬兆改造等等。這些措施可以保證數據中心之間的網絡包延遲控制在 2ms 以內,並且提供較高網絡穩定性。

同時,在數據庫層面,TDSQL 也針對主備節點跨數據中心強同步的場景,做了性能上的優化,儘量降低性能和響應時間的損耗。

從最終上線運行的結果來看,雖然跨數據中心流量確實帶來了業務整體聯機交易耗時的增加,但都在可預期和可接受的範圍內。

同城應用多活的架構改造,進一步提升了整體的可用性,簡化了容災架構,同時也將數據庫的六副本縮減爲三副本,極大的降低了資源成本,可以說很好的完成了架構優化目標。

(三)

2018~2020,引入 NEWSQL 數據庫

隨着業務的快速發展,DCN 的數量也在快速增加,DCN 的水平擴展特性很好的支撐了業務的快速增長。但在某些非 DCN 架構的中後臺業務場景中,單實例架構的 TDSQL 逐漸遇到了容量或者性能上的瓶頸。

一個比較典型的場景就是安全存證類的數據存儲。這個場景屬於中後臺業務,需要持續存儲交易行爲類的數據,以供隨時審計或者舉證,所以一般是不能刪除的。隨着業務規模增漲,存證數據也會持續的增漲。

然而對於單實例的 TDSQL 或者 MySQL 實例來說,是要求不能超過 3TB 的存儲容量的,一個原因是硬件層面的限制(SSD 的單盤容量),另一個原因是單實例過大的容量,會帶來數據庫性能上的不確定性和運維的複雜性。

按照比較傳統的解決方案,可以選擇基於中間件的分庫分表方案來解決這個問題(TDSQL 也有提供分庫分表的版本)。

然而分庫分表事實上是對業務開發和 DBA 都不太友好的一種方案。對業務開發來說,因爲分庫分表一般在語法和 SQL 使用層面都會有一些限制和限定,所以一般需要重構代碼和 SQL,以適配分庫分表環境下的數據庫使用;對於 DBA 來說,分庫分表的擴展性不是那麼靈活,DDL 等日常操作也比較得複雜,使得整體的運維工作量增加。

我們不想走回分庫分表的老路,所以也在探尋有沒有更優雅、更先進的解決方案。2018 年下半年開始,NEWSQL 的概念逐漸興起,帶來了一種全新的 share nothing 的分佈式架構的數據庫(基本上是以 Google Spanner 分佈式架構爲原型)。

經過充分的調研和評估,我們最終選取國產開源的 NEWSQL 數據庫產品 TiDB 進行嘗試。TiDB 主要有以下幾個特性吸引了我們:

  1. TiDB 採用了標準的 Share Nothing 架構,計算與存儲分離,並且都可以做到水平擴展,且對業務層透明。

  2. TiDB 採用 MySQL 協議體系,與我們當前的協議體系兼容度高,降低業務的開發和遷移成本以及接入門檻。

  3. TiDB 採用開源的模式進行運營,社區較爲活躍,版本迭代較快,並且已有一部分的互聯網用戶開始使用。

TiDB 整體架構

可以說,TiDB 的特性可以很好的解決我們的需求和瓶頸,但當時 TiDB 還是屬於一個非常新興的數據庫產品,穩定性和成熟性不夠,所以我們也是非常謹慎的進行充分的測試和驗證,在生產上首先選取的比較邊緣的業務場景進行灰度,並且準實時同步一份數據到 TDSQL 進行兜底。

TiDB 在微衆的部署架構也類似於 TDSQL,利用同城三機房的硬件優勢,採用同城三副本跨三中心部署,可以有效的支持應用同城多活架構。

TiDB 部署架構

經過近兩年多的運營,我們已將 TiDB 應用在安全、智能監控、數據歸檔、反欺詐、反洗錢、歷史交易明細查詢等各類中後臺業務中。隨着 TiDB 的版本逐漸成熟,整體的穩定性和可運維性也提升了不少。

回頭來看,雖然我們冒着喫螃蟹的風險,採用了 NEWSQL 的方案而主棄了分庫分表的方案,但帶來的收益也是巨大的。

目前,TDSQL 繼續作爲核心數據庫,承載 DCN 架構下的核心繫統;TiDB 作爲補充,承載非 DCN 架構下的、對容量和擴展性要求較高的中後臺系統。TiDB 作爲微衆整個單化元架構的補充,很好的補齊了數據庫層面的短板。

(四)

2020~2021,

NEWSQL 在覈心批量場景的應用

經過兩年多對 TiDB 數據庫的使用,踩了不少坑,也積累了不少經驗。TiDB 本身隨着版本迭代也更加成熟穩定,逐漸形成企業級的數據庫產品。

2020 年初,我們收到了貸款科技部門針對貸款核心的日終批量系統的優化需求。

當時,貸款核心系統的日終批量系統是部署在業務 DCN 內部的,和聯機系統複用 DCN 內的 TDSQL 數據庫資源。隨着交易數據的日積月累,貸款核心系統的批量面臨着以下幾個問題:

  1. 批量的耗時持續增漲(優化前已近三小時),如果因爲某種原因批量需要重跑,有比較大的超時風險。

  2. 批量系統和聯機系統都在 DCN 內部署,批量系統帶來的數據庫高負載,會對聯機系統產生影響。

  3. 受限於 MySQL 的主備複製的原理限制以及單實例的性能瓶頸,無法繼續通過提高應用層併發來提升批量效率。

  4. 批量效率逐漸成爲單個 DCN 的用戶容量瓶頸,而非實際的用戶量。

貸款核心批量架構(優化前)

基於以上問題,業務部門也提出了優化目標:

  1. 將整個批量系統重構(包括應用層和數據庫層),核心業務微粒貸的整體批量耗時縮短到半小時內以(在限定的資源內);

  2. 將批量系統的資源和聯機系統完全解耦(包括應用層和數據庫層);

  3. 批量系統的數據庫需要具備可水平伸縮的特性。

最初看到這個優化目標,感覺還有挑戰的。特別是每天數億條帳務的批量計算處理,需要優化到半小時以內完成,應該沒有那麼容量。

經過評估,我們最終決定嘗試用 NEWSQL 數據庫 TiDB 來承載貸款核心的批量系統(優化後的架構如下圖)。批量數據每天通過 DCN 內的 TDSQL 近實時的同步到 TiDB 集羣進行彙總,然後由批量應用程序在 TiDB 集羣進行批量計算和加工。經過近一年的持續優化、調整和灰度驗證,最終項目順利上線,並且完全達到了既定的優化目標。

貸款核心批量架構(優化後)

下表是微衆 5 個主要貸款業務的核心批量優化前後的耗時對比,優化效果非常明顯。

在整個項目的實施的過程中,踩坑不少,也總結了不少的優化經驗和教訓,主要有以下幾點:

1、應用 SQL 模型的整體重構和優化。

2、基於 TiDB 的熱點數據打散機制優化

在 share nothing 架構的數據庫中, 數據熱點是經常會遇到的一個問題,如果分片規則或者應用的寫入的規則不合理,很容易就形成針對某一個數據庫分片的熱點,導致數據庫響應變慢,甚至假死。

貸款核心的批量數據表,都是數億級別的數據量導入,熱點問題更加明顯。針對這種超大表的數據導入,我們聯合數據庫廠商,開發了數據表預打散的功能,完全避免了熱點問題。

3、TDSQL 到 TiDB 數據同步的一致性校驗機制優化

貸款核心批量的數據正確性至關重要。在優化後的架構,批量數據表需要從多個 TDSQL 源近實時的彙總同步到一個 TiDB 集羣中,並進行合表處理。爲了保證數據同步的可靠性和準確性,我們在三個層面做了優化:

4、故障 SOP 預案和兜底機制的建立和演練

TiDB 數據庫在貸款核心批量系統的應用,是對微衆整個單元化架構的又一次補充和完善。我們經常說,數據庫沒有銀彈,沒有一種數據庫能夠適用所有的業務場景。針對每個場景,用最適合的數據庫產品和數據庫架構,纔是價值的最大化。

除了關係數據庫產品,我們也大量使用了 Redis 來適合大部分需要高併發、低延遲響應的讀場景。在儘量保證架構一致性的前提下,我們根據業務的實際需求,也少量引入了 Monggo DB、PostgreSQL、Oracle 等數據庫產品。

未來,我們也將在數據庫的雲原生、數據庫的智能運維、數據庫的硬件國產化、HTAP 場景的應用實踐等方向繼續探索,不斷提升和完善我們的架構,爲國產數據庫在金融場景的應用實踐貢獻自己的一份力量。

作者 enochhu(胡盼盼) 基礎科技產品部 / 數據庫運維室

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/cwBKxQXfpMC1X1qoLLUkwg