TiDB 4.0 為解決熱點問題做了哪些改進?

TiDB_Robot發表於2020-07-29

作者:李坤

熱點問題概述

一直以來,TiDB 的資料訪問熱點問題,是使用者比較關注的問題。為什麼這個問題如此突出呢?這其實是 “分散式” 帶來的結構效應。單機資料庫由於只有一個節點,是不存在熱點問題的 (因為效能的上限就是單機的處理能力),而分散式資料庫叢集存在多個節點,在達到儲存擴充套件、讀寫能力擴充套件的目的上,我們希望大量的讀寫壓力能夠平攤在每個節點上,TiDB 也一直在朝著這個目標靠近。

資料庫也存在二八原則,80% 的讀寫在 20% 的最新資料上,以使用最廣泛的 MySQL 為例,很多從 MySQL 遷移到 TiDB 的業務,遷移前會使用自增主鍵,將隨機寫轉為順序寫提高效能。而這種方式,在寫入 QPS 較大的 TiDB 叢集上,會造成寫入熱點,原因是 TiDB 使用 range 的方式來進行資料分片,導致新寫入的資料集中在一個 range 範圍所在的節點,對於這部分寫入就會退化成單機的寫入效能,未能利用分散式讀寫擴充套件的優勢。

直面問題

為了解決這些問題,TiDB 在很早之前的 2.0 版本就開始設法改進,這就是新增的表屬性 SHARD_ROW_ID_BITS,它的原理是將自動生成的主鍵在二進位制的高几位進行一個位翻轉從而將單調遞增的 ID 轉化為一定範圍內的隨機 ID,來達到自動將寫入資料的壓力分攤到不同節點,由於多數業務對於主鍵通常只需要不重複而不是單調遞增,這個特效能夠相當程度上緩解單點寫入的壓力。並且支援了 PRE_SPLIT_REGIONS,在建表時為該表預設多個 Region。同時,在後面的 3.0 大版本上,也一直在優化 PD 和 TiKV 節點的熱點排程的演算法,引入了獨立熱點排程器 HOT-REGION-SCHEDULER,更及時的保持不同節點的讀寫熱點 range 均衡。

不過,這些改進還不足以完全解決熱點問題,還需要不斷演進。TiDB 需要直面這些問題、解決問題,發展到 3.0 依然存在如下幾個比較突出的問題:

  • SHARD_ROW_ID_BITS 標誌

    • 易用性差,使用者存在理解和學習成本;
    • 不能支援與 Int 型別主鍵共同使用,這造成使用的困擾,表結構改造大,無法相容 Binlog 的使用要求;
    • 導致有時使用者需要自己部署類似 snowflake 的隨機 id 生成服務。
  • 熱點排程

    • 3.0 版本統計熱點 Region 的方式比較單一,統計出持續一段時間讀或寫流量超過一定閾值的 Region,對其進行排程,會造成流量統計不準確、過度排程、熱點數目較多時不穩定,等問題。
  • 熱點排查

    • 無法直觀斷定是否存在熱點;
    • 無法直觀判斷哪張表存在熱點,是什麼語句造成的熱點;
    • 熱點問題排查困難,需要結合多處監控、日誌,綜合判斷。

4.0 版本的改進

熱點問題一直是 TiDB 非常重視的問題,但這不是一日之功的事情,從 2.x 到 3.x 再到 4.0 版本,一直在不斷演進中。那麼 4.0 為了優化上面的三點問題,做了哪些改進呢?

AutoRandom ID

AutoRandom 是 TiDB 4.0 提供的一種擴充套件語法,用於解決整數型別主鍵通過 AutoIncrement 屬性分配 ID 時的寫熱點問題。

它的使用形式和 AutoIncrement 幾乎相同,但能實現隨機的表內唯一性,普通使用者不再需要理解複雜的 Shard 機制。

當然,AutoRandom 和 SHARD_ROW_ID_BITS 一樣,可以配合 PRE_SPLIT_REGIONS 語法共同使用,也可以使用 LAST_INSERT_ID() 獲取其值。

AutoRandom 的出現,極大的方便了 MySQL 使用者的上遷和下遷。MySQL 到 TiDB 的同步,表結構只需要稍作修改,可以沿用原 MySQL 的 AUTOINCREMENT 值。在相容性方面,AutoRandom 也是以表結構上註釋的形式作為解析,沒有實現對應特性的 TiDB 版本則會忽略該屬性,因此 TiDB 向下遊其他資料庫產品同步也是可行的。

紅色部分 AutoRandom 以註釋作為解析方式

同時,AutoRandom 作為一個隨機方案,必須要能做到均勻分佈,才能真正解決熱點問題,我們通過一個測試,觀察一個大量插入後的效果,統計不同分段的行數可以看到是非常均勻的。

需要保證 AutoRandom 生成值的資料分佈均勻

上圖中 dist_interval 表示分段的基準間隔, interval 表示不同分段範圍,length 表示 AutoRandom 的結果命中在該範圍中的次數。

下面介紹一下 AutoRandom 的原理。

AutoRandom 成為了 Primary Key,與使用 SHARD_ROW_ID_BITS + auto_increment 唯一索引的方案相比,該方式實際上將隱式的 TiDB 內部的主鍵 _tidb_rowid 變成了顯式主鍵,底層機制幾乎相同,因此效能不會出現衰減。它將 64 位的 bigint 分為 3 段:

  • SignBit - 符號位,有符號時佔用,長度為 1。

  • ShardBits - 生成隨機數對 ID 值域打散,由屬性 auto_random(5) 指定,預設為 5。

  • increment_bits - 自增位,用於保證 ID 的唯一性以及單語句 Insert 時,分配的連續性。

