如何構建企業內的 TiDB 自運維體系

得物技術發表於2022-12-20

1. 前言

得物 App 從創立之初,關係型資料庫一直使用的開源資料庫產品 MySQL。和絕大部分網際網路公司一樣,隨著業務高速增長、資料量逐步增多,單例項、單庫、單表出現效能瓶頸和儲存瓶頸。從選型和架構設計角度來看這很符合發展規律,一開始沒必要引入過於複雜的架構導致資源成本和開發成本過高,而是逐步隨著業務發展速度去迭代架構。為了應對這些問題,我們採取了諸多措施如單庫按業務邏輯拆分成多個庫的垂直拆分,分庫分表的水平拆分、一主多從讀寫分離等。這些技改同時也使得整個業務層架構更加複雜,且無法做到透明的彈性,因此我們逐步把目光轉向了已經趨於成熟的分散式關係型資料庫 TiDB。

自 2020 年初開始使用 TiDB,隨著運維體系的逐步完善,產品自身能力的逐步提升,接入業務已經涉及得物的多個 業務線,其中個別為關鍵業務場景。業界關於 TiDB 的功能剖析、場景落地、平臺化建設都有很多優秀的文章。本文基於得物內部的實踐情況,會從選型策略、運維手段、運營方式、核心場景實踐等幾個方向講述TiDB 在得物實踐落地過程。

2. TiDB 架構

上圖是我們目前的接入方式和整體架構。TiDB 的部署架構這裡就不做贅述了,需要了解的同學可以參考官方文件。我們之所以採用 SLB 來做 TiDB 的負載均衡接入,就是為了簡化接入成本與運維成本,訪問流量的負載均衡以及節點擴縮容可以透過調整 SLB 解決。當然如果能夠實現 SDK 負載均衡與故障剔除,結合配置中心的流量排程也是非常好的解決方案。得物 TiDB 部署均採用單機單例項部署,TiDB Server、PD 採用無本地 SSD 機型,TiKV 採用本地 SSD 機型。既兼顧了效能,又能降低成本。詳細的機型選擇會在後面的內容提到。

3. MySQL 與 TiDB 的對比

