TiDB 5.4 作為 2022 年開山之作,包含了許多有用有益的新功能和持續性的效能/穩定性提升。本文著重介紹重要新增功能和特性所帶給使用者的新體驗和價值,按照以下章節來組織:
基礎效能優化和提升
面向雲環境的功能擴充
產品易用性和運維支援
新增實用性功能涉及到的系統配置開關選項
主要的 bug 修復和穩定性提升
更多詳細內容還可以參照 Release Notes 和 使用者手冊 。
基礎效能優化和提升
TiDB 5.4 在效能提升方面實現了以下的重要改進:查詢計劃可利用多個列上的索引進行高效條件過濾相關的優化工作,即通過正式支援索引合併查詢優化功能,使此類查詢的效能獲得數量級的提升,並且具有響應時間穩定不佔系統資源的突出特點;對於資料量大、讀寫更新頻繁的分析場景, TiFlash 儲存引擎的效能優化將使 CPU 佔用率在現有基礎上顯著降低並間接幫助提升併發查詢下的總體效能;最後,TiDB 5.4 在大規模資料同步場景下顯著提升了同步工具 Lightning 的效能使得大規模的資料同步任務更輕鬆快捷。
TiFlash 儲存層大幅優化行存到列存轉碼效率
使用者場景與挑戰
HTAP 平臺和應用中,資料更新和大量掃錶行為交織在一起,儲存系統的效能是影響效能和穩定性的關鍵因素,重度使用者總是期待系統能有更好的效能並承載更多的業務。特別是 TiDB HTAP 採用了事務處理與分析查詢物理分離的架構,同一份資料根據業務的需要,在後臺進行自動的行式儲存到列式儲存的轉換以分別響應 OLTP 和 OLAP 兩種型別的負載。儲存層大幅優化了從 TiKV “行”儲存到 TiFlash “列”儲存格式的轉換效率,在“行 - 列”轉換環節的 CPU 效率大幅提升,進而使得高負載情況下可以節約出更多的 CPU 資源用於其他環節的計算任務。
解決方案與效果
TiDB 5.4 重新梳理了 TiFlash 中行存到列存轉碼模組的程式碼架構,大量簡化了冗餘的資料結構和判斷邏輯,採用 CPU 快取和向量化友好的資料結構和演算法,從而大幅提高執行效率。另外,新版本還相應地優化了 TiFlash 的儲存引擎 DeltaTree 的預設配置,綜合效果的確認參見下文。
列式儲存引擎寫入效能驗證:在不同併發情況下吞吐效能提高 60%~90%
驗證環境:
6 TiKV( 1 副本)、1 TiFlash( 1 副本),每個節點 40 個 CPU 邏輯 core,CH-benCHmark (1500 warehouse)。
CH-benCHmark 測試結果: 10 併發下部分查詢(Q1、Q6)效能提高約 20%
測試環境:
3 TiKV( 3 副本)、2 TiFlash( 2 副本),每個節點 40 個 CPU 邏輯 core,CH-benCHmark (1500 warehouse)。
小結
TiDB 行存與列存之間的資料轉換同步通常被外界認為是一種較大的 overhead, 但是經過努力,今後 TiDB 的行列轉換在架構保持大體不變的情況下,實際執行時已經不構成明顯的效能瓶頸。
TiDB 正式支援索引合併查詢優化
使用者場景與挑戰
以往有些查詢在邏輯上需要同時掃描多個列,而之前版本的 TiDB 處理區域掃描的查詢中只能選擇單獨某一列(或多列)上的索引(或一個複合列索引),即便各列上都已經有索引但整體的效能受此影響不能達到理想狀態。在 TiDB 5.4 版本中,正式提供了索引合併功能,得以允許優化器在查詢處理中同時選擇使用多列的索引以減少回表,達到超過一兩個數量級的過濾效果。對於此類以往容易形成效能瓶頸的問題在查詢時間和效能穩定性上都有較大幫助,例如(參見下文)查詢的響應時間可以由 600 毫秒縮短 30 倍至 20 毫秒,並提升一個數量級的查詢併發度。
解決方案
TiDB 在原有三種讀資料運算元基礎上增加了第四種型別的運算元 IndexMergeReader:
TableReader
IndexReader
IndexLookUpReader
IndexMergeReader
前兩種比較好理解,直接讀取主表資料或者索引表資料。IndexLookUpReader(回表運算元)會先讀取索引表,得到 row_id,再根據 row_id 從主表中讀取資料。
IndexMergeReader 執行流程類似於 IndexLookUpReader,區別在於可以利用多個索引進行回表,在如下例的場景可以極大提升查詢的效能:
SELECT * FROM t1 WHERE c1 < 10 OR c2 < 100;
上述查詢中如果 c1/c2 上都有索引,但是由於過濾條件是 OR,無法單獨使用 c1 或 c2 索引,導致只能進行全表掃。使用索引合併可以解決無法使用索引的問題:索引合併會單獨利用 c1/c2 索引得到 row_idx ,然後將兩個索引拿到的 row_id 進行 UNION 操作,以 UNION 操作的結果從主表中獲取實際行。
索引合併優勢場景
資料來源為以 TPC-H SF 1 (lineitem 錶行數為 600W),使用如下的查詢來獲取 lineitem 表中價格為 930,或者 orderkey 為 10000 且 comment 為特定字串的行:
SELECT l_partkey, l_orderkey
FROM lineitem
WHERE ( l_extendedprice = 930
OR l_orderkey = 10000 AND Substring(Lpad(l_comment, 'b', 100), 50, 1) = 'b' )
AND EXISTS(SELECT 1
FROM part
WHERE l_partkey = p_partkey);
不使用索引合併時,執行時間為 3.38s+
使用索引合併時,執行時間為 8.3ms:
索引合併非舒適場景
如果使用過濾性很差的條件,則直接使用全表掃的效能會比使用索引合併更好
SELECT l_partkey, l_orderkey
FROM lineitem
WHERE ( l_extendedprice >= 930
OR l_orderkey >= 10000 )
AND EXISTS(SELECT 1
FROM part
WHERE l_partkey = p_partkey);
下面的查詢沒有使用索引合併,執行時間只有 2.34s
使用 hint 強制優化器選擇索引合併,由於需要額外的回表時間,執行時間需要 19.79s
無明顯收益場景
在以下場景中,使用索引合併不會帶來明顯的收益 在資料量不大的情況下,由於資料很快能掃描並過濾完成,使用索引合併不會有很大收益 在過濾條件計算比較快的情況下(例如只是整型的比較),即使資料量相對較大(例如百萬行級別),相對於全表掃,索引合併也不會有很大提升。
如下查詢,雖然條件的過濾性很高,但是由於計算比較輕量級(只是整型的比較),計算都在 TiKV 完成,所以使用索引合併(26ms) 和不使用索引合併(30ms) 效能差異不大。
SELECT l_partkey, l_orderkey
FROM lineitem
WHERE ( l_extendedprice <= 930
OR l_orderkey = 10000 )
AND EXISTS(SELECT 1
FROM part
WHERE l_partkey = p_partkey);
資源消耗
在索引合併優勢場景的查詢中,由於大部分行已經在 TiKV 過濾掉,所以 CPU/記憶體資源消耗基本可以忽略。
未使用索引合併的查詢,由於過濾條件無法下推,導致需要將所有行都傳給 TiDB 進行 Selection 操作,記憶體消耗較大,在 10 個併發查詢情況下,TiDB 需要 2G 記憶體來過濾 600W 行資料。
小結
在過濾條件選擇率較高時,可以考慮使用索引合併。資料流量較大且過濾條件較好的場景,查詢響應時間可縮短 2 個數量級(本文給出的例子是 400 倍),將秒級響應的查詢變為毫秒級。
索引合併可大幅減少併發查詢時的系統資源消耗,特別是過濾條件無法下推的查詢(消耗資源較大)可以達到顛覆性的效果(例如原本消耗 2GB 的查詢,使用索引合併之後資源消耗甚至可以忽略不計)。
TiDB Lightning 新增高效的重複資料檢測特性
使用者場景與挑戰
在生產環境中,由於歷史原因,使用者的各個分片 MySQL 例項的資料可能存在重複,當主鍵/唯一索引重複時則形成衝突資料。因此在將多個分片 MySQL 合併匯入下游 TiDB 時必須進行檢測和處理,且可能高達幾十 TB 的單表資料量對檢測效率也是一項極大的挑戰。
解決方案
TiDB Lightning 是用於從 CSV/SQL 檔案高速匯入大規模資料到新 TiDB 叢集的工具。Lightning 的 local backend 模式可將源資料編碼為有序鍵值對,直接插入 TiKV 儲存,其匯入效率極高,並且支援使用多臺主機並行匯入一張表,是目前初始化 TiDB 叢集資料的常用方式。
在 local backend 模式下,資料匯入並不會經過事務寫入的介面,因此無法在插入時檢測衝突資料。在之前的版本, Lightning 僅能通過對比 KV 級別的校驗碼來實現,但侷限性較大,僅能知曉發生了錯誤,卻無法定位衝突資料的位置。
新增的重複資料檢測特性使得 Lightning 精準檢測衝突資料,並且內建了一種衝突資料刪除演算法以自動聚合。檢測到衝突資料後, Lightning 可以將其儲存以供使用者篩選後再次插入。
重複資料檢測特性預設關閉,可以在使用時根據不同的場景需求設定 record/remove 等不同的處理方式。
詳細效能驗證資料可參考下表:
小結
使用 Lightning 並行匯入特性,開啟重複資料檢測,可以精準定位資料來源中的衝突資料,執行效率在多次優化後耗時佔比約為總時長的 20%。
面向雲環境的功能擴充
TiDB 5.4 重視與雲環境的生態結合,特別推出了一項可以大幅節約儲存成本的 Raft Engine日誌儲存引擎,可為使用者節約 30% 以上的資料傳輸費用同時還在某些場合下有額外的效能收益;強化了資料備份效率,在支援 Amazon S3、Google Cloud Storage 的基礎上,新增了對 Azure 環境的支援,完成了與世界主流雲廠商儲存服務的對接。
支援使用 Raft Engine 作為 TiKV 的日誌儲存引擎
使用者場景與挑戰
雲環境上使用者最為關心的問題之一是成本,資料儲存量和 IO 請求所產生的開銷不可小覷。通常來說,分散式資料庫在處理使用者寫入時需要複製並持久化記錄大量的日誌,這無疑會增加使用者部署服務的成本。另一方面看,由於雲環境下的硬體資源有較為明確的限制,當使用者負載發生波動,而預設的硬體配置無法滿足時,服務質量也會受到顯著影響。
解決方案
TiDB 5.4 推出一項實驗性功能:Raft Engine,一款自研的 開源 日誌儲存引擎,相較於使用預設的 RocksDB 引擎,它最大的優勢在於節省了磁碟頻寬的使用量。首先,Raft Engine 將 TiDB 叢集的“寫入日誌”壓縮後直接存放在檔案佇列中,而不進行額外的全量轉儲。另外,Raft Engine 擁有更為高效的垃圾回收機制,利用過期資料的空間區域性性進行批量清理,在大部分場景下不額外佔用後臺資源。
這些優化能夠大幅降低同等負載下 TiDB 叢集中儲存節點的磁碟頻寬使用量。這意味著,同等水平的叢集將能服務更高峰值的業務輸入,而同等強度的業務可以縮減部分儲存節點數量來獲得近似的服務水平。
另外,作為自研引擎,Raft Engine 具有更輕量的執行路徑,在一些場景下顯著減少了寫入請求的尾延遲。
在實驗環境中,TPC-C 5000 Warehouse 負載下,使用 Raft Engine 能夠減少叢集約 30% 的總寫入頻寬,並對前臺吞吐有一定提升。
詳情參見 使用者手冊 。
小結
使用 Raft Engine 儲存叢集日誌,能夠有效減少寫入頻寬用量,節省雲上部署成本的同時提升服務穩定性。
支援 Azure Blob Storage 作為備份目標儲存
Backup & Restore (BR) 支援 Azure Blob Storage 作為備份的遠端目標儲存。在 Azure Cloud 環境部署 TiDB 的使用者,可以支援使用該功能方便地將叢集資料備份到 Azure Blob Storage 服務中,支援 AD 備份 和 金鑰訪問 兩種恢復方式。囿於篇幅,具體資訊請移步使用者手冊中的 Azure Blob Storage 備份支援 與 外部儲存 章節。
產品易用性和運維支援
TiDB 5.4 持續提升產品易用性和運維效率,做出了以下的努力:為提升優化器生成執行計劃的質量,增強了統計資訊的收集和管理功能,可以針對不同的表、分割槽、索引設定不同的採集配置項並且預設儲存設定,方便後續收集統計資訊時沿用已有配置項;資料備份過程有時會影響正常業務,這是長久以來困擾一些使用者的問題。5.4 BR 新增了備份執行緒自動調節功能,可顯著減輕備份帶來的負面影響;TiDB 執行過程中產生的大量日誌資料處理不當會造成對效能和穩定性的影響,5.4 版本提供了新的實驗特性可 使用 Raft Engine 儲存日誌,可以顯著減少寫流量和 CPU 使用率,提升前臺吞吐減少尾延遲;此外,TiDB 自 5.4 開始 支援 GBK 字符集 。
統計資訊採集配置持久化
詳情參見 使用者手冊 。
優化備份對叢集的影響
詳情參見 使用者手冊 。
新增實用性功能涉及到的系統配置開關選項
TiDB 5.4 對系統配置引數的優化做出了許多努力,完整資訊可參見 Release notes 和相關使用者手冊,本文僅舉其中一項代表性的改善點。
支援 session 變數設定有界限過期讀
TiDB 是基於 Raft 協議的多副本分散式資料庫。面對高併發,高吞吐業務場景,可以通過 follower 節點實現讀效能擴充套件,構建讀寫分離架構。針對不同的業務場景,follower 可以提供以下兩種讀模式:
強一致讀:通過強一致讀,可以確保所有節點讀取的資料實時一致,適用於一致性要求嚴格的業務場景,但是因為 leader 和 follower 的資料同步延遲導致強一致讀的吞吐較低、延遲較高,特別是在跨機房架構下延遲問題被進一步放大。
過期讀:過期讀是指可以通過快照讀取過去時間的過期資料,不保證實時一致性,解決了 leader 節點和 follower 節點的延遲問題,提升吞吐。該讀模式適用於資料實時一致性要求較低或者資料更新不頻繁的業務場景。
TiDB 目前支援通過顯示只讀事務或 SQL 語句的方式開啟 follower 過期讀。兩種方式均支援“指定時間”的精確過期讀和“指定時間邊界”的非精確過期讀兩種模式,詳細用法請參考 過期讀官方文件 。
從 TiDB 5.4.0 版本開始,TiDB 支援通過 session 變數設定有界限過期讀,進一步提升易用性,具體設定示例如下:
set @@tidb_replica_read=leader_and_follower
set @@tidb_read_staleness="-5"
通過該設定,TiDB 可以通過 session 變數快速開啟過期讀,避免了頻繁的顯示開啟只讀事務或者在每個 SQL 內指定過期讀語法,提升易用性,方便批量地實現就近選取 leader 或 follower 節點,並讀取 5 秒鐘內的最新過期資料,滿足準實時場景下低延遲、高吞吐資料訪問的業務訴求。
主要的 bug 修復和穩定性提升
自 TiDB 5.1 版本釋出以來,提高穩定性不斷“捉蟲”,是研發和 QA 團隊最優先的任務。5.4 版本總計進行了 200 餘項的體驗優化,其中主要部分在 Release notes 中記錄,其他細節可以參考 GitHub 上的 PR 記錄。TiDB 研發和 QA 團隊始終秉持對使用者負責的姿態,使產品日臻完善,期待贏得廣大使用者的信任。
PM 寄語
2022 年是廣大 TiDB 使用者事業虎虎生風蒸蒸日上的一年,希望 TiDB 5.4 能給使用者帶來更多的舒心,更多的便利,助力各種應用和業務的健康高效發展。敬請關注 TiDB 官網 , GitHub 以及各種社交媒體賬號,謹代表 TiDB 產品經理(PM) 團隊、研發工程與質量團隊一道,期待與廣大使用者一起開創更美好的一年。如果您對 TiDB 的產品有任何建議,歡迎來到 internals.tidb.io 與我們交流。
檢視 TiDB 5.4.0 Release Notes ,立即 下載試用 ,開啟 TiDB 5.4.0 之旅。