TiDB 在馬上消費金融核心賬務系統歸檔及跑批業務下的實踐

作者介紹:

康文權,馬上消費金融總賬高級研發工程師。

李銀龍,原騰訊雲運維工程師,馬上消費金融容器雲 TiDB 負責人,西南區 TUG Leader。

背景介紹

馬上消費金融於 2015 年 6 月營業,截止到 2020 年 1 月,歷經 4 年多風雨,總註冊用戶數 8000 萬,活躍用戶數 2500 萬,累計放貸 2900 多億元人民幣。公司於 2018 年 6 月增資到 40 億,成爲內資第一大的消費金融公司。

在業務爆發式增長的 4 年多裏,馬上消費金融的數據庫經歷了從單表數十 GB 到數百 GB 的過程,單表的數據量正在往 TB 級別演進。基於數據量的升級變遷,我們的數據庫也經歷了 2 次架構迭代,並在探索

第三代數據庫架構:

  • 第一代數據庫架構——核心系統以 Oracle 爲主,MySQL 爲輔的時代。
  • 第一代數據庫架構——核心系統以 Oracle 爲主,MySQL 爲輔的時代。
  • 第三代數據庫架構——核心系統以 MySQL 結合 NewSQL 爲主,NewSQL、MySQL、NoSQL 並存的時代。

馬上金融第二代數據庫架構痛點

海量數據 OLTP 場景需求痛點

截止目前賬務系統的核心表累計數據量已達到單表 15 億行以上,還在高速增長中。監管要求金融行業歷史數據至少保留 5 年以上。這給數據庫系統帶來了巨大挑戰:

  1. 海量的歷史交易與賬務數據堆積在 MySQL 數據庫中,使數據庫臃腫不堪,維護困難(在線 DDL 變更、數據遷移、磁盤容量瓶頸、磁盤 IO 瓶頸等)。

  2. 用戶對歷史交易訂單的查詢(OLTP 場景)是必備功能,這些海量的歷史數據會根據用戶需求通過 Web 頁面、APP 終端等渠道進行實時查詢(內部、外部用戶)。此場景決定了不能通過傳統的離線大數據方案來滿足需求。需要一種偏向於前臺、中臺的數據治理方案

傳統分庫分表解決方案痛點

根據馬上金融的經驗,MySQL 單表在 5000 萬行以內時,性能較好,單表超過 5000萬行後,數據庫性能、可維護性都會極劇下降。當我們的核心賬務系統數據庫單表超過 100GB 後(截止 2018 年 10 月該表累計已達到 528GB),經技術架構團隊、業務需求團隊聯合調研後,選擇了 sharding-jdbc 作爲分庫分表的技術方案。

此方案的優點非常明顯,列舉如下:

  1. 將大表拆分成小表,單表數據量控制在 5000 萬行以內,使 MySQL 性能穩定可控。

  2. 將單張大表拆分成小表後,能水平擴展,通過部署到多臺服務器,提升整個集羣的 QPS、TPS、latency 等數據庫服務指標。

但是,此方案的缺點也非常明顯:

  1. 分表跨實例後,產生分佈式事務管理難題,一旦數據庫服務器宕機,有事務不一致風險。

  2. 分表後,對 SQL 語句有一定限制,對業務方功能需求大打折扣。尤其對於實時報表統計類需求,限制非常之大。事實上,報表大多都是提供給高層領導使用的,其重要性不言而喻。

  3. 分表後,需要維護的對象呈指數增長(MySQL 實例數、需要執行的 SQL 變更數量等)。

傳統 MySQL 在線 DDL 痛點

對超過賬務系統的 528GB 大表分庫表成 16 張表之後,每張表有 33GB,仍然是大表。我們採用了 gh-ost 工具進行加字段 DDL 操作,但是,業務仍然會有輕微感知。因此,必須要將大表的 DDL 操作放到凌晨來做,對業務的 7*24 小時服務有較大限制。

原生 MySQL 的 HA 機制不完善痛點

MySQL 的集羣基於 Binlog 主從異步複製來做,切集羣主從角色以 instance 爲單位,非常僵化。一旦主庫出現故障,需要人工重建 MySQL 集羣主從關係(也可以把人工操作落地成程序,比如 MHA 方案),截止目前(2020 年 1 月)原生 MySQL 仍然沒有成熟可靠基於 Binlog 異步複製的 HA 方案。基於 Binlog 異步複製的 MySQL 主從架構實現金融級高可用有其本質困難。

馬上金融 NewSQL 技術選型

基於馬上金融第二代數據庫架構的核心痛點,我們需要探索新的數據庫技術方案來應對業務爆發式增長所帶來的挑戰,爲業務提供更好的數據庫服務支撐。