圈內一直流傳著一句話,沒有一種資料庫是"銀彈"。絕大部分使用者選擇 TiDB 就是為了彌補 MySQL 的不足,所以選型階段對兩者做些比較也是在所難免的。本文基於我們內部的現狀和場景對兩個產品我們關注的點進行了簡要對比。對比的目的不是為了去印證那個資料庫產品能力更強。而是想透過對比來幫助團隊在合適的場景選擇合適的產品。

  • 擴充套件性

    • MySQL

    MySQL 就自身擴充套件能力而言主要是來自於垂直擴容,但是這個會受限於機器的規格上限。水平擴容涉及業務改造和使用成本提升。改造為分庫分表,對研發來說是一個費力度很高的方案。需要引入 Sharding 邏輯,改造完成後需要業務 SQL 必須帶 Sharding Key 才能執行或者高效執行。所以並不是說做不到可擴充套件。

    • TiDB

    由於 TiDB 是計算儲存分離的架構,且有狀態的儲存層 TiKV 是分散式儲存。所以單從上面定義的擴充套件性來說,確實對比 MySQL 有很大優勢。叢集處理能力和儲存能力,可以透過擴容 TiDB Server、TiKV 簡單實現。這裡需要注意的是,TiKV 屬於有狀態服務,擴容會涉及到資料的 Reblance,過程中 TiKV(region 遷移) 和 PD(排程) 產生大量互動,為避免影響業務,擴縮容過程中需要關注叢集情況,根據需求適當調整遷移力度。

  • 效能

    • MySQL

    關於 RT。MySQL 由於是單機資料庫,所以對於點查或簡單查詢的 RT、熱點更新的 RT 與 TPS ,相比分散式資料庫有天然優勢。資料獲取鏈路短(單機資料庫本地呼叫,分散式資料庫涉及存算分離),且不用考慮分散式事務的衝突檢測。所以總體的訪問 RT 要低於 TiDB,具體資料這邊就不羅列了,社群有不少效能壓測的帖子。

    關於聚合查詢。網際網路公司在 C 端基本不存在此類問題,也是不允許的。所以主要是場景在 B 端。解決方法一般是分為幾種:1.提供專門的只讀例項給 B 端提供查詢能力;2.異構資料來解決(MySQL+ES、ADB 等等)。

    關於最佳化器。MySQL 多年的積累,在最佳化器的穩定性雖然不如商用資料庫那麼可靠,偶爾也有走錯索引的情況。一般只能透過修改 SQL、修改索引來解決,切記別用 force index 這種有坑的解決方案。但是總體來說我們遇到的 MySQL 走錯索引的情況要遠低於 TiDB。

    • TiDB

    關於 RT。分散式資料庫解決的更多是吞吐量和容量上的需求,比如點查或簡單查詢的 RT 無法像單機資料庫那麼短,但是可以透過節點擴容的方式提升 QPS 吞吐量。熱點資料這裡就不展開講了,它本身也不是分散式資料庫能解決的範疇。如果你的業務場景是一個對 RT 要求很高的場景,那麼優先使用 MySQL。如果是高吞吐量需求優先,可以嘗試使用 TiDB。

    關於聚合查詢。由於 TiDB 的儲存節點 TiKV 不只是具備儲存能力,TiKV 實現了coprocessor 框架來支援分散式計算的能力。所以理論上透過加機器就能擴充套件計算能力,從我們實際使用的場景來看也是如此,這部分的能力就要優於 MySQL。具體的效果在本文最後的章節會有體現。

    關於最佳化器。這個是大家對 TiDB 一直以來吐槽的點之一,有時候統計資訊健康度 90 以上的情況下,還是會走錯索引,當然這裡有一部分原因可能是條件過多和索引過多導致的。為了解決問題,核心服務上線的 SQL 就必須一一 Review。如果無法正確使用索引的就使用 SPM 繫結,雖然能解決,但是使用成本還是略高。希望官方繼續加油。

  • 資源成本

    • MySQL

    如果是一個資料量小且查詢模型比較簡單的需求(比如:1-2TB,簡單查詢為主),那麼肯定是 MySQL 成本較低。以我們 TiDB 基礎配置為例,相比 MySQL 成本高出 27%(該成本是用高可用的 MySQL 對標3 TiDB、3 TiKV、3 PD 的 TiDB)。所以得物內部選型,單從資源成本角度考慮,還是首選 MySQL。

    TiDB如果是一個資料量較大且持續增長或查詢模型比較複雜的需求(比如:3-5 TB 以上,多條件查詢、聚合查詢等)。一般該型別的業務都採用分庫分表的解決方案。以得物一個分庫分表的叢集(10個寫例項、10個讀例項)為例,替換為 TiDB(6 TiDB、12 TiKV、3 PD),成本相比 MySQL 成本節省 58%。此例子只作為得物一個業務場景的替換結果,不代表所有場景。為了驗證這個結論,本文後面的內容會講到這個核心場景的實踐。

  • 運維成本

    • MySQL

    MySQL 作為被使用最多的開源關係型資料庫,從社群活躍度、產品成熟度、周邊生態工具、解決方案積累等方面來看都是非常優先的產品。主從架構的 MySQL 維護成本極低,當主庫異常或無法修復時,我們只需要切換即可。

    另外得益於優秀的社群生態,運維工具、資料庫接入元件、資料同步元件都有非常多的成熟工具,稍加改造就可以實現本地化適配。

    • TiDB

    分散式的架構的設計沒有像 MySQL 這樣的主從,每個儲存節點都是提供讀寫。當一個節點出問題的時候,會影響整個叢集的訪問。無法實現 MySQL 這樣透過主從切換實現快速的故障隔離。

    TiDB 由 3 個角色組成,當出現問題的時候無法快速定位問題(當然也是我們個人能力需要提升的點),比如當某個時間點的查詢超過預期的時候,需要排查執行計劃、各個節點的負載情況、各節點的網路情況。雖然提供了完善的監控,但是指標與節點過多需要一一排查才能有結論。不像 MySQL 出現查詢超預期的問題,基本上透過幾個核心指標就能判斷出根因。

  • 結構變更(DDL)

    • MySQL

    這裡以我們主要使用的 MySQL 5.7 為例,較大資料量的情況下 DDL 成本較高,為了規避鎖表和主從延遲的問題,一般都是用工具去執行。我們通常使用的兩個知名開源無鎖 DDL 工具:Percona 開源的 pt-osc、Github 開源的 gh-ost。目前我們和大部分公司一樣都在透過定製化開發的 gh-ost 來變更。但是用工具只是解決了前面提到的鎖表和主從延遲問題,隨著資料量規模上升,變更時長也逐步上升。另外工具的 Bug 也會帶來資料丟失的風險。當然 MySQL 8.0 的特性 Instant Add Column 推出以後解決了加列的痛點,但是也只解決了一部分。

    • TiDB

    TiDB 的 DDL 透過實現 Google F1 的線上非同步 schema 變更演算法,來完成在分散式場景下的無鎖,線上 schema 變更。DDL 變更中除過 add index 以外其他都不需要做資料回填,修改完元資訊即可,所以可以立即完成。而 add index 會做兩件事情:1.修改 table 的元資訊,把 indexInfo加入到 table 的元資訊中去;2.把 table 中已有了的資料行,把 index columns的值全部回填到 index record中去。變更速度取決於表中的資料和系統負載。所以 TiDB 在 DDL 操作上解決了很多 MySQL 上的痛點,但是與 MySQL 相比,TiDB 的 DDL 還是有些不一樣的地方的,也帶來了一些限制:

    1. 不能在單條 ALTER TABLE 語句中完成多個操作。MySQL 下會把多個同一張表的 DDL 進行合併,然後使用 gh-ost 或者 pt-osc 工具一次性執行。TiDB 裡只能一個個單獨去執行;(6.2 已經支援了ALTER TABLE語句增刪改多個列或索引)
    2. 不支援不同型別的索引 (HASH|BTREE|RTREE|FULLTEXT);
    3. 不支援新增 / 刪除主鍵,除非開啟了 alter-primary-key 配置項;
    4. 不支援將欄位型別修改為其超集,例如不支援從 INTEGER 修改為 VARCHAR,或者從 TIMESTAMP 修改為 DATETIME,否則可能輸出的錯誤資訊 Unsupported modify column
    5. 更改 / 修改資料型別時,尚未支援“有損更改”,例如不支援從 BIGINT 更改為 INT;
    6. 更改 / 修改 DECIMAL 型別時,不支援更改精度 ;
    7. 更改 / 修改整數列時,不允許更改 UNSIGNED 屬性 ;