最後,看 AutoRandom 的幾個注意事項:

  • Shard 位數不建議過多,通常預設的即可(預設值 5),太大會造成 Incremental 部分的可分配的位數變少,以及增加 rpc 互動消耗;

  • 和 AutoIncrement 一樣,AutoRandom 也支援使用者顯式寫入,但極其不建議這樣使用,Incremental 部分將會按使用者值 rebase,這可能會導致可分配 id 提前耗盡;

  • 建議使用 unsigned bigint 作為 AutoRandom 列的型別,可以最大程度增加 Incremental 的位數。

新熱點排程器

在熱點排程演算法方面,4.0 也有不少的改進。3.0 的版本是從單個 Region 視角出發,而沒有很好的彙總 TiKV 節點 上的統計資料,而 4.0 中,TiDB 將從 TiKV 節點的視角出發,去彙總和處理資料,因此新熱點排程器也叫做 Load-base 熱點排程。它從以下方面進行了優化:

對統計資訊新增降噪處理:對於統計資訊處理,新增了如下策略,忽略新 Leader 第一次上報的統計資訊和修復流量的計算時間。這將修復一部分統計不準確和虛高的問題。為了更好的降低噪聲,我們還新增了兩級處理的機制。

使用 TopN 覆蓋更多熱點:目前熱點識別演算法在熱點 Region 數量超過設定的預期值後將無法工作,為了覆蓋更多熱點,將維護熱點區域的資料結構,從兩個快取佇列修改為 TopN 的資料結構。

新增期望排程:為了避免出現冗餘排程的情況,我們新增了期望排程,即算出每個 Store 的期望,只有當實際數目低於期望乘係數才允許調入,當實際數目高於期望乘係數才允許調出。

新增 Pending Influence 對未來預判:為了解決過度排程的出現,我們必須慎重對待 operator 反映到統計上需要耗費時間,所以引入 Pending Influence 對統計進行預測修正,對於每一個新增的新 operator 將他們的開銷和代價記錄下來,作為接下來新 operator 的參考。

多維排程:為了進一步提高熱點排程器的能力,也考慮到對未來的可擴充套件性,我們設計了一個可以適應多維負載均衡的新熱點排程器框架,並基於該框架實現了流量的負載均衡。先列舉可能的排程方案,然後通過基於規則的比較找到最好的方案。

開啟新熱點排程後,測試流量可以快速得到均衡

熱點視覺化

在前面 4.0 Feature 的介紹中,已經介紹了 Dashboard 功能,他其中有一項是 「熱點視覺化」,也叫 KeyViz,他以熱力影像的方式,直觀的告訴使用者,你的讀寫流量集中在哪個庫,哪個索引,哪段範圍,這也是發現和定位熱點問題的一個利器,極大的方便使用者的排查熱點問題。

觀察上圖明亮的部分,可以看到有規律的斜線,可以清晰的看出是一個流量隨著 Region 範圍增長的熱力圖,這是一個典型自增主鍵造成的熱點。滑鼠指向其中一個色塊,可以看到具體熱點背後的庫表資訊。

小表熱點優化

前面的優化方法還不能解決小表熱點問題。由於 PD 的熱點排程只能以 Region 為粒度,小表通常只在一個 Region 中,PD 就無能為力了。例如,一些配置表的大量全表掃描、索引查詢產生的單 Region 熱點,往往這時需要人為手工介入 Split Region,但操作麻煩並且不及時,如果熱點只存在某幾個 Key 上,也不易確定切割位置。

在 4.0 版本中引入了 Load Base Split 功能,可以實現熱點小表的自動 Split 。Load Base Split 會基於統計資訊自動拆分 Region。通過統計去識別出那些讀流量在 10s 內持續超過閾值的 Region,並在合適的位置將這些 Region 拆分。在選擇拆分的位置時,會盡可能平衡拆分後兩個 Region 的訪問量,並儘量避免跨 Region 的訪問。在 4.0 版本上已經預設開啟該功能。

總結

熱點處理是分散式資料庫亙古不變的話題,經過四個大版本的演進,目前 TiDB 4.0 通過 AutoRandom、新熱點排程器、熱點視覺化這幾個方面進行了大幅度的優化。這些變化將以潤物細無聲的方式影響使用者的體驗。

當然,熱點問題還沒有終結,還需要在整個社群的幫助下,不斷的探索和改進:

  • 通過聚簇索引減少回表,提高讀熱點場景的資料訪問效率;目前在最新 Master 版本已經完成,已經有使用者在對應場景下測試發現,TPC-C 有 50% 的效能提升,聚簇索引將在下一個 GA 版本中提供;

  • 另外一個探索的方向是結合 AI 的預測,提前進行排程操作;

  • 小表熱點方面,5.0 版本將通過 readonly table(常量表)功能,會得到進一步優化;

  • 目前 KeyViz 雖然可以在 Region 的粒度上定位熱點的範圍,但還可以更加一步到位,比如直接告訴業務是否有讀寫熱點,直接展示哪類 SQL 造成的熱點,一鍵 Split 熱點 Region,自動分析潛在熱點根因。

更多原創文章乾貨分享,請關注公眾號
  • TiDB 4.0 為解決熱點問題做了哪些改進?
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章