微衆銀行數據庫架構演進及 TiDB 實踐經驗

做者介紹:

胡盼盼,微衆銀行數據平臺室室經理。碩士畢業於華中科技大學,畢業後加入騰訊,任高級工程師,從事分佈式存儲與雲數據庫相關的研發與運營工做;2014 年加入微衆銀行,負責微衆銀行的數據庫平臺的建設與運營。mysql

黃蔚,微衆銀行數據庫平臺室高級 DBA。2011 年加入騰訊互動娛樂運營部,擔任英雄聯盟在內的多款海量用戶產品的數據庫運維工做。2015 年加入微衆銀行擔任高級 DBA,負責監控優化、性能優化以及新技術預研,目前致力於行內 NewSQL 的推廣與生態建設。算法

本文將介紹微衆銀行的數據庫架構演進過程,並分享 TiDB 在微衆銀行實踐經驗和部分業務案例。sql

1、微衆銀行數據庫架構演進

2014 年微衆銀行成立之時,就很是有前瞻性的確立了微衆銀行的 IT 基礎架構的方向:去 IOE,走互聯網模式的分佈式架構。IOE 即 IBM、Oracle、EMC,表明了傳統基礎架構領域的服務器、商業數據庫和存儲產品體系,衆所周知傳統銀行 IT 架構體系很是依賴於 IOE,每一年也須要巨大的 IT 費用去維護和升級 。從數據庫角度來看,當時除了 Oracle,能知足金融級銀行場景的數據庫產品並很少,微衆銀行基礎架構團隊通過多輪的評估和測試,最終肯定使用騰訊主推的一款金融級別數據庫 TDSQL。數據庫

<center>圖 1</center>安全

TDSQL 是基於 MariaDB 內核 ,結合 mysql-proxy、ZooKeeper 等開源組件實現的數據庫集羣系統,而且基於 MySQL 半同步的機制,在內核層面作了大量優化,在性能和數據一致性方面都有大幅的提高,同時徹底兼容 MySQL 語法,支持 Shard 模式(中間件分庫分表)和 NoShard 模式(單機實例),同時還集成了管控平臺,智能運維等功能模塊。2014 年,TDSQL 已經支撐了騰訊內部的海量的計費業務,因爲計費業務的場景和銀行的場景有所相似,對數據庫的可靠性和可用性要求也相近,因此咱們當時選擇了 TDSQL 做爲微衆銀行的核心數據庫。性能優化

1. 基於 DCN 的分佈式架構

<center>圖 2</center>服務器

肯定了數據庫的選型以後, 下一步就是架構設計。咱們設計了基於 DCN(Data Center Node)的分佈式架構。DCN 能夠認爲是一個「自包含單位」,它會包含應用層、接入層、數據庫層,每一個 DCN 承載規定數據量的用戶,通俗的理解,每一個 DCN,就至關於微衆銀行的一個小的分行;基於 DCN 能夠實現集羣規模的水平擴展。這種架構對於數據庫來講,實際上是比較友好的,由於每一個 DCN 的用戶規模是肯定的,那麼對數據庫的容量和性能要求也是可肯定的,所以咱們沒必要再採用複雜的中間件分庫分表的方式構建數據庫,而只用單實例模式承載,極大簡化了數據庫架構,也下降了業務開發成本。網絡

如圖 2 所示,爲了實現 DCN 架構,這裏有兩個關鍵組件:RMB 和 GNS。RMB 負責各個模塊以及各個 DCN 之間的消息通訊;GNS 負責全局的 DCN 路由,即某個用戶保存在哪一個 DCN。另外這裏有一個比較特殊的地方就是 ADM 管理區,它是一個統一的管理區,保存着沒法進行 DCN 拆分的全局業務數據,和經過各 DCN 進行彙總的數據。後來 ADM 區成爲了一個 TDSQL 的瓶頸,這是咱們引入 TiDB 的動機之一。架構

2. IDC 架構

<center>圖 3</center>併發

接下來看一下咱們的 IDC 的架構。目前咱們是兩地六中心的架構,深圳的 5 個 IDC 是生產中心,而位於上海的跨城 IDC 是容災中心。同城的任意兩個 IDC 以前的距離控制在 10~50 千米之內,並經過多條專線互聯,以此保證兩個 IDC 之間的平均網絡延遲能夠控制在 2ms 左右,並保證網絡的穩定性。

