股份制銀行網際網路理財場景中 TiDB 的選型和應用適配實戰

TiDB_Robot發表於2020-05-28

作者:鄒建偉,北京開科唯識技術有限公司 技術專家。

一、網際網路理財的興起

在經濟和科技飛速發展的趨勢下,相比於以前傳統的線下理財模式,網際網路理財的模式,因其入圍門檻相對較低,選擇範圍廣,加上隨時隨地用電腦或者手機就能夠進行理財,導致便捷性和靈活性的提升,從而讓越來越的人們開始接受理財、樂於理財,理財的意識和投入的形態也越來越多。但隨著監管制度的管控、使用者規模、渠道規模、業務形態、高併發業務請求的不斷增長和變化,傳統的理財 IT 基礎設施建設已經無法滿足使用者的使用體驗,基於分散式系統建設新的業務系統必將破浪前行。

這次我們在中國某大型股份制銀行—— G 行的網際網路理財系統建設中,也是採用了分散式的資料庫系統來取代傳統 Oracle 資料庫系統,在使用分散式資料庫 TiDB 時,遇到了新技術適配的一些問題,通過遷移、開發改造和聯調優化,積累了網際網路理財場景中的一些分散式資料庫 TiDB 的經驗。本篇文章分享下在建設中遇到的問題和最終的解決方案,希望對所有準備建設和正在建設網際網路理財系統的的使用者有所幫助。

二、網際網路理財業務簡介

網際網路理財最早於 2003 年就已經開展業務,主要承載基金代銷、理財銷售等線上業務,2018 年 4 月隨著 “資管新規” 的釋出,銀行理財產品起售點由 5 萬下調至 1 萬,大大促進了銀行資管理財業務的發展,更加激發了客戶購買理財產品的熱情,部分明星熱銷產品,更是吸引了大量客戶集中搶購。G 行網際網路理財系統主要涉及兩大類業務場景:

  • 聯機交易場景 :處理開戶申請請求,對單筆交易的響應時間有較高的要求;
  • 批量任務場景 :處理理財批量業務,屬於計算密集型的工作,對資料庫大資料量下的吞吐能力要求較高。

2.1 業務功能拓撲

網際網路理財系統主要包含檔案傳輸、實時開戶、交易確認、份額登記、收益結轉、產品管理、產品運營等功能,拓撲圖如下:

業務對資料庫處理能力提出了明確的技術指標要求:

  • 批量任務:要求資料庫提供在 2h 內對 5000w 筆交易記錄,能夠跑完夜間批量任務的能力。
  • 聯機任務:要求資料庫提供事務平均響應延時不超過 100ms 的能力。

2.2 資料儲存拓撲

同城兩中心

整套叢集伺服器使用接近 30 臺物理伺服器,每臺物理伺服器均配置 4 塊 NVMe 盤、2 個萬兆網路卡、2 個千兆網路卡、72vcore、512G 記憶體,預期可以保留 3 個月的線上資料。

三、選型之路

3.1 背景與依據

在傳統理財業務系統使用集中式的 IOE 架構,原有傳統資料庫 Oracle 資料庫遇到支撐的瓶頸,已無法適應網際網路 + 理財業務模式的發展需求, 取而代之的是通過開源自主可控、分散式資料庫的技術方案來支撐當下的網際網路技術模式的系統建設,現有 Oracle 主要遇到亟待解決的的問題如下:

  1. 容量上限不能擴充套件 (存不下、查不出來,索引優化已沒有用)。

  2. 分散式改造和適配如何取捨。

在當前分散式資料庫解決方案領域內,可以聚焦的資料庫選擇範圍就剩下分庫分表方案 和 NewSQL 原生分散式方案(順帶的說明下,這裡我們不爭論分庫分表究竟算不算分散式架構,我們相信技術是為場景存在的)。選型我們主要考慮三點:首先是資料庫功能,例如括高可用性、SQL 相容、橫向擴充套件、擴容等等;其次是技術架構的前瞻性、發展潛力、社群活躍度;最後是大資料量下的資料庫效能最為看重。前期我們與候選的資料庫廠家的工程師合作模擬了 daemon 業務程式,來驗證資料庫的效能,主要兩個部分內容:

  1. 資料初始化能力