這裡大部分限制可以在結構設計階段和後期規範來規避掉,比如一個表的多個 DDL 操作無法合併的問題,可以透過自動化手段降低複雜度;BIGINT 更改為 INT 這種長改短的就是日常變更規範中要管控的。

  • 產品流行度

    • MySQL

    如果我們從 MySQL 1.0 開始算起至今已經有 26 年了。這期間幾經週轉,最終歸到了 Oracle 旗下。版本也從 1.0 來到了 8.0。作為一個久經錘鍊的資料,特別是作為網際網路盛行時期依賴的主流資料庫,不論是產品成熟度和社群活躍度都得到了極大的促進。MySQL 在 DB-Engines 的開源資料庫中排名久居第一。

圖片資料來源 DB-engines 官網

    • TiDB

    TiDB 從 2015 年創立並開源至今已經 7 年,作為一個複雜的基礎軟體來說確實還比較年輕。依賴早期的 3 個創始人網際網路背景出身,深知大家在關係型資料庫上的痛點。所以 TiDB 推出後獲得了不少使用者的推崇,特別是網際網路行業。社群在 TiDB 的發展中也起到了至關重要的作用,從打磨產品、需求提煉、落地場景總結等。目前 TiDB 在 DB-Engines 排名為 98,進一步證明了基礎軟體的難度以及作為一款國產資料庫在國際化程式中還有很大的空間。從墨天輪中國資料庫排行的情況,可以看到 TiDB 長期以來保持第一的位置。在 12 月跌落榜首,由 OceanBase 取代。