3. 數據庫部署架構

<center>圖 4</center>

基於以上的 DCN 架構和 IDC 架構,咱們設計了數據庫的基礎架構,如圖 4 所示:咱們採用同城 3 副本+跨城 2 副本的 3+2 部署模式,同城 3 副本爲 1 主 2 備,跨 3 個同城 IDC 部署,副本之間採用 TDSQL 強同步,保證同城 3 IDC 之間的 RPO=0,RTO 秒級,跨城的 2 副本經過同城的一個 slave 進行異步複製,實現跨城的數據容災。基於以上架構,咱們在同城能夠作到應用多活,即同城的業務流量,能夠同時從 3 個 IDC 進來,任何一個 IDC 宕機,能夠保證數據 0 丟失,同時在秒級內能夠恢復數據庫服務。這個架構在微衆銀行內部運行了四年多,當前已有 1500 多個實例在運行,數據量達到 PB 級,承載了銀行數百個核心系統,總體上來講還比較穩定的。但同時也遇到一些瓶頸。由於咱們採用的是單實例的部署模式,對於有些沒法經過 DCN 拆分進行擴展的業務場景,單實例的性能和容量就很容易到達瓶頸。

固然,TDSQL 也提供了 TDSQL-Shard 模式,也就是經過中間件分庫分表的方式把一個表 Shard 以後再處理,但咱們當時評估以後認爲該模式對應用的侵入性比較大,好比全部的表必須定義 shard-key,有些語法可能不太兼容,有些分佈式事務的場景可能會有瓶頸,進而致使業務遷移的成本會比較高。

因此在這個背景下,咱們開始尋求其它的解決方案,大約在 2018 年,NewSQL 的概念逐漸被提了出來,同時也有一些商業和開源的 NewSQL 數據庫出現。咱們很驚喜的發現,NewSQL 數據庫的特性,能夠較好的解決咱們當時面臨的問題。NewSQL 比較通用的定義是:一個能兼容相似 MySQL 的傳統單機數據庫、可水平擴展、數據強一致性同步、支持分佈式事務、存儲與計算分離的關係型數據庫。通過大量的調研,對比與分析,咱們最終決定重點考察開源 NewSQL 數據庫產品 TiDB。

2、微衆銀行 TiDB 數據庫實踐

1. Why TiDB ?

<center>圖 5</center>

除了 TiDB 的 NewSQL 特性以外,咱們選擇 TiDB 的另外一個主要緣由,就是 TiDB 是一個開源的項目,並且社區很活躍,版本迭代快速,咱們以爲這是一個很好的模式,並且微衆自己也是很是擁抱開源的

<center>圖 6</center>

這裏展現了 TiDB 的基本架構模型,很是簡潔優雅的架構,相信稍微瞭解 TiDB 的同窗,對這個架構都比較熟悉了,在這裏就再也不贅述。固然,如今 TiDB 3.0 版本有了新的特性以及模塊加入,好比 Titan 引擎, 針對 RocksDB 大 Value 寫放大問題作了很大的優化和性能提高,再好比列式存儲引擎 TiFlash ,爲實現真正的 HTAP 奠基了基礎。

2. 對 TiDB 的評估與測試

<center>圖 7</center>

咱們對 TiDB 作了一些評估和測試,對語法和 DDL、負載均衡、一致性、擴容等特性都作了不少測試。下面重點介紹如下 3 點:

  • 支持在線 DDL,不鎖表,對業務無影響

    這個特性對咱們來講,有很大的好處。由於在 MySQL 裏面作 DDL,是風險比較大或者說比較重的一個操做,特別是一些超大的表的 DDL;但在 TiDB 裏,這個操做變得輕量而安全。

  • TiDB 採用樂觀鎖事務模型

    這和 MySQL 的悲觀鎖模型是不太同樣的,這個特性對於某些業務場景的兼容性可能會有問題。
    TiDB 3.0 版本中已經試驗性支持了悲觀鎖,而且在今年下半年有望成爲一個正式功能,這是一個很好的消息。在金融場景裏面悲觀鎖應用仍是比較普遍的

  • 支持同城 IDC 部署與切換,經過了真實的 IDC 隔離故障演練

    咱們將 TiDB,TiKV,PD 節點跨 3 個同城機房部署,而後把其中一個機房的網絡所有隔離,來測試 TiDB 的可用性,包括 Raft Group 的 Leader 的切換等等,測試結果總體符合預期。

