TiDB 在平安核心系統的引入及應用

做者:何志勇
本文轉載自公衆號「平安科技數據庫產品團隊」。mysql

2019 年 5 月 9 日,平安科技數據庫產品資深工程師何志勇在第十屆數據庫技術大會 DTCC 上分享了《TiDB 在平安核心系統的引入及應用》,經過對 TiDB 進行 POC 測試,詳細解析如何選擇適用於金融行業級別的開源分佈式數據庫,以及平安「財神節」活動中引入 TiDB 的全流程應用實踐案例分享。本文根據演講內容整理。

<center>何志勇 平安科技數據庫產品團隊 資深工程師</center>redis

1、TiDB 引入的 POC 測試

做爲一名運維人員,引入一個新的數據庫產品前必需要明確幾點:spring

  • 從業務的角度,引入的產品可否知足業務基本需求和使用場景。
  • 從運維管理角度看,這產品必須是可運維、可管理的,而且咱們須要對其相應的功能與特性,要有一個很好的瞭解。
  • 產品性能穩定。

因此在咱們引入前從如下六個方面分別對 TiDB 進行測試驗證,其中功能與架構、配置與管理、備份與恢復都是針對咱們運維管理,SQL 特性、基準測試、應用場景測試則是應對業務需求和業務場景的。sql

1. 功能與架構

TiDB 事務隔級別爲 SI,支持 Spark 生態,支持動態擴容,跨數據中心部署。數據庫

這是 TiDB 官網最新的架構圖:編程

從左至右看,能夠經過 MySQL 或 MySQL 客戶端接入 TiDB,TiDB 有 TiDB、PD、TiKV 三個組件,組件之間功能相互獨立,需獨立部署,分別負責計算、調度、存儲功能;同時又相互協做,共同完成用戶請求處理。在 TiKV 層各節點是使用 Raft 協議保證節點間數據的一致性,同時它還提供 Spark 接口供大數據分析。 服務器

從上往下看,可經過 Data Miaration 工具從 MySQL 遷移到 TiDB,同時提供備份恢復功能、內部性能監控監測及診斷、支持容器化部署。多線程

TiDB 從架構及生態上基本上具有了傳統數據庫應有的功能。架構

2. SQL 特性

兼容 mysql 語法,2.0 版本不支持窗口函數、分區表、視圖、trigger 等。併發

3. 配置與管理

支持在線 DDL,2.0 只支持串行的 DDL、不支持併發,在優化器上支持 RBO 與 CBO,能對單會話進行管理,能夠支持複雜的 SQL。

4. 備份與恢復

備份恢復工具均爲開源,支持多線程備份恢復,當前版本不支持物理備份,loader 恢復時間偏長。

5. 基準測試

TiDB 在單條 SQL 的性能較好,高併發場景下性能較穩定,但 DML 事務大小有限制。

6. 應用場景測試

支持標量子查詢,能支持很是複雜的查詢,查詢引擎可朔性強。

這個應用場景是咱們的產險的實際分析場景,表數據量不大可是 SQL 較爲複雜,是典型的星型查詢。在 Oracle 用了 134 秒,可是 TiDB 用了 50 分鐘,咱們以爲很詫異,與 TiDB 的同事諮詢後,他們經過現場支持咱們優化底層代碼後 34 秒能夠跑出來。

2、「財神節」活動中 TiDB 的應用實戰

「財神節」是中國平安綜合性年度線上金融狂歡節。2019 年平安集團「財神節」活動於 1 月 8 日正式啓動,涉及壽險、產險、銀行、養老險、健康險、普惠、證券、基金、健康互聯、陸金所、壹錢包、互娛、不動產等多個領域,活動參與的 BU 數量與推廣的力度是歷年之最。單日成交額超過 1000 億,在單日交易額破千億背後是幾百個後臺數據庫實例的運維保障。

咱們看下活動業務場景的特色:

  • 參與門檻低:暖寶保這個業務保費價格低至 19.9,因此人人均可以參與。
  • 咱們的推廣力度很大:以微服務的方式對接如平安健康、好福利、平安銀行、陸金所等全部 APP 端,同時配合各類合做夥伴的宣傳。
  • 典型的互聯網活動形式如秒殺、紅包雨,因此對數據庫的要求是高併發、低延遲、高響應、高可用,2-5 年在線數據存儲量預計達到 20~50TB,而這些只是預估,有可能遠遠大於以上評估值。

平安在用的開源數據庫有不少,那在這麼多數據庫中,咱們選擇什麼數據庫呢?

綜合對比考量最終咱們選擇 TiDB,在選擇的同時也面臨着挑戰:

  • 時間緊迫

    2018 年 12 月 17 日~2019 年 1 月 7 日,20 天時間內完成開發測試到生產上線,時間短,風險大

  • 開發零使用經驗

    現有開發大都是基於傳統 Oracle 保險業務,對於 TiDB 沒有使用經驗

  • 併發量與擴容

    互聯網業務併發需求前期不可徹底需求,前期不能很好的以實際壓力進行測試,與資源準備

  • DB 運維管理