圖片資料來源 墨天輪

4. TiDB 在得物的運維體系落地及探索

4.1 選型

關於資料庫選型,我們一向非常謹慎,會根據具體的業務情況來推薦合適的資料庫。要避免陷入“手拿鐵錘的人,看什麼都像釘子”的誤區。不是為了使用 TiDB 而使用,要去解決一些 MySQL 無法滿足或者改造成本比較高的場景。關係型資料庫我們還是優先推薦MySQL。能用分庫分表能解決的問題儘量選擇 MySQL。畢竟運維成本相對較低、資料庫版本更加穩定、單點查詢速度更快、單機QPS效能更高這些特性是分散式資料庫無法滿足的。以下是我們總結的關於選型的兩個大方向。

適合接入的場景:

  • 分庫分表場景:上游 MySQL 分庫分表,業務查詢時無法使用到分片
  • 磁碟使用大場景: CPU 和記憶體使用率低但磁碟容量達到 MySQL 瓶頸
  • 分析 SQL 多場景:業務邏輯比較複雜,存在併發查詢+分析查詢
  • 資料歸檔場景:資料冷熱分離、定期歸檔、資料重要,不能丟失
  • 日誌流水場景:日誌流水業務、單表較大、寫入平穩、查詢不多

不適合接入的場景:

  • 資料抽取場景:下游存在大資料或者其他業務部門進行資料抽取
  • 讀寫分離的場景: TIDB 沒有主從的概念,無法進行讀寫分離
  • 指定點恢復場景:指定時間點級別恢復,需要恢復到某個時間點
  • 資料熱點場景:高併發單行更新、熱點小表、熱點庫存

4.2 運維標準化

  • 業務接入

場景:當業務選型考慮TiDB時,我們會根據業務的使用場景和業務特點綜合評估是否適合TiDB(優先 推薦使用MySQL)。

配置:評估業務成本壓力和未來一年資料量、TPS,選擇合適的TiDB叢集配置。

使用:給使用方提供 MySQL 和 TiDB 的差異及其規範,避免增加開發週期和成本。

  • 資源規格

根據不同業務場景,我們定義了不同的伺服器配置。由於藉助雲上的資源交付能力和隔離能力, 我們無需像 IDC 那樣,在高規格機器上採用多例項部署。這樣避免了混部帶來兩個問題:1.多個例項之間的資源爭奪;2.高規則機器部署密度與穩定性的權衡。

節點數量配置
TIDB3基礎規格:8C32G200GB(雲盤)高配規格:16C64G200GB(雲盤)
PD3基礎規格:8C16G200GB(雲盤)高配規格:16C64G200G(雲盤)
Monitor14C16G200GB(雲盤)
TIKV/TIFLASH3基礎規格:8C32G1788G(本地SSD)高配規格:16C64G1788G(本地SSD)
  • 資料庫備份

備份工具:BR[官方物理備份工具]

備份策略:凌晨低峰期進行資料全量備份

備份保留週期:7天

    • 線上業務

對於線上業務,除了常規的BR備份外會額外調整 tikv_gc_life_time 時間為 1-3 天,當業務出現誤操作時可以恢復三天內任意時間的資料。

    • 離線業務

TiDB叢集離線業務大部分是從上游RDS同步到TiDB的場景。上游RDS會有一份最近的資料,所以對於離線業務只有常規的BR備份。