3. TiDB 在微衆的部署模型

<center>圖 8</center>

圖 8 是 TiDB 在微衆銀行的部署模型,從一開始就選擇了同城三機房部署,也就是位於最底層的存儲層 TiKV 跨 3 個機房,3 個副本分佈在 3 個機房,而且每一個機房有 1 套獨立的 TiDB Server 集羣負責接入與計算;PD 模塊也是跨 3 個機房部署。另外,針對比較重要的業務,咱們會在容災 IDC 掛一個容災 TiDB 集羣,這個容災 TiDB 集羣會經過 TiDB Binlog 工具從生產集羣實時同步數據。

3、微衆銀行 TiDB 業務實踐

TiDB 在微衆銀行的應用場景包括 OLAP、OLTP 及部分混合場景,大部分場景在 TB 級別的業務數據規模。下面詳細介紹貸款核心批量系統在測試 TiDB 過程當中的實踐和優化,以及數據存證系統 TiDB 遷移實踐

1. 貸款核心批量場景下的 TiDB 實踐

<center>圖 9</center>

這個業務場景的特殊性在於天天晚上 0 點以後,須要經過線上數據庫生成數億級別的批量數據,並進行一系列相關計算,而後 ETL 到大數據平臺去,其中涉及大量的增刪查改操做,而且對總時效要求很高,必須在兩個小時內跑完,不能出現任何問題。

存在的問題

  • 跑批的時間過長,接近 2 小時,並且業務規模還在擴大。
  • 分散於各個 DCN 跑批,而後進行數據彙總,架構比較複雜。
  • 受限於 MySQL 主備複製的性能,沒法再增長併發,跑批的時間沒有辦法再縮短,不然會影響聯機系統可用性。

因此咱們嘗試經過 TiDB 來承載這個批量場景,把天天的批量數據,彙總到一個大的 TiDB 集羣中,再進行跑批,最後再 ETL 到大數據平臺中去作處理。整個流程如圖 9 右半部分所示,其中 「DM 工具」即 TiDB DM(TiDB Data Migration),是由 PingCAP 開發的一體化數據同步任務管理平臺,支持從 MySQL 或 MariaDB 到 TiDB 的全量數據遷移和增量數據同步。

咱們對應用側和 TiDB 2.1 版本進行了一系列的調優,總體的優化效果達到預期,批量的耗時縮短了 45% 左右。咱們同時也測試了 3.0 beta 版本,3.0 相對於 2.1 版本,總體批量耗時又縮短了 30% 左右。總體來看,TiDB 讓咱們的貸款核心批量場景下效率獲得大幅度的提高

在整個業務測試的過程當中。咱們在應用側和數據庫側,都作了大量優化,也踩了很多坑,這裏也分享幾點。

a. 數據導入過程 Region 熱點集中

<center>圖 10</center>

該業務對批量數據導入的時間很敏感,但咱們測試時發現雖然底層有 6 個 TiKV 節點,但每次數據開始導入時有 3 個 TiKV 節點負載特別高,另外 3 個節點負載很低,同時寫入也有瓶頸。經過排查發現這個問題的緣由在於,對於快速的超大表的數據寫入,TiKV 的熱點調度並不及時,沒有辦法作到負載均衡,進而致使熱點。

咱們和 PingCAP 夥伴們討論解決方案後,增長了 Region 預打散的功能。就是在建表時,就對錶進行 Region 打散操做 ,至關於一個空表就分散成多個 Region 分佈在 6 個 TiKV 節點上,當數據導入的時候就直接寫入各個 Region。從圖 10 能夠看到增長預打散功能後,6 臺 TiKV 的負載很是均衡,而且耗時也變短了。

b. 無效 Region 過多致使系統變慢

<center>圖 11</center>

另一個遇到問題就是無效 Region 過多的問題。前面提到,該業務數據在天天跑批完成以後須要刪掉,次日所有數據須要從新生成,因此該場景下天天都有大量的數據表刪除和重建,會累積大量無效 Region,致使 PD 元數據管理壓力過大,Region 副本之間的心跳也會大量增長 grpc 調用,致使整個系統運行比較慢。因此咱們後來灰度上線了 Region merge 功能,這個功能在 TiDB 2.1.8 之後的版本中(含 3.0 GA)引入,