來自網際網路渠道的理財資料,預估每小時至少千萬級別,在 1 個小時內我們有一系列的批量任務,留給資料庫入庫的時間最多 10 分鐘。

  1. 業務效能測試

理財業務具有多工並存的特點,大方向說包括聯機交易任務和跑批任務兩部分,跑批任務包括日間任務和夜間任務以及數倉 edw 任務。聯機任務要求事務平均響應延時不超過 100ms,批量任務即使並存時也不可以超過總體執行時間。

經過多輪的測試、評審,分庫分表對業務設計上的不解決夠優雅,由於拆分欄位的規則限制了業務實現的一些方式,不能靈活進行業務處理,並且在批量的複雜邏輯 SQL 處理上效能無法滿足業務要求,最終我們選擇 TiDB 來進行分散式資料庫的建設。驗證下來,完全滿足業務資料初始化效率、提升聯機交易和批量處理響應能力、縮短批量處理時間週期,而且也無需限制業務場景的處理邏輯,根據壓力需求靈活的進行線上擴充套件和線上收縮。上線前的非功能測試中,聯機交易部分:在併發使用者 30 下,資料庫處理能力為 536 筆/s,響應時間為 0.0558s,滿足預期 200TPS。批量入庫:64 併發下,5kw 資料入庫 9.7min,當然這並非極限值。

3.2 TiDB 的特性優勢

水平彈性擴充套件

這裡說的水平擴充套件包括兩方面:計算能力和儲存能力。TiDB Server 負責處理 SQL 請求,隨著業務的增長,可以簡單的新增 TiDB Server 節點,提高整體的處理能力,提供更高的吞吐。TiKV 負責儲存資料,隨著資料量的增長,可以部署更多的 TiKV Server 節點解決資料 Scale 的問題。

高可用

TiDB 叢集核心三大元件:TiDB/TiKV/PD 都能容忍部分例項失效,不影響整個叢集的可用性。TiDB 本身是無狀態的,支援動態的增加刪除。TiKV/PD 採用 Raft 協議,在大多數存活的前提叢集便是可用的。

資料強一致

TiDB 的分散式演算法使用 Raft,其事務可以跨分片、跨節點執行,並且強一致。

生態強大

這個特點應該毋庸置疑,說是 “風口的豬” 也不過分。TiDB 分散式資料庫從 2015 年 4 月份開源以來,有來自社群的開發者、使用者、佈道師、設計師等不同角色的貢獻者們的細心呵護,也有來自 PingCAP 持續不斷的資源投入,截止到 2020 年 3 月,TiDB 社群專案已經聚集了來自全球的 760 多位 Contributor,100 多位核心使用者,30000+ GitHub Stars 支援,TiDB 現已被近 1000 家不同行業的領先企業應用在實際生產環境。TiDB 詳細的架構和原理可以參照官網(不再贅述)

四、開發改造中的思考&問題

G 行採用的 TiDB 版本是 3.0 早期版本,僅提供樂觀鎖機制, 這個問題在 TiDB 3.0.8 後引入了悲觀鎖後得到了解決。作為一名 “重度” 悲觀鎖使用者,TiDB 的樂觀鎖是我剛開始接觸 TiDB,所認為的開發改造過程中最大 “阻礙”。但實際開發過程中,這裡的碰到的問題其實很少,更多是認知理解的過程。整個改造過程中主要遇到了以下幾個方面的問題,也都通過 TiDB 提供的最佳開發實踐獲得了很好的處理效果。

問題 1:熱點賬戶更新

select for update 語句是悲觀鎖機制下熱點賬戶更新場景常被利用的機制,Oracle 資料庫中,這個語句的作用是:

The FOR UPDATE clause lets you lock the selected rows so that other users cannot lock or update the rows until you end your transaction.

也就是說利用它可以實現資料行的鎖定,阻塞其它事務對該行資料的 DML 操作。TiDB 也支援這個語句,不過在樂觀鎖機制下,這個語句不會在事務開啟就鎖住資料,而是其他事務在提交的時候進行衝突檢查,如有衝突,會進行回滾。

問題 2:Rows Affected 不可信