4.3 穩定性治理

  • 變更管理

    • 面向 DBA 的流程管控

上圖的流程主要是用於管控非白屏化的 TiDB 基礎設施變更。透過變更文件整理、運維小組 Review 的機制,確保複雜變更的規範化。

    • 面向研發變更的系統管控DML\DDL 變更工單風險自動化識別

語法檢查:

  1. DDL 與 DML 型別判斷,確保每次執行的內容是同一個型別
  2. SQL 語法檢查,確保提交的 SQL 語法是正確的

合規檢查:

變更合規性檢查,確保提交的 SQL 是可以按照 DBA 定義的規範設計(可以使用的欄位型別、欄位命名、索引命名、索引數量,欄位長度由長修改短等限制),簡單說就是要麼允許,要麼不允許

風險識別:

  1. 該項的作用是將允許執行的進行風險識別,研發可以根據風險等級選擇執行時間,DBA 也能在審批階段判斷是否合理,並修改執行時間。
  2. 相關風險定義

下圖是基於以上提到的能力,實現的 TiDB 變更管控功能。

  • 穩定性巡檢

資料庫巡檢手段是相當於告警比較前置的一個動作,巡檢閾值相比告警較低,目的是為了提前發現問題並跟進解決。收益是:1.降低告警數量;2.避免小問題逐步積累導致大問題。我們的做法是按照自定義的評分規則,雙日晨會對焦,對有風險的服務進行問題跟進。

巡檢指標的資料採集來自於監控系統,我們會統計相關指標的峰值。每天記錄一個點,展示近 30 天內的指標值。

某叢集的巡檢情況

  • 慢查治理

雖然 TiDB 自帶的 Dashboard 可以提供慢查的白屏化,但是這需要提供賬號密碼給研發,5.0 之前的版本還必須使用 root 賬號登入,另外就是我們希望慢查治理可以結合內部系統進行管理。所以對於這部分做了些自研工作,將日誌採集並加工後存入 ES。DBA 平臺可以透過報表等手段進行推進治理。

下面兩張圖就是我們內部的平臺對慢查治理的閉環管理方案。DBA 或者研發 TL 在平臺指派 SQL,處理人就會收到治理訊息,處理完成後可以在後臺進行狀態變更。然後基於這些資料可以做報表最佳化治理效果。

  • 告警管理

基於 TiDB 官方的監控方案,我們在告警部分做了些定製化,Prometheus 中配置的 rule 觸發後會把告警資訊推送至我們自己的資料庫管理平臺 OneDBA,由平臺處理後進行傳送。平臺的告警管理模組的實現類似於 Alertmanager,不同的我們新增了自定義的需求,比如元資訊關聯、支援叢集指標級別的閾值定義、告警沉默、告警降噪、告警治理閉環(有告警通知和認領,確保及時跟進處理)。另外這裡的 Prometheus 主要功能是做資料採集與告警,資料儲存與趨勢圖檢視在公司統一監控平臺,降低不必要的儲存資源投入。由於我們管理的資料庫型別比較多,所以在告警方案上做了收斂。這裡講到的方案就是得物資料庫團隊目前針對負責的所有資料庫的管理方案。

閾值管理

  • 故障演練

故障演練的目的是為了鞏固目前的系統高可用。我們針對 TiDB 制定了一套故意演練流程,包含了 8 個場景。

【演練場景1】TiKV Server 1 個節點當機

【演練場景2】TiDB Server 1 個節點當機

【演練場景3】PD Server 1 個節點當機

【演練場景4】PD Server 節點重啟

【演練場景5】TiKV Server 節點重啟

【演練場景6】應用高併發寫入,CPU、IO告警是否及時傳送

【演練場景7】PD Server Leader、follow節點重啟

【演練場景8】TiDB 叢集 當機一個TiDB Server節點