從 圖 11 能夠看到上線 Region merge 功能以後,Region 數量直線降低, 這個功能讓系統性能的提高提高了 30% 左右

2. 數據存證系統 TiDB 遷移實踐

數據存證系統是微衆銀行很是重要的系統,存儲了具備法律效力的證據類數據,這些數據對客戶來講是很是重要的。

<center>圖 12</center>

隨着愈來愈多的業務系統的接入,該場景的數據增加速度很是快,好比每一次轉賬都須要生成一個證據,而且不是簡單的一條記錄,而是發生糾紛時法院承認的證據,因此也決定了這些數據不能刪除。這些數據劃分在 ADM 區,沒辦法作橫向擴展,遇到了很大的瓶頸。基於這些場景特色,微衆選擇了 TiDB 的解決方案。咱們有幾個基本的遷移原則:1)數據不能錯、不能丟;2)服務敏感度很是高,須要儘可能無縫切換到 TiDB 架構上;3)由於是比較嚴肅的金融場景,若是在遷移過程當中有任何困難,咱們指望可以隨時回切到 MySQL。

<center>圖 13</center>

遷移總體方案如圖 13,步驟流程比較長,但會更加安全。接下來介紹每一個步驟中咱們碰到的困難和解決方案。第一個步驟是前置檢查。首先表必須有主鍵,若是是短期海量連續寫入,不建議用自增 ID,能夠把自增 ID 改爲由雪花算法生成,再把雪花算法的時間戳後幾位提到最前面,這樣能夠保證主鍵足夠隨機 ,而後使用咱們以前提到的 Split Region 的功能,提早把 Region 切分,並打散到全部的 TiKV 節點裏,這樣能夠在寫入的時候實現負載均衡,解決短時大量寫入瓶頸問題。

<center>圖 14</center>

觸發器、存儲過程、視圖、function 這些特性在咱們行內是禁止使用的,因此對咱們是沒有影響的。總體來看,前置檢查這一步咱們重點關注的是性能問題,尤爲是保證寫的性能,該場景是大批量數據,短期的數億數據寫入性能的瓶頸問題仍是值得關注並解決的。

<center>圖 15</center>

前置檢查完成後,接下來就是將數據同步到 TiDB,PingCAP 提供了實時同步工具 TiDB DM,在簡單配置以後能夠「一鍵式」將 MySQL 中的數據導入 TiDB,讓數據遷移變得很是便捷。固然,咱們也遇到了幾點問題:

  • DM 不能保證高可用的問題。

    咱們和 PingCAP 研發同窗們討論以後,臨時解決方案是部署兩個 dm-worker(冗餘部署),一旦某個 dm-worker 發生問題,就啓動另一個 dm-worker,從下游記錄的 pos 點繼續同步數據。另外,咱們很是期待將來 DM 整合到 TiDB 的 K8s 部署生態工具鏈中, 再配合雲盤(好比 ceph)作狀態信息的存檔 ,這樣會更加完善 DM 的高可用性,咱們也深度參與了 PingCAP 研發同窗們關於 DM 高可用方案的設計討論。

  • 上游故障須要人工切換的問題。

    由於目前「一主多備」架構下,咱們把 DM 掛載在其中一臺備機,若是這臺備機因爲服務器故障緣由致使宕機,就須要人工把 DM 掛載其餘正常的備機,處理時效上會沒那麼及時;很是期待將來 DM 可以把這個切換操做作成自動化。

  • 從 DM 角度看, 表必需要有主鍵。

    一方面,DM 回放 binlog 時須要作併發處理,可是處理以前會作衝突檢測,若是沒有主鍵就作不了衝突檢測,也就不能作併發回放,致使同步效率比較差。另外一方面,冪等操做,好比 DM task 重啓或者恢復,會從下游記錄的 pos 點繼續同步數據,但由於 pos 點不是實時記錄,因此會致使重複回放 binlog,若是沒有主鍵,好比重跑兩次 insert,數據就重複寫入了。所以就要求表必須有主鍵,DM task 重啓或者恢復的時候,DM 內部作一個冪等轉換,好比把 Insert 轉換成 replace ,把 update 轉換成 delete+replace,這樣的話就算重跑不少次,它的結果是不會受影響的。

