如何構建企業內的 TiDB 自運維體系
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 還是有些不一樣的地方的,也帶來了一些限制:
- 不能在單條 ALTER TABLE 語句中完成多個操作。MySQL 下會把多個同一張表的 DDL 進行合并,然后使用 gh-ost 或者 pt-osc 工具一次性執行。TiDB 里只能一個個單獨去執行;(6.2 已經支持了ALTER TABLE語句增刪改多個列或索引)
- 不支持不同類型的索引 (HASH|BTREE|RTREE|FULLTEXT);
- 不支持添加 / 刪除主鍵,除非開啟了 alter-primary-key 配置項;
- 不支持將字段類型修改為其超集,例如不支持從 INTEGER 修改為 VARCHAR,或者從 TIMESTAMP 修改為 DATETIME,否則可能輸出的錯誤信息 Unsupported modify column
- 更改 / 修改數據類型時,尚未支持“有損更改”,例如不支持從 BIGINT 更改為 INT;
- 更改 / 修改 DECIMAL 類型時,不支持更改精度 ;
- 更改 / 修改整數列時,不允許更改 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.高規則機器部署密度與穩定性的權衡。
節點 | 數量 | 配置 |
TIDB | 3 | 基礎規格:8C32G200GB(云盤) 高配規格:16C64G200GB(云盤) |
PD | 3 | 基礎規格:8C16G200GB(云盤) 高配規格:16C64G200G(云盤) |
Monitor | 1 | 4C16G200GB(云盤) |
TIKV/TIFLASH | 3 | 基礎規格: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 變更工單風險自動化識別
語法檢查:
- DDL 與 DML 類型判斷,確保每次執行的內容是同一個類型
- SQL 語法檢查,確保提交的 SQL 語法是正確的
合規檢查:
變更合規性檢查,確保提交的 SQL 是可以按照 DBA 定義的規范設計(可以使用的字段類型、字段命名、索引命名、索引數量,字段長度由長修改短等限制),簡單說就是要么允許,要么不允許
風險識別:
- 該項的作用是將允許執行的進行風險識別,研發可以根據風險等級選擇執行時間,DBA 也能在審批階段判斷是否合理,并修改執行時間。
- 相關風險定義
變更類型 | 變更項 | 風險提示 |
DDL | Create table | 低 |
Add index | 測試環境(低) 生產環境(表大小,低/中/高) | |
Add column | 低 | |
Modify column 類型有限修改 | 高 | |
Modify column 長度 變長 | 低 | |
Drop index | 測試環境(低) 生產環境(高) | |
Truncate table | 測試環境(低) 生產環境(高) | |
DML | update/delete | 測試環境(低) 生產環境(修改數量,低/中/高) |
insert | 低 |
下圖是基于以上提到的能力,實現的 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
SQL2
SQL3
SQL4
關于 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 后的集群規模為 TiDB*6、TiKV*12。成本下降了58%。所以再重復說一下選對了場景,TiDB 也能順帶節省成本。
大促考驗
項目上線后輕松應對了今年的雙 11、雙 12,大促中的系統 RT表現穩定。
6、總結
最后特別說明下,文章中涉及一些產品的對比只是基于我們當時的場景和需求進行的分析,并不代表某個數據庫產品的好壞。寫這篇文章的目的是想把我們 TiDB 落地經驗做個階段性總結,順便也能給同行們做個大方向上的參考。我們的這套方法論,理論上適用于任何一個需要再企業內部引入新型數據,并且推廣的場景。本文涉及的內容和方向比較多,無法每個模塊都做深入的探討。后面我們也會把大家感興趣的模塊單獨拆分出來做幾期深入分享。