以上的場景我們透過 ChaosBlade 實現了 100% 自動化故障注入。故障演練也促使我們達成整個技術部的目標:1 分鐘發現,5 分鐘止損,10 分鐘定位。目前也正在計劃將該流程引入新叢集交付前以及版本升級後的標準化流程。

4.4 人才儲備

  • 專業認證

PingCAP 目前有三個認證,分別是 PCTA、PCTP、PCSD。前兩個是早期推出面向 DBA 從業者崗位初高階認證。得物 DBA 團隊有 6 位同學獲得TiDB的 PCTA 認證考試、其中 5 位同學獲得了進階的 PCTP (TiDB專家)認證考試。認證雖然不能完全代表實力,但是代表了 DBA 團隊對技術的追求和 DBA 團隊在得物做好 TiDB 服務支援的決心與態度。

透過PCTP認證學習,團隊成員深入瞭解TiDB資料庫的體系架構、設計理念與各個元件的執行原理。學習並掌握 TiDB 資料庫的體系架構,設計實踐,效能監控、引數最佳化、故障排除、SQL最佳化和高可用設計。這個對於公司和團隊來說就是人才和技術上的儲備。


部分在職的 PCTP 得物 DBA 證書截圖

  • 運維小組

對自建資料庫服務我們採用了小組負責制,以 TiDB 為例,會有 3 名同學負責基礎設施運維的工作(資源評估、變更流程評估、二線問題處理等),其中一名是 Owner。關於日常業務側的變更、SQL 最佳化等由具體對接業務的 DBA 負責處理。這樣既解決了人員互備問題,又解決了變更風險評估問題,還解決了運維小組運維壓力的問題。

4.5 技術運營

對於一個新興資料庫,DBA 基於產品特性介紹、場景分析、案例分享等,在公司內部的技術運營也非常重要。它決定了研發同學對這個產品的認知和信心。好的技術氛圍一定是得益於公司內部完善的機制和平臺,同時你也能合理的加以利用。這裡沒有講到對外分享,是因為我們的原則是先內部沉澱修煉,然後再對外分享。以下是我們對於 TiDB 的技術運營在公司內部的 3 個主戰場。

  • 技術分享

技術夜校是得物技術部技術文化的特色之一。為技術部有意分享的同學提供一個平臺,就現有技術實戰經驗、技術研究成果、重點專案回顧等,在技術部與同學們做分享和交流,營造濃厚的技術分享氛圍,形成技術知識沉澱,打造學習型組織,提升技術影響力,拓寬技術同學的知識面。

這是一個能夠有力促進技術影響力和產品影響力的機會,我們當然也不能錯過。本文的作者在剛入職得物的時候就分享了《分散式資料庫 TiDB 的設計和架構》,培訓教室座無虛席,參與人次創下新高。這次分享讓研發對 TiDB 也有了一個全面的認識。所以技術分享一定程度上解決了前面說的產品能力認知問題。

  • 技術部落格

"毒"家部落格也是得物技術部技術文化的特色之一。初衷是為了各位同學們交流技術心得,透過輸入與輸出的方式促進進步、相互成長。很多高質量文章也被推送到了得物技術公眾號。

DBA 團隊藉助內部的技術部落格平臺,輸出了多篇有關 TiDB 的技術文章。內容涵蓋核心原理分析、最佳化案例、故障 case 分析、業務場景落地等。在整個氛圍的帶動下,不少研發同學也發表了關於 TiDB 的學習和落地的技術文章。

  • 課程錄製

組織內部的技術分享的投入較大,分享的頻次不宜太高,否則參與度也會比較低。而且從內容深度、知識獲取效率、自助學習來看,分享也不是長期的方案。錄製影片課程的事情就提上日程了,影片課程的好處是可以濃縮知識點,將技術分享 40 分鐘的內容(有一些不必要的內容,比如重複的話、口頭語等)壓縮至 15 分鐘。完美解決了前面提到的問題。正好公司內部有一個自研的學習平臺,日常就用於釋出各種培訓、學習的影片。為確保錄製效果和效率我們前期的課程都準備了稿件。我們基於這個平臺也釋出了一期( 5 節)課程,最近已經在籌備第二期的課程內容了。