恰逢 NewSQL 愈漸火熱,引起了我們的極大關注。NewSQL 技術有如下顯著特點:

  • 無限水平擴展能力

  • 在線 DDL 操作不鎖表

  • 分佈式強一致性,確保金融數據 100% 安全

  • 完整的分佈式事務處理能力與 ACID 特性

在賬務系統研發團隊、公共平臺研發團隊、DBA 團隊等聯合推動下,我們開始對 NewSQL 技術進行調研選型。

在 GitHub的活躍度及社區貢獻者方面,TiDB 與 CockcoachDB(CRDB) 都是國際化的全球開源級項目,是 NewSQL 行業中的代表性產品。

由於馬上金融的應用絕大部分對 MySQL 依賴較高,在協議兼容性方面,我們毫無疑問地將 MySQL 兼容性列爲必選項。

TiDB 從項目發起之初就將 MySQL 協議兼容性列爲最 basic 的戰略目標之一。而 CRDB 在項目發起之初,考慮的是兼容 PostgreSQL 協議。

基於此,我們優先選擇了 TiDB 技術產品。

馬上金融實踐案例分享(兩則)

案例一:核心賬務系統歸檔場景

馬上消費金融賬務系統歸檔項目是公司第一個持續實踐 TiDB 的項目,也是第一個對 NewSQL 技術提出迫切需求的項目,上線後 TiDB 架構如下:

上游分庫分表的 8 套 MySQL 集羣通過 DM 聚合到一套 TiDB 裏,TiDB 對外提供歷史歸檔大表查詢服務。

應用架構關鍵機制:

  • 讀寫分離。通過 sharding-jdbc 實現應用程序讀寫分離,將歷史數據查詢請求分發到 TiDB 集羣。

  • 熔斷機制。應用架構設計了熔斷機制,當請求 TiDB 超時或者失敗後,會自動將請求重新轉發到 MySQL,恢復業務。

通過熔斷機制可確保萬一 TiDB 出現異常時,能快速恢復業務,確保業務的可用性。

賬務 TiDB 集羣每天業務高峯期將會承載約 1.3 萬 QPS 的請求量(如下圖所示),在做活動期間,請求量能衝擊到近 3 萬 QPS。

經過接近 1 年的不斷優化提升,TiDB 集羣表現越來越穩定,大部分請求能在 50ms 內返回:

研發同事對 TiDB 的 Latency 與 TPS 的性能表現比較滿意。

在 2019 年 4 月,賬務系統 TiDB 項目已將 MySQL 數據庫 2018 年以前的歷史數據刪除。極大地降低了賬務系統 8 套 MySQL 數據庫集羣的 IO 壓力。這部分歷史數據僅保存在 TiDB 集羣內,對業務提供實時查詢支持。

案例二:總賬跑批業務場景

馬上消費金融總賬項目是公司第一個完全運行在 TiDB 的項目,也是第一個從項目上線之初就放棄 MySQL,堅定不移選擇 TiDB 的項目。

總賬項目部分模塊關鍵流程示意圖如下:

馬上消費金融總賬項目是公司第一個完全運行在 TiDB 的項目,也是第一個從項目上線之初就放棄 MySQL,堅定不移選擇 TiDB 的項目。

總賬項目部分模塊關鍵流程示意圖如下:

  • 數據量基數大。總賬項目吸納了公司核心賬務系統以及其他關聯繫統的所有數據,數據基數非常巨大,要求至少 10TB+ 空間,未來 2 年內可能會增長到 20TB 以上。這個基數 MySQL 難以承載。

  • 每日批量時限短。總賬項目服務於管理層,每月初呈現公司當月的營收覈算等信息。在總賬項目數據量基數巨大的前提下,日增量 5 億到 10 億,希望每天能在 3 個小時內完成跑批,用 MySQL 單實例跑不下來。而分庫分表技術方案對於總賬系統出報表需求又具備其客觀難題。

TiDB 是分佈式 NewSQL,計算與存儲分離,且計算節點與存儲節點都具備水平擴展能力,特別適用於總賬項目的大數據量、大吞吐量、高併發量場景。

項目上線已穩定運行半年左右,目前集羣規模如下:

  • 8 TB+ 數據量

  • 12 POD TiDB 節點

  • 24 POD TiKV 節點

  • 跑批期間峯值超過 10 萬 QPS

總賬項目目前完成了第二期開發,隨着項目的繼續發展,未來第三期的 ngls 正式接入後,數據量與併發量將再次成倍增長。

總賬項目上線後,跑批期間 QPS 如下:

跑批期間的 SQL 響應時間如下:

跑批期間的 TiKV CPU 使用率如下:

跑批期間事務量與性能如下:

馬上金融 TiDB 經驗總結分享

TiDB 切入點經驗

TiDB 是一個新潮的 NewSQL 數據庫。想要將 TiDB 運用到生產環境,解決 MySQL 數據庫面臨的歷史難題(而不是把問題搞得更大),並不是一件簡單的事情。

時至今日(2020 年 1 月 14 日),TiDB 已經在數千家企業有實踐經驗,其中不乏大型銀行核心系統 TiDB 實踐經驗。且 TiDB 3.0 GA 之後,TiDB 在性能、穩定性方面比起之前版本都有了很大的提升。

這意味着已經有數千家企業在向 PingCAP 官方反饋 TiDB 的各種問題並持續得到修復。在這樣的背景下,TiDB 能在生產環境中穩定運行並持續爲企業創造價值已是毋庸置疑。

對於企業而言,當前的關注焦點可能不再是 TiDB 是否穩定可靠,而是怎麼才能快速獲取到 TiDB 的最佳實踐經驗,將其納入企業基礎技術棧之內。

那麼,如何才能快速實踐 TiDB,積累到第一手經驗,使企業儘快享受到 TiDB 帶來的福利呢?

建議從兩個方面切入:

  • 選定一個歸檔項目着手嘗試: 參考我們的賬務系統 TiDB 歸檔技術方案作爲企業的切入點。通過此方案,大家可以快速上手 TiDB,在技術風險可控的前提下積累到 TiDB 實踐經驗。

  • 聯繫官方或者 TUG 組織獲取資源:TiDB 是一個全新的分佈式數據庫,整個體系架構的相比於 MySQL 要複雜得多。而截止目前(2020 年 1 月 14 日),TiDB 官方提供的文檔相比 MySQL 等傳統數據庫要簡陋得多。官方文檔是入手 TiDB 的必讀資料,但是,僅僅依靠官方文檔是不充分的。最好能聯繫官方同學或者各地的 TUG 組織獲得支持。

TiDB 服務器硬件實踐經驗

從我們過去近兩年實踐經驗看,TiDB 是否能在生產環境運行穩定,硬件規劃是至關重要的先決條件之一。其中,硬件規劃最重要的環節包括兩個:

  • **存儲設備規劃。**TiDB 官方建議使用 NVME 協議的 SSD,時至今日(2020 年 1 月 14 日),主流的服務器 NVME 協議接口已不再是 pcie 口,而是 u.2 口。這個是大家都知道的,本無需贅言。真正需要關注的是 SSD 的品牌、型號。我們建議選擇 Intel p4510 這一款 SSD,這款 SSD 的讀 IOPS 理論值達到 60 萬以上、寫 IOPS 理論值達到 8 萬以上,在生產實踐對比結果來看,是 TiDB 的最佳搭檔。

  • **網絡設備規劃。**服務器、交換機都採用萬兆網卡,比較簡單,但非常重要。

TiDB 相關軟件實踐經驗

tidb-server 優化經驗

tidb-server 可能發生性能異常的地方主要是 CBO 統計信息失效問題與索引設計不合理問題。這兩個點並非 TiDB 獨有的問題,MySQL、Oracle 等也有類似的問題。對於前者,建議對關鍵表定時做 analyze,以確保統計信息準確性。而索引相關的問題,根據常見的數據庫優化技巧處理即可。從 3.0 版本開始,TiDB 支持 SQL 查詢計劃管理功能(SQL Plan Management),對這類問題提供了另一套解決方案。

tikv-server 優化經驗

TiKV 第一個最常見的問題是內存消耗過多被 OOM kill 的問題。TiDB 3.0 以後對 TiKV 內存配置做了優化,官方推薦將 block-cache-size 配置成 TiKV 實例佔據總內存的 40%,我們在實踐中發現,40% 的參數值在數據庫壓力極大的情況下仍然可能會出現 OOM 現象,需要基於 40% 繼續往下調整才能找到與業務場景真正匹配的參數值。

TiKV 另外一個問題是樂觀鎖適配問題。Oracle、MySQL 採用悲觀鎖模型,事務在做變更之前需要獲取到行鎖,然後才能做變更,如果沒有獲取到行鎖,則會排隊等待。而 TiDB則相反,採用樂觀鎖模型,先更新記錄,在提交事務時,再做鎖衝突檢測,如果衝突了,則後提交事務的會話會報錯 Write Conflict 錯誤引起應用程序異常。這個錯誤需要從 2 個方向進行處理。在 TiDB 3.0 版本下,默認關閉了事務提交重試功能,需要手工設置 tidb_disable_txn_auto_retry 參數,才能打開事務失敗重試功能。另外,TiDB 的樂觀鎖模型決定了其不擅長處理事務衝突較大的場景,比如典型的“計數器”功能,這類場景最好將技術器功能放到第三方軟件來實現會比較合適(比如 Redis)。另外,從 3.0 版本開始,TiDB 已經開始支持悲觀鎖功能,這個功能預計在 4.0 GA,我們也開始了這一塊的測試工作。