TiDB 還處於生產落地階段,一類系統還沒有使用過 TiDB,沒有大規模應用運維經驗

基於以上挑戰,咱們在 9 臺 PC 服務器上作了驗證測試,測試工具是 jmeter,TiKV 節點數咱們是逐步增長的,具體的測試過程以下:

總結一下,就是:

  • TiDB 吞吐:在 select 中即 point select,TiDB 的吞吐比較好。
  • 彈性擴容:在 insert 場景下隨着節點數的增長,TPS 也會相應的增長,每增長 3 個節點 TPS 可提高 12%~20% 左右,同時在相同 TiKV 節點數下,TPS 與響應時間,此消彼長。
  • 批量提交性能尤佳:業務中一個保單須要同時寫 7 個表,7 個表同時 commit 比單表 commit TPS 高,相同 TPS 場景下延遲更小。
  • 初始化 region 分裂耗時長:因在測試時沒有預熱數據(表爲空表),對空表寫入前幾分鐘,響應時間會比較大,約 5~8 分鐘後響應時間趨於穩定。在前幾分鐘內響應時間大,是由於每一個表初始化完都是一個 region,大量 insert 進來後須要進行分裂,消耗時間比較大。
  • Raftstore cpu 高問題:因爲 Raftstore 仍是單線程,測試中從監控指標看到 CPU 達到瓶頸是raftrestore 線程。
  • TiKV 性能中的「木桶原理」:TiKV 中一個節點的寫入性能變慢會影響到整個集羣的 TPS 與響應時間。

上線時咱們作了如下兩方面改善:

1. 優化表的定義與索引

表定義:不使用自增加列(自增加的 rowid)做爲主鍵,避免大量 INSERT 時把數據集中寫入單個 Region,形成寫入熱點。

索引:使用有實際含義的列做爲主鍵,同時減小表沒必要要的索引,以加快寫入的速度。

2. 對錶的 region 進行強制分裂

查找表對應的 region:curl http://$tidb_ip:$status_port /tables/$schema/$table_name/regions

使用 pd-ctl 工具 split 對應表的 region:operator add split-region $region_id

打散表的隱式 id,打散表的數據分佈:alter table $table_name shard_row_id_bits=6;

咱們使用了 25 臺機器,後面還臨時準備了 10 臺機器去應對高併發的不時之需。

在使用過程當中遇到以下問題:

(1) 2.0.10 版本下 in 不能下推到表過渡問題

你們看到咱們兩個相同的表結構,同時寫入一些數據,在兩個表進行關聯的時候,發現過濾條件 t1.id=1 時,上面那個執行計劃能夠下推到兩個表進行過濾,兩個表能夠徹底精準的把數據取出來,可是下面把等號後改爲 in 的時候,對 t2 表進行全表掃描,若是 t2 表數據量很大時就會很慢,這是 TiDB 的一個 bug,解決方案就是不要用 in,在 2.1 版本修復了這個 bug。

(2) 2.0.10 下時區設置致使客戶端不能連

咱們在跑命令的時候沒有問題,而且結果是能夠的,可是跑完後就斷掉了,從後臺看也是有問題的,重啓 TiDB 組件也不行,後來找到代碼咱們發現這是一個 bug。

緣由:這個 bug 會在你鏈接時 check 這個時區,致使用戶不能鏈接。

解決辦法:咱們找研發同事從新編譯一個 tidb-server 登入服務器,把時區設置爲正確的,而後使用最初的 TiDB 組件登陸,2.1 版本後這個 bug 修復。

(3) Spring 框架下 TiDB 事務

image

這個問題是比較重要的問題,有個產品須要生成一個惟一的保單號,業務是批量生成的,當時在 TiDB 中咱們建了一個表,表中只有一條數據,可是咱們發現會有重複保單號出來。

緣由:TiDB 使用樂觀事務模型,在高併發執行 Update 語句對同一條記錄更新時,不一樣事務拿的版本值多是相同的,因爲不一樣事務只有在提交時,纔會檢查衝突,而不是像 Oracle、MySQL、PG 那樣,使用鎖機制來實現對一記錄的串行化更改。

解決辦法:Spring 開發框架下,對事務的管理是使用註解式的,沒法捕獲到 TiDB commit 時的返回狀態。所以須要將 spring 註解式事務改爲編程式事務,並對 commit 狀態進行捕獲,根據狀態來決定是重試機制,具體步驟:

  • 利用 redis 實現分佈式鎖,執行 SQL。
  • 捕獲事務 commit 狀態,並判斷更新成功仍是失敗:

    • 失敗:影響行數爲 0 || 影響行數爲 1 && commit 時出現異常。
    • 成功:影響行數爲 1 && commit 時無異常。

相關文章
相關標籤/搜索