課程錄製也可以使 DBA 再一次複習細節知識,因為要講清楚知識點,就必須自己深入理解。這個一定程度上表明瞭我們對 TiDB 的瞭解程度和做好它的決心,也給了研發使用的信心。

5. TiDB 在核心業務場景實踐

5.1 業務痛點

得物商家訂單庫由早期 MySQL 單庫進階到 MySQL 分庫分表,這個方案支撐了業務的高速發展。而以商家 ID 做 shareding-key,會使的同一個商家的訂單資料都會在一個表中,隨著訂單量的逐步提升,最終大商家的查詢會形成了單點效能問題。主要體現在慢 SQL 較多和 資料庫負載上升,每天約 1W 條慢 SQL,部分統計類查詢已經超 10S。另外就是單機容量也有上限,垂直擴容受限。隨著訂單量的上升,系統整體的效能和容量需要最進一步的規劃。

5.2 解決思路

基於以上提到的問題,我們對所有的解決方案都做了對比。表格中是對四種解決方案的關鍵資訊提煉。我們希望能夠選擇一個比較長期的方案,可以支撐未來 3-5 年的需求,既要解決效能問題,還要解決容量問題,又要比較低的研發成本。所以最終選擇了引入分散式資料庫的方案。

5.3 資料庫選型

基於目前得物在使用的資料庫進行了評估,主要包含以下三種選擇。

由於得物在 2020 年就引入了 TiDB。雖然沒有大規模推廣,但是陸續也有不少業務接入。大部分的業務把它作為 MySQL 分庫分表的聚合庫使用,有一小部分業務是直接接入了讀寫需求。基於之前的實踐經驗和業務需求,經過和研發團隊的協商,直接採用的讀寫庫的使用方案。另外一個方面是從只讀過渡到全量讀寫的週期會比較長,會產生不必要的並行成本和延遲專案時間。

5.4 相容性&效能測試

  • 相容性測試

SQL 相容性的問題,我們並沒有完全依賴後期的業務測試來驗證。而是透過獲取 MySQL 上的全量 SQL 的方式進行驗證。由於我們將全量 SQL 儲存在了 Clickhouse,並且儲存前做了SQL 指紋提取。所以很容易可以獲得去重後的業務 SQL。然後將所有型別的 SQL 樣本在 TiDB 中進行回放,這裡主要針對 Select。最終測試所有業務 SQL 100% 相容。

SQL 指紋

  • 效能測試

    • 單量較少的商家場景效能測試

和預期的結果一樣,由於 TiDB 分散式的架構,資料獲取路徑比 MySQL 要長,所以 RT 上相比 MySQL 分別多出 91%、76%、52%。從這裡可以看出隨著併發的上升,TiDB 和 MySQL 之間的 RT 差距也逐步縮短。由於 TiDB 可以透過擴充套件 DB 和 KV 節點提升 QPS 能力,我們在壓測中也做了相關驗證,符合預期。包括現有資料量翻一倍的基礎上對效能的影響也做了驗證,結論是無影響。為了方便和後面的內容對比,我們這裡只提供了 RT 的指標。

    • 單量較多的商家場景效能測試

我們挑了幾個出現頻率較高且查詢較慢的 SQL進行測試,詳情參照以下內容。

SQL1

SELECT *
  FROM table_name
 WHERE xx_id= 1203030
   AND xx_status IN(4000, 3040)
   AND is_del= 0 ORDER BY id DESC,
         create_time DESC  LIMIT 20

SQL2

SELECT [column_name] FROM table_name
WHERE xx_id = 1203030
        AND xx_status = 8010
        AND close_type = 13
        AND close_time > ‘2022-06-19 18:16:24.519'
LIMIT 0, 30000

SQL3