DM 實踐經驗

到目前爲止(2020 年 1 月 14 日),DM 仍然沒有發佈高可用機制版本,官方正在緊鑼密鼓實現高可用機制,我們建議將 TiDB 用做歸檔場景作爲實踐 TiDB 的起點,而不將其作爲最終的目標。實踐 TiDB 的目標是將 TiDB 作爲對前臺應用提供 OLTP 服務的數據庫。

使用 DM 的關鍵是有效規避 MySQL 到 TiDB 同步的異常問題,使同步能持續穩定運行。對於剛接觸 TiDB 的同學而言,建議從最簡化的方式使用 DM:

  • 保持 MySQL 到 TiDB 同步的邏輯結構一致。也就是說,MySQL 裏的庫表是什麼樣子,DM 同步到 TiDB 就是什麼樣子。不做分表聚合。分表聚合長期實時同步有其本質困難,不適合作爲初學者的目標。

  • 語法預驗證確保兼容性。TiDB 與 MySQL 是“高度兼容”的,但沒有人能承諾 100% 兼容(其他數據庫也一樣不敢誇口 100% 兼容 MySQL)。也就是說,如果一些生僻的 SQL 語句在 MySQL 上執行成功了,通過 DM 同步到 TiDB,可能會執行失敗,引起同步中斷異常。這類問題的最好解決方法是先將變更的 SQL 語句在測試環境 TiDB 執行一遍,確保正確後再到生產環境的 MySQL 執行。

TiDB 熱點數據優化實踐經驗

TiDB 根據表主鍵 ID 做 range 分區,將數據拆分到各個不同的 region 內。當某個 region 的數據量達到最大 size 限制後,將會進行分裂。感性來看,一旦某個 region 分裂成兩個 region 後,讀寫壓力也會拆分到兩個不同的 region。但是,假設一種場景,當我們不斷對一張表進行 insert 操作,而且這張表是自增主鍵。那麼,應用插入的數據永遠會落在該表 range 範圍最大的 region,永遠處於“添油戰術”的狀態,最大 range 範圍的 region 所在的 TiKV 實例一直處於高負載,整個 TiKV 集羣的壓力無法均攤下去,出現瓶頸。

這類場景在跑批應用中比較常見。我們的優化實踐建議如下:

  • 確保表主鍵是整形類型。

  • 確保表主鍵離散隨機生成,而非自增。

通過以上兩種機制能確保批量 insert 操作的寫壓力隨機分攤到各個 region 中去,提升整個集羣的吞吐量。

關於 Cloud TiDB 技術方向引子

坊間傳言我們是國內第一家將所有 TiDB 都運行在 Kubernetes 容器雲上的(金融)企業。我們地處西南,平日疏於與業界優秀數據庫同行交流心得,是否第一不得而知,但我們的 TiDB 確實都運行在 Kubernetes 容器雲上。

將 TiDB 全部運行到容器雲上主要是爲了提升軟件部署密度,充分利用服務器硬件資源,爲日後大規模部署 TiDB 集羣打下基礎。

根據我們的實踐經驗,基於物理服務器部署 TiDB 集羣,至少 6 臺物理服務器( pd-server 與 tidb-server 混合部署)起才能部署好一套生產環境 ready 的集羣。

當我們將 TiDB 全部遷移到容器雲平臺後,最小 TiDB 集羣資源從 6 臺服務器降低成了 2 pods tidb-server、3 pods pd-server、3 pods tikv-server,硬件成本降低爲原來的 30% 左右。

馬上金融 TiDB 項目未來展望

到目前爲止,我們對 TiDB 技術的儲備已經持續了近 2 年時間。我們積累了賬務歸檔、總賬跑批等大數據量、高併發量的 TiDB 實踐經驗。我們還將所有 TiDB 運行到了 Kubernetes 容器雲平臺之上,使數據庫真正獲得了 Cloud-native 能力。

未來,我們將探索更多適用於 TiDB 的核心業務場景,提升 TiDB 在公司內基礎技術棧的覆蓋面,尤其對 TiDB 即將正式推出的 True HATP 功能充滿了期待。我們將繼續深度使用 TiDB,使其爲消費金融行業賦能增效增效,共同創造更深遠的社會價值。
在這裏插入圖片描述

發佈了250 篇原創文章 · 獲贊 280 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章