<center>圖 16</center>

做爲一個金融場景,尤爲是異構的數據同步,數據校驗是一個很是嚴肅的確認過程。熟悉 MySQL 的同窗應該瞭解過 pt-table-checksum 工具,它的原理和 PingCAP 提供的數據校驗功能相似,將這個數據切片以後,對數據切片進行 checksum 計算,而後比對上下游全部切片的 checksum 值是否同樣來判斷數據一致性;可是它當前還作不到相似 pt-table-checksum 的在線校驗,若是上游 MySQL 的數據一直在變,就沒辦法作校驗了。另外,Chunk 切分偶爾不許、上下游排序規則不一致,這兩個問題已經在新版本有了優化。

<center>圖 17</center>

接下來是灰度切讀流量的過程。基於安全性考慮,咱們先把非關鍵的讀流量灰度切換到 TiDB 中去,觀察一段時間,再把關鍵的讀流量也逐漸切換到 TiDB。當時遇到了執行計劃不許的問題,致使把讀流量切換到 TiDB 後發現,有些 SQL 查詢變慢了,這個問題在新版本中已經解決了,包括 TiDB 3.0 中也有執行計劃綁定(Plan Management)、增量統計信息更新等優化。

實際上,執行計劃不許的問題在 MySQL 等一些數據庫產品中比較廣泛,由於統計信息不能 100% 實時更新。之前使用 MySQL 產品時,用戶可能須要強制指定某個索引 Index,這個操做對業務侵入性很大,而基於上面兩個功能,TiDB 在這點上對業務的侵入是不多的。

<center>圖 18</center>

在讀流量切換到 TiDB 沒有出現什麼問題以後,咱們再把寫流量切換到 TiDB,但也不是一次性切換,咱們選擇先雙寫 TiDB 和 MySQL:先寫 MySQL 返回自增 ID,再用該 ID 加上業務數據異步寫入到 TiDB;上下游的 ID 保存一致方便咱們進行數據校驗。在雙寫改造完成後,架構如圖 18 所示。應用準備發版時,爲了保證業務暫停的時間足夠短,咱們臨時調大了消息隊列 MQ 的長度,由於在整個應用關閉以後,消息隊列仍在存儲消息,可能會把消息隊列存滿。調大消息隊列長度以後,再逐個關閉應用,等到全部應用都停掉後,在確認 DM 的數據同步已經追平後,就能夠把 DM 斷開,接下來就能夠逐個啓動新版本的應用了。業務中止時間(最後一個應用關閉到新版本第一個應用啓動的時間間隔)控制在 1 分鐘之內,對應用的影響很是小

到這一步驟爲止,其實整個服務讀寫都採用了 TiDB,但爲了保證數據出現問題時可以及時回遷,因而咱們把灰度上線的的週期拉長,使用 TiDB Binlog 把 TiDB 中的數據反向同步到 MySQL,以下圖所示。

<center>圖 19</center>

咱們觀察到 Drainer 與同城 IDC 的下游 MySQL 部署在一塊兒,RPC 延遲會更短,性能會更好。在幾個月以後,咱們最終把反向同步關閉了,徹底由 TiDB 提供服務。

<center>圖 20</center>

如圖 20 所示,咱們還會作例行的數據備份的操做,包括使用 mysqldump 每週全量備份,使用 drainer pb 每 5 分鐘備份增量 binlog,另外數據備份最好使用單獨的 tidb-server 節點,對聯機的請求影響最小。

在觀察一段時間以後,觀察到各方面的性能指標都很是穩定,而後決定將反向同步 MySQL 斷掉,也就意味着數據存證系統這樣一個很是重要的系統,徹底跑在了 TiDB 上,回顧整個遷移過程,仍是比較流暢且順利的

4、總結

TiDB 是一個很優秀的分佈式關係型數據庫產品。對銀行場景來講,灰度和上線的節奏沒有互聯網行業那麼快,隨着 TiDB 產品的日趨成熟,咱們正在更多適合的場景試用 TiDB,也會有更多的經驗和你們分享。

本文根據胡盼盼、黃蔚在 TiDB TechDay 2019 北京站及深圳站上的演講整理。

相關文章
相關標籤/搜索