SELECT * FROM table_name
 WHERE xx_id= 1203030
   AND xx_status IN(7000, 8000, 8010)
   AND is_del= 0
ORDER BY id DESC,create_time DESC 


LIMIT 20

SQL4

select count(*)  from table_name
 WHERE(seller_id= 1203030
   and is_del= 0
   and biz_type in('0', '12')
   and create_time>= '2021-11-01 00:00:00.0'
   and create_time< '2021-11-30 23:59:59.0'
   and(xx_status<> 1000 R biz_type<> 21))

關於 xxDB 特別做了處理,大家可以忽略,因為我們主要對比的是 MySQL 和 TiDB。從測試結果來看效果很好,完全滿足業務側的要求。

5.5 遇到的一些問題

  • SQL 執行計劃

問題:

首先說明一下,統計資訊健康度是 90 以上。SQL 還是會選錯索引。我們分析了一下,主要是兩個問題:1.查詢條件比較多,索引也比較多;2.最佳化器的能力待提升。

解決方案:

上線前和研發對已有 SQL 進行了全面的 Review,如果執行計劃不對,就透過 SPM 解決。

  • Bug

問題1:

Update 語句併發執行耗時 3S,經過排查是由於研發未使用顯示事務,所以第一次執行是樂觀事務,第二次重試才是悲觀事務。調整以後遇到了悲觀事務下,偶發性的寫寫衝突的問題。經排查是由於悲觀鎖未獲取到導致的寫寫衝突,需要升級到 5.3.2 才能解決。

解決方案:

升級版本到 5.3.2 解決

問題 2:

TiDB出現部分節點不可用,SQL執行報 Region is unavailable 錯誤。經排查是 5.3.2 引入的 TiKV bug。

PD leader 發生切換後,TiKV 向 PD client 傳送心跳請求失敗後不會重試,只能等待與 PD client 重連。

這樣,故障 TiKV 節點上的 Region 的資訊會逐步變舊,使得 TiDB 無法獲取最新的 Region 資訊,導致 SQL 執行出錯。

解決方案:

這是一個讓人後背發涼的 bug。當時的判斷是由於 PD 切換導致的,但是不清楚是 bug。我們採用了影響最小的故障恢復方案(把 PD leader 切回去,因為原 PD Leader 沒有掛,只是發生了切換)。問題解決後在官方發現了這個bug fix。所以又安排了升級。

這是我們上線過程中遇到的幾個典型問題。總體來說引入一個新資料庫就會帶來一定的試錯成本,所以我們依然處於謹慎選型的狀態。另外就是吐槽一下,就上面的問題 2,建議官方要加強 Code Review 和混沌工程演練。

5.6 上線效果

  • 效能收益

為了確保上線穩定性,我們透過灰度切流的方式逐步放量。完全切流後成果顯著,慢 SQL 幾乎全部消失,如下圖所示。

  • 成本收益

由於 MySQL 的分庫分表叢集由 10個寫例項、10個讀例項構成,遷移至 TiDB 後的叢集規模為 TiDB6、TiKV12。成本下降了58%。所以再重複說一下選對了場景,TiDB 也能順帶節省成本。

  • 大促考驗

專案上線後輕鬆應對了今年的雙 11、雙 12,大促中的系統 RT表現穩定。

6. 總結

最後特別說明下,文章中涉及一些產品的對比只是基於我們當時的場景和需求進行的分析,並不代表某個資料庫產品的好壞。寫這篇文章的目的是想把我們 TiDB 落地經驗做個階段性總結,順便也能給同行們做個大方向上的參考。我們的這套方法論,理論上適用於任何一個需要再企業內部引入新型資料,並且推廣的場景。本文涉及的內容和方向比較多,無法每個模組都做深入的探討。後面我們也會把大家感興趣的模組單獨拆分出來做幾期深入分享。

*文/xiaoyu

關注得物技術,每週一三五晚18:30更新技術乾貨

要是覺得文章對你有幫助的話,歡迎評論轉發點贊~

相關文章