悲觀鎖機制下,顯式事務每條 DML 語句執行完成後資料庫會返回影響行數:affect rows,業務會利用 affect rows 實際值不同進行不同的邏輯處理,這個是沒問題的。不過 TiDB 樂觀鎖機制,顯示事務每條 SQL 執行完成後返回的 affect rows 是不可信,究其根本原因,悲觀鎖是先加鎖再更新,而樂觀鎖機制下,行衝突檢測和資料上鎖是放在事務提交時檢測的,這裡舉一個例子:

對於事務 B 來說,update 語句執行後資料庫返回 1 row affected,不過顯而易見,這個語句提交時並沒有發生更新,也即此時的 Affected rows 是不可信的。如果業務還希望使用 affected rows 來做程式執行邏輯的判斷條件,可行的方式是:顯示事務下,先判斷事務成功的條件,然後再根據 affected rows 進行邏輯處理。而隱示事務下,可以直接使用 affected rows 進行邏輯處理。

問題 3:大事務

熟悉 MySQL 的同學會對事務大小設計比較熟悉,開發規範中會盡可能拆分大事務為多個小事務。TiDB 對大事務也有類似的要求,並給出了限定具體限定標準:

  • 每個事務內的 SQL 數量不超過 5000 條(可配置)。
  • 每個鍵值對不超過 6MB。
  • 鍵值對的總大小不超過 100MB。
  • 鍵值對的總數不超過 300,000。

開發使用過程中,體會最多的限制是鍵值對的總數不超過 300,000,老系統稍不注意就超出了這個限制,造成處理失敗。這裡要著重說明,鍵值對數與行數不等價。舉例說明:一行資料是一個鍵值對,一行索引也是一個鍵值對,當一張表只有 9 個索引時,每 insert 一行資料會寫入 10 個鍵值對。這裡的原因涉及到 TiKV 使用的儲存格式,感興趣的同學可以搜尋 TiDB 相關文章進一步閱讀。

問題 4:WRITE CONFLICT

WRITE CONFLICT 是開發中碰到的頻率最多的問題之一,報錯示例資訊:

Err:[kv:9007]Write conflict, txnStartTS=411771139330670593, conflictStartTS=411754809751764993, conflictCommitTS=0, key={tableID=698, handle=391317290} primary={tableID=698, indexID=5, indexValues={0, 391317246, }} [try again later], ErrCount:313, SnapshotVersion:411752587989614594

問題的成因這裡不贅述,感興趣的同學可以搜尋相關文件檢視。TiDB 預設針對這個錯誤不會進行事務重試,由引數 tidb_disable_txn_auto_retry 控制,3.0 版本預設值是 1,而在更早的 2.1 版本里沒有這個引數,預設行為是會自動重試,預設值更改的原因是優化事務處理邏輯,適應更多場景。

五、總結

目前網際網路理財業務系統穩定的執行在 TiDB 3.0 版本樂觀鎖下,TiDB 4.0 馬上要 GA 了,我們當初能趕上基於 4.0 的改造該有多好啊,據說 4.0 版本有了更多的新特性 ,讓後續遷移到 TiDB 資料庫的同學會更加的通用、易用。比如:

4.0 有了大事務

對於開發人員說,TiDB 4.0 以前事務的限制始終有點「達摩克利斯之劍」的意味,總是擔心一個不留心就撞牆。4.0 版本開始,對事務的限制鬆綁很多,鍵值對的總大小允許 10GB 以內。

有了悲觀鎖

相比大事務帶來的彆扭,悲觀鎖個人覺得是最期待的特性。最早在 TiDB 3.0.8 版本引入,4.0 版本開始預設開啟悲觀鎖。悲觀事務模型是對於金融場景非常重要的一個特性,有了悲觀鎖我相信 TiDB 才會走的更高更遠。

新特性很期待

TiDB 4.0 GA 版本即將釋出,除了本文涉及的大事務、悲觀鎖等等還有很多新特性,例如 Sequence、Key VisualizerFollower Read等等,有興趣的同學可以官網檢視相關文章。

更多 TiDB 實踐案例閱讀:案例 | PingCAP

關於 TiDB 使用上的問題可以登入可以在 TiDB 使用者論壇 Asktug.com 交流探討~

更多原創文章乾貨分享,請關注公眾號
  • 股份制銀行網際網路理財場景中 TiDB 的選型和應用適配實戰
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章