TiDB 效能分析&效能調優&優化實踐大全
本文包含:
-
TiDB 效能優化概述
-
TiDB 效能分析和優化
-
OLTP 負載效能優化實踐
-
Performance Overview 皮膚重要監控指標詳解
1、TiDB 效能優化概述
https:// tidb.net/blog/1731b977
2、TiDB 效能分析和優化
本文介紹了基於資料庫時間的系統優化方法,以及如何利用 TiDB Performance Overview 皮膚進行效能分析和優化。
通過本文中介紹的方法,你可以從全域性、自頂向下的角度分析使用者響應時間和資料庫時間,確認使用者響應時間的瓶頸是否在資料庫中。如果瓶頸在資料庫中,你可以通過資料庫時間概覽和 SQL 延遲的分解,定位資料庫內部的瓶頸點,並進行鍼對性的優化。
基於資料庫時間的效能優化方法
TiDB 對 SQL 的處理路徑和資料庫時間進行了完善的測量和記錄,方便定位資料庫的效能瓶頸。即使在使用者響應時間的效能資料缺失的情況下,基於 TiDB 資料庫時間的相關效能指標,你也可以達到以下兩個效能分析目標:
- 通過對比 SQL 處理平均延遲和事務中 TiDB 連線的空閒時間,確定整個系統的瓶頸是否在 TiDB 中。
- 如果瓶頸在 TiDB 內部,根據資料庫時間概覽、顏色優化法、關鍵指標和資源利用率、自上而下的延遲分解,定位到效能瓶頸具體在整個分散式系統的哪個模組。
確定整個系統的瓶頸是否在 TiDB 中
- 如果事務中 TiDB 連線的平均空閒時間比 SQL 平均處理延遲高,說明應用的事務處理中,主要的延遲不在資料庫中,資料庫時間佔使用者響應時間比例小,可以確認瓶頸不在資料庫中。在這種情況下,需要關注資料庫外部的元件,比如應用伺服器硬體資源是否存在瓶頸,應用到資料庫的網路延遲是否過高等。
- 如果 SQL 平均處理延遲比事務中 TiDB 連線的平均空閒時間高,說明事務中主要的瓶頸在 TiDB 內部,資料庫時間佔使用者響應時間比例大。
如果瓶頸在 TiDB 內部,如何定位
一個典型的 SQL 的處理流程如下所示,TiDB 的效能指標覆蓋了絕大部分的處理路徑,對資料庫時間進行不同維度的分解和上色,使用者可以快速的瞭解負載特性和資料庫內部的瓶頸。
資料庫時間是所有 SQL 處理時間的總和。通過以下三個維度對資料庫時間進行分解,可以幫助你快速定位 TiDB 內部瓶頸:
- 按 SQL 處理型別分解,判斷哪種型別的 SQL 語句消耗資料庫時間最多。對應的分解公式為:
DB Time = Select Time + Insert Time + Update Time + Delete Time + Commit Time + ...
- 按 SQL 處理的 4 個步驟(即 get_token/parse/compile/execute)分解,判斷哪個步驟消耗的時間最多。對應的分解公式為:
DB Time = Get Token Time + Parse Time + Comiple Time + Execute Time
- 對於 execute 耗時,按照 TiDB 執行器本身的時間、TSO 等待時間、KV 請求時間和重試的執行時間,判斷執行階段的瓶頸。對應的分解公式為:
Execute Time ~= TiDB Executor Time + KV Request Time + PD TSO Wait Time + Retried execution time
利用 Performance Overview 皮膚進行效能分析和優化
本章介紹如何利用 Grafana 中的 Performance Overview 皮膚進行基於資料庫時間的效能分析和優化。
Performance Overview 皮膚按總分結構對 TiDB、TiKV、PD 的效能指標進行編排組織,包括以下三個部分:
- 資料庫時間和 SQL 執行時間概覽:通過顏色標記不同 SQL 型別,SQL 不同執行階段、不同請求的資料庫時間,幫助你快速識別資料庫負載特徵和效能瓶頸。
- 關鍵指標和資源利用率:包含資料庫 QPS、應用和資料庫的連線資訊和請求命令型別、資料庫內部 TSO 和 KV 請求 OPS、TiDB 和 TiKV 的資源使用概況。
- 自上而下的延遲分解:包括 Query 延遲和連線空閒時間對比、Query 延遲分解、execute 階段 TSO 請求和 KV 請求的延遲、TiKV 內部寫延遲的分解等。
資料庫時間和 SQL 執行時間概覽
Database Time 指標為 TiDB 每秒處理 SQL 的延遲總和,即 TiDB 叢集每秒併發處理應用 SQL 請求的總時間(等於活躍連線數)。
Performance Overview 皮膚提供了以下三個面積堆疊圖,幫助你瞭解資料庫負載的型別,快速定位資料庫時間的瓶頸主要是處理什麼語句,集中在哪個執行階段,SQL 執行階段主要等待 TiKV 或者 PD 哪種請求型別。
- Database Time By SQL Type
- Database Time By SQL Phase
- SQL Execute Time Overview
顏色優化法
通過觀察資料庫時間分解圖和執行時間概覽圖,你可以直觀地區分正常或者異常的時間消耗,快速定位叢集的異常瓶頸點,高效瞭解叢集的負載特徵。對於正常的時間消耗和請求型別,圖中顯示顏色為綠色系或藍色系。如果非綠色或藍色系的顏色在這兩張圖中佔據了明顯的比例,意味著資料庫時間的分佈不合理。
- Database Time By SQL Type:藍色標識代表 Select 語句,綠色標識代表 Update、Insert、Commit 等 DML 語句。紅色標識代表 General 型別,包含 StmtPrepare、StmtReset、StmtFetch、StmtClose 等命令。
- Database Time By SQL Phase:execute 執行階段為綠色,其他三個階段偏紅色系,如果非綠色的顏色佔比明顯,意味著在執行階段之外資料庫消耗了過多時間,需要進一步分析根源。一個常見的場景是因為無法使用執行計劃快取,導致 compile 階段的橙色佔比明顯。
- SQL Execute Time Overview:綠色系標識代表常規的寫 KV 請求(例如 Prewrite 和 Commit),藍色系標識代表常規的讀 KV 請求(例如 Cop 和 Get),其他色系標識需要注意的問題。例如,悲觀鎖加鎖請求為紅色,TSO 等待為深褐色。如果非藍色系或者非綠色系佔比明顯,意味著執行階段存在異常的瓶頸。例如,當發生嚴重鎖衝突時,紅色的悲觀鎖時間會佔比明顯;當負載中 TSO 等待的消耗時間過長時,深褐色會佔比明顯。
示例 1:TPC-C 負載
Database Time by SQL Type:主要消耗時間的語句為 commit、update、select 和 insert 語句。
- Database Time by SQL Phase:主要消耗時間的階段為綠色的 execute 階段。
- SQL Execute Time Overview:執行階段主要消耗時間的 KV 請求為綠色的 Prewrite 和 Commit。
注意
- KV 請求的總時間大於 execute time 為正常現象,因為 TiDB 執行器可能併發向多個 TiKV 傳送 KV 請求,導致總的 KV 請求等待時間大於 execute time。TPC-C 負載中,事務提交時,TiDB 會向多個 TiKV 並行傳送 Prewrite 和 Commit 請求,所以這個例子中 Prewrite、Commit 和 PessimisticsLock 請求的總時間明顯大於 execute time。
- execute time 也可能明顯大於 KV 請求的總時間加上 tso_wait 的時間,這意味著 SQL 執行階段主要時間花在 TiDB 執行器內部。兩種常見的例子:
- 例 1:TiDB 執行器從 TiKV 讀取大量資料之後,需要在 TiDB 內部進行復雜的關聯和聚合,消耗大量時間。
- 例 2:應用的寫語句鎖衝突嚴重,頻繁鎖重試導致
Retried execution time
過長。
示例 2:OLTP 讀密集負載
Database Time by SQL Type:主要消耗時間的語句為 select、commit、update和 insert 語句。其中,select 佔據絕大部分的資料庫時間。
- Database Time by SQL Phase:主要消耗時間的階段為綠色的 execute 階段。
- SQL Execute Time Overview:執行階段主要消耗時間為深褐色的 pd tso_wait、藍色的 KV Get 和綠色的 Prewrite 和 Commit。
示例 3:只讀 OLTP 負載
- Database Time by SQL Type:幾乎所有語句為 select。
- Database Time by SQL Phase:主要消耗時間的階段為橙色的 compile 和綠色的 execute 階段。compile 階段延遲最高,代表著 TiDB 生成執行計劃的過程耗時過長,需要根據後續的效能資料進一步確定根源。
- SQL Execute Time Overview:執行階段主要消耗時間的 KV 請求為藍色 BatchGet。
注意
示例 3 select 語句需要從多個 TiKV 並行讀取幾千行資料,BatchGet 請求的總時間遠大於執行時間。
示例 4: 鎖爭用負載
Database Time by SQL Type:主要為 Update 語句。
- Database Time by SQL Phase:主要消耗時間的階段為綠色的 execute 階段。
- SQL Execute Time Overview:執行階段主要消耗時間的 KV 請求為紅色的悲觀鎖 PessimisticLock,execute time 明顯大於 KV 請求的總時間,這是因為應用的寫語句鎖衝突嚴重,頻繁鎖重試導致
Retried execution time
過長。目前Retried execution time
消耗的時間,TiDB 尚未進行測量。
TiDB 關鍵指標和叢集資源利用率
Query Per Second、Command Per Second 和 Prepared-Plan-Cache
通過觀察 Performance Overview 裡的以下三個皮膚,可以瞭解應用的負載型別,與 TiDB 的互動方式,以及是否能有效地利用 TiDB 的 執行計劃快取。
- QPS:表示 Query Per Second,包含應用的 SQL 語句型別執行次數分佈。
- CPS By Type:CPS 表示 Command Per Second,Command 代表 MySQL 協議的命令型別。同樣一個查詢語句可以通過 query 或者 prepared statement 的命令型別傳送到 TiDB。
- Queries Using Plan Cache OPS:TiDB 叢集每秒命中執行計劃快取的次數。執行計劃快取只支援 prepared statement 命令。TiDB 開啟執行計劃快取的情況下,存在三種使用情況:
- 完全無法命中執行計劃快取:每秒命中次數為 0,因為應用使用 query 命令,或者每次 StmtExecute 執行之後呼叫 StmtClose 命令,導致快取的執行計劃被清理。
- 完全命中執行計劃快取:每秒命中次數等於 StmtExecute 命令每秒執行次數。
- 部分命中執行計劃快取:每秒命中次數小於 StmtExecute 命令每秒執行次數,執行計劃快取目前存在一些限制,比如不支援子查詢,該型別的 SQL 執行計劃無法被快取。
示例 1:TPC-C 負載
TPC-C 負載型別主要以 Update、Select 和 Insert 語句為主。總的 QPS 等於每秒 StmtExecute 的次數,並且 StmtExecute 每秒的資料基本等於 Queries Using Plan Cache OPS。這是 OLTP 負載理想的情況,客戶端執行使用 prepared statement,並且在客戶端快取了 prepared statement 物件,執行每條 SQL 語句時直接呼叫 statement 執行。執行時都命中執行計劃快取,不需要重新 compile 生成執行計劃。
示例 2:只讀 OLTP 負載,使用 query 命令無法使用執行計劃快取
這個負載中, Commit QPS = Rollback QPS = Select QPS。應用開啟了 auto-commit 併發,每次從連線池獲取連線都會執行 rollback,因此這三種語句的執行次數是相同的。
QPS 皮膚中出現的紅色加粗線為 Failed Query,座標的值為右邊的 Y 軸。非 0 代表此負載中存在錯誤語句。
- 總的 QPS 等於 CPS By Type 皮膚中的 Query,說明應用中使用了 query 命令。
- Queries Using Plan Cache OPS 皮膚沒有資料,因為不使用 prepared statement 介面,無法使用 TiDB 的執行計劃快取, 意味著應用的每一條 query,TiDB 都需要重新解析,重新生成執行計劃。通常會導致 compile 時間變長以及 TiDB CPU 消耗的增加。
示例 3:OLTP 負載,使用 prepared statement 介面無法使用執行計劃快取
StmtPreare 次數 = StmtExecute 次數 = StmtClose 次數 ~= StmtFetch 次數,應用使用了 prepare > execute > fetch > close 的 loop,很多框架都會在 execute 之後呼叫 close,確保資源不會洩露。這會帶來兩個問題:
- 執行每條 SQL 語句需要 4 個命令,以及 4 次網路往返。
- Queries Using Plan Cache OPS 為 0, 無法命中執行計劃快取。StmtClose 命令預設會清理快取的執行計劃,導致下一次 StmtPreare 命令需要重新生成執行計劃。
注意
從 TiDB v6.0.0 起,你可以通過全域性變數 (
set global tidb_ignore_prepared_cache_close_stmt=on;
) 控制 StmtClose 命令不清理已被快取的執行計劃,使得下一次的 SQL 的執行不需要重新生成執行計劃。
KV/TSO Request OPS 和連線資訊
在 KV/TSO Request OPS 皮膚中,你可以檢視 KV 和 TSO 每秒請求的資料統計。其中,
kv request total
代表 TiDB 到 TiKV 所有請求的總和。通過觀察 TiDB 到 PD 和 TiKV 的請求型別,可以瞭解叢集內部的負載特徵。
在 Connection Count (連線資訊)皮膚中,你可以檢視總的連線數和每個 TiDB 的連線數,並由此判斷連線總數是否正常,每個 TiDB 的連線數是否不均衡。
active connections
記錄著活躍連線數,等於每秒的資料庫時間。
示例 1:繁忙的負載
在此 TPC-C 負載中:
- 每秒總的 KV 請求的數量為 104.2k。按請求數量排序,最高的請求型別為
PessimisticsLock
、Prewrite
、Commit
和BatchGet
等。 - 總的連線數為 810,三個 TiDB 例項的連線數大體均衡。活躍的連線數為 787.1。對比活躍連線數和總連線數,97% 的連線都是活躍的,通常意味著資料庫是這個應用系統的效能瓶頸。
示例 2:空閒的負載
在此負載中:
- 每秒總的 KV 請求資料是 2.6 K,TSO 請求次數是每秒 1.1 K。
- 總的連線數為 410,連線數在三個 TiDB 中相對均衡。活躍連線數只有 2.5,說明資料庫系統非常空閒。
TiDB CPU,以及 TiKV CPU 和 IO 使用情況
在 TiDB CPU 和 TiKV CPU/IO MBps 這兩個皮膚中,你可以觀察到 TiDB 和 TiKV 的邏輯 CPU 使用率和 IO 吞吐,包含平均、最大和 delta(最大 CPU 使用率減去最小 CPU 使用率),從而用來判定 TiDB 和 TiKV 總體的 CPU 使用率。
- 通過
delta
值,你可以判斷 TiDB 是否存在 CPU 使用負載不均衡(通常伴隨著應用連線不均衡),TiKV 是否存在熱點。 - 通過 TiDB 和 TiKV 的資源使用概覽,你可以快速判斷叢集是否存在資源瓶頸,最需要擴容的元件是 TiDB 還是 TiKV。
示例 1:TiDB 資源使用率高
下圖負載中,每個 TiDB 和 TiKV 配置 8 CPU。
- TiDB 平均 CPU 為 575%。最大 CPU 為 643%,delta CPU 為 136%。
- TiKV 平均 CPU 為 146%,最大 CPU 215%。delta CPU 為 118%。TiKV 的平均 IO 吞吐為 9.06 MB/s,最大 IO 吞吐為 19.7 MB/s,delta IO 吞吐 為 17.1 MB/s。
由此可以判斷,TiDB 的 CPU 消耗明顯更高,並接近於 8 CPU 的瓶頸,可以考慮擴容 TiDB。
示例 2:TiKV 資源使用率高
下圖 TPC-C 負載中,每個 TiDB 和 TiKV 配置 16 CPU。
- TiDB 平均 CPU 為 883%。最大 CPU 為 962%,delta CPU 為 153%。
- TiKV 平均 CPU 為 1288%,最大 CPU 1360%。delta CPU 為 126%。TiKV 的平均 IO 吞吐為130 MB/s,最大 IO 吞吐為 153 MB/s,delta IO 吞吐為 53.7 MB/s。
由此可以判斷,TiKV 的 CPU 消耗更高,因為 TPC-C 是一個寫密集場景,這是正常現象,可以考慮擴容 TiKV 節點提升效能。
Query 延遲分解和關鍵的延遲指標
延遲皮膚通常包含平均值和 99 分位數,平均值用來定位總體的瓶頸,99 分位數用來判斷是否存在延遲嚴重抖動的情況。判斷效能抖動範圍時,可能還需要需要藉助 999 分位數。
Duration 和 Connection Idle Duration
Duration 皮膚包含了所有語句的 99 延遲和每種 SQL 型別的平均延遲。Connection Idle Duration 皮膚包含連線空閒的平均和 99 延遲,連線空閒時包含兩種狀態:
- in-txn:代表事務中連線的空閒時間,即當連線處於事務中時,處理完上一條 SQL 之後,收到下一條 SQL 語句的間隔時間。
- not-in-txn:當連線沒有處於事務中,處理完上一條 SQL 之後,收到下一條 SQL 語句的間隔時間。
應用進行資料庫事務時,通常使用同一個資料庫連線。對比 query 的平均延遲和 connection idle duration 的延遲,可以判斷整個系統效能瓶頸或者使用者響應時間的抖動是否是由 TiDB 導致的。
- 如果應用負載不是隻讀的,包含事務,對比 query 平均延遲和
avg-in-txn
可以判斷應用處理事務時,主要的時間是花在資料庫內部還是在資料庫外面,藉此定位使用者響應時間的瓶頸。 - 如果是隻讀負載,不存在
avg-in-txn
指標,可以對比 query 平均延遲和avg-not-in-txn
指標。
現實的客戶負載中,瓶頸在資料庫外面的情況並不少見,例如:
- 客戶端伺服器配置過低,CPU 資源不夠。
- 使用 HAProxy 作為 TiDB 叢集代理,但是 HAProxy CPU 資源不夠。
- 使用 HAProxy 作為 TiDB 叢集代理,但是高負載下 HAProxy 伺服器的網路頻寬被打滿。
- 應用伺服器到資料庫延遲過高,比如公有云環境應用和 TiDB 叢集不在同一個地區,比如資料庫的 DNS 均衡器和 TiDB 叢集不在同一個地區。
- 客戶端程式存在瓶頸,無法充分利用伺服器的多 CPU 核或者多 Numa 資源,比如應用只使用一個 JVM 向 TiDB 建立上千個 JDBC 連線。
示例 1:使用者響應時間的瓶頸在 TiDB 中
在此 TPC-C 負載中:
- 所有 SQL 語句的平均延遲 477 us,99 延遲 3.13ms。平均 commit 語句 2.02ms,平均 insert 語句 609ms,平均查詢語句 468us。
- 事務中連線空閒時間
avg-in-txn
171 us。
由此可以判斷,平均的 query 延遲明顯大於
avg-in-txn
,說明事務處理中,主要的瓶頸在資料庫內部。
示例 2:使用者響應時間的瓶頸不在 TiDB 中
在此負載中,平均 query 延遲為 1.69ms,事務中連線空閒時間
avg-in-txn
為 18ms。說明事務中,TiDB 平均花了 1.69ms 處理完一個 SQL 語句之後,需要等待 18ms 才能收到下一條語句。
由此可以判斷,使用者響應時間的瓶頸不在 TiDB 中。這個例子是在一個公有云環境下,因為應用和資料庫不在同一個地區,應用和資料庫之間的網路延遲高導致了超高的連線空閒時間。
Parse、Compile 和 Execute Duration
在 TiDB 中,從輸入查詢文字到返回結果的 典型處理流程 1。
SQL 在 TiDB 內部的處理分為四個階段,get token、parse、compile 和 execute:
- get token 階段:通常只有幾微秒的時間,可以忽略。除非 TiDB 單個例項的連線數達到的 token-limit 的限制,建立連線的時候被限流。
- parse 階段:query 語句解析為抽象語法樹 abstract syntax tree (AST)。
- compile 階段:根據 parse 階段輸出的 AST 和統計資訊,編譯出執行計劃。整個過程主要步驟為邏輯優化與物理優化,前者通過一些規則對查詢計劃進行優化,例如基於關係代數的列裁剪等,後者通過統計資訊和基於成本的優化器,對執行計劃的成本進行估算,並選擇整體成本最小的物理執行計劃。
- execute 階段:時間消耗視情況,先等待全域性唯一的時間戳 TSO,之後執行器根據執行計劃中運算元涉及的 Key 範圍,構建出 TiKV 的 API 請求,分發到 TiKV。execute 時間包含 TSO 等待時間、KV 請求的時間和 TiDB 執行器本身處理資料的時間。
如果應用統一使用 query 或者 StmtExecute MySQL 命令介面,可以使用以下公式來定位平均延遲的瓶頸。
avg Query Duration = avg Get Token + avg Parse Duration + avg Compile Duration + avg Execute Duration
通常 execute 階段會佔 query 延遲的主要部分,在以下情況下,parse 和 compile 階段也會佔比明顯。
- parse 階段延遲佔比明顯:比如 query 語句很長,文字解析消耗大量的 CPU。
- compile 階段延遲佔比明顯:如果應用沒有使用執行計劃快取,每個語句都需要生成執行計劃。compile 階段的延遲可能達到幾毫秒或者幾十毫秒。如果無法命中執行計劃快取,compile 階段需要進行邏輯優化和物理優化,這將消耗大量的 CPU 和記憶體,並給 Go Runtime 帶來壓力(因為 TiDB 是
href="https://go.dev/">Go 編寫的),進一步影響 TiDB 其他元件的效能。這說明,OLTP 負載在 TiDB 中是否能高效執行,執行計劃緩扮演了重要的角色。
示例 1:資料庫瓶頸在 compile 階段
此圖中 parse、compile 和 execute 階段的平均時間分別為 17.1 us、729 us 和 681 us。因為應用使用 query 命令介面,無法使用執行計劃快取,所以 compile 階段延遲高。
示例 2:資料庫瓶頸在 execute 階段
在此 TPC-C 負載中,parse、compile 和 execute 階段的平均時間分別為 7.39us、38.1us 和 12.8ms。query 延遲的瓶頸在於 execute 階段。
KV 和 TSO Request Duration
在 execute 階段,TiDB 會跟 PD 和 TiKV 進行互動。如下圖所示,當 TiDB 處理 SQL 語句請求時,在進行 parse 和 compile 之前,如果需要獲取 TSO,會先請求生成 TSO。PD Client 不會阻塞呼叫者,而是直接返回一個
TSFuture
,並在後臺非同步處理 TSO 請求的收發,一旦完成立即返回給 TSFuture,TSFuture 的持有者則需要呼叫 Wait 方法來獲得最終的 TSO 結果。當 TiDB 完成 parse 和 compile 之後, 進入 execute 階段,此時存在兩個情況:
- 如果 TSO 請求已經完成,Wait 方法會立刻返回一個可用的 TSO 或 error
- 如果 TSO 請求還未完成,Wait 方法會 block 住等待一個可用的 TSO 或 error(說明 gRPC 請求已傳送但尚未收到返回結果,網路延遲較高)
TSO 等待的時間記錄為 TSO WAIT,TSO 請求的網路時間記錄為 TSO RPC。TiDB TSO 等待完成之後,執行過程中通常需要和 TiKV 進行讀寫互動:
- 讀的 KV 請求常見型別:Get、BatchGet 和 Cop
- 寫的 KV 請求常見型別:PessimisticLock,二階段提交的 Prewrite 和 Commit
這一部分的指標對應以下三個皮膚:
- Avg TiDB KV Request Duration:TiDB 測量的 KV 請求的平均延遲
- Avg TiKV GRPC Duration:TiKV 內部 GRPC 訊息處理的平均延遲
- PD TSO Wait/RPC Duration:TiDB 執行器等待 TSO 延遲 (wait) 和 TSO 請求的網路延遲(rpc)。
其中,Avg TiDB KV Request Duration 和 Avg TiKV GRPC Duration 的關係如下
Avg TiDB KV Request Duration = Avg TiKV GRPC Duration + TiDB 與 TiKV 之間的網路延遲 + TiKV GRPC 處理時間 + TiDB GRPC 處理時間和排程延遲。
Avg TiDB KV Request Duration 和 Avg TiKV GRPC Duration 的差值跟網路流量和延遲,TiDB 和 TiKV 的資源使用情況密切相關。
- 同一個機房內,Avg TiDB KV Request Duration 和 Avg TiKV GRPC Duration 的差值通常應該小於 2 毫秒。
- 同一地區的不同可用區,Avg TiDB KV Request Duration 和 Avg TiKV GRPC Duration 的差值通常應該小於 5 毫秒。
示例 1:同機器低負載的叢集
在此負載中,TiDB 側平均 Prewrite 請求延遲為 925 us,TiKV 內部 kv_prewrite 平均處理延遲為 720 us,相差 200 us 左右,是同機房內正常的延遲。TSO wait 平均延遲 206 us,rpc 時間為 144 us。
示例 2:公有云叢集,負載正常
在此示例中,TiDB 叢集部署在同一個地區的不同機房。TiDB 側平均 Commit 請求延遲為 12.7 ms,TiKV 內部 kv_commit 平均處理延遲為 10.2ms,相差 2.5ms 左右。TSO wait 平均延遲為 3.12ms,rpc 時間為 693us。
示例 3:公有云叢集,資源嚴重過載
在此示例中,TiDB 叢集部署在同一個地區的不同機房,TiDB 網路和 CPU 資源嚴重過載。TiDB 側平均 BatchGet 請求延遲為 38.6 ms,TiKV 內部 kv_batch_get 平均處理延遲為 6.15 ms,相差超過 32 ms,遠高於正常值。TSO wait 平均延遲為 9.45ms,rpc 時間為 14.3ms。
Storage Async Write Duration、Store Duration 和 Apply Duration
TiKV 對於寫請求的處理流程如下圖
-
scheduler worker
會先處理寫請求,進行事務一致性檢查,並把寫請求轉化成鍵值對,傳送到raftstore
模組。 -
raftstore
為 TiKV 的共識模組,使用 Raft 共識演算法,使多個 TiKV 組成的儲存層可以容錯。Raftstore 分為 store 執行緒和 apply 執行緒。: - store 執行緒負載處理 Raft 訊息和新的
proposals
。 當收到新的proposals
時,leader 節點的 store 執行緒會寫入本地 Raft DB,並將訊息複製到多個 follower 節點。當這個proposals
在多數例項持久化成功之後,proposals
成功被提交。 - apply 執行緒會負載將提交的內容寫入到 KV DB 中。當寫操作的內容被成功的寫入 KV 資料庫中,apply 執行緒會通知外層請求寫請求已經完成。
Storage Async Write Duration 指標記錄寫請求進入 raftstore 之後的延遲,採集的粒度具體到每個請求的級別。
Storage Async Write Duration 分為 Store Duration 和 Apply Duration。你可以通過以下公式定位寫請求的瓶頸主要是 在 Store 還是 Apply 步驟。
avg Storage Async Write Duration = avg Store Duration + avg Apply Duration
注意
Store Duration 和 Apply Duration 從 v5.3.0 版本開始支援。
示例 1:同一個 OLTP 負載在 v5.3.0 和 v5.4.0 版本的對比
v5.4.0 版本,一個寫密集的 OLTP 負載 QPS 比 v5.3.0 提升了 14%。應用以上公式
- v5.3.0:24.4 ms ~= 17.7 ms + 6.59 ms
- v5.4.0:21.4 ms ~= 14.0 ms + 7.33 ms
因為 v5.4.0 版本中,TiKV 對 gRPC 模組進行了優化,優化了 Raft 日誌複製速度, 相比 v5.3.0 降低了 Store Duration。
v5.3.0:
v5.4.0:
示例 2:Store Duration 瓶頸明顯
應用以上公式:10.1 ms ~= 9.81 ms + 0.304 ms,說明寫請求的延遲瓶頸在 Store Duration。
Commit Log Duration、Append Log Duration 和 Apply Log Duration
Commit Log Duration、Append Log Duration 和 Apply Log Duration 這三個延遲是 raftstore 內部關鍵操作的延遲記錄。這些記錄採集的粒度是 batch 操作級別的,每個操作會把多個寫請求合併在一起,因此不能直接對應上文的 Store Duration 和 Apply Duration。
- Commit Log Duration 和 Append Log Duration 均為 store 執行緒的操作。Commit Log Duration 包含複製 Raft 日誌到其他 TiKV 節點,保證 raft-log 的持久化。一般包含兩次 Append Log Duration,一次 leader,一次 follower 的。Commit Log Duration 延遲通常會明顯高於 Append Log Duration,因為包含了通過網路複製 Raft 日誌到其他 TiKV 的時間。
- Apply Log Duration 記錄了 apply 執行緒 apply Raft 日誌的延遲。
Commit Log Duration 慢的常見場景:
- TiKV CPU 資源存在瓶頸,排程延遲高
-
raftstore.store-pool-size
設定過小或者過大(過大也可能導致效能下降) - IO 延遲高,導致 Append Log Duration 延遲高
- TiKV 之間的網路延遲比較高
- TiKV 的 gRPC 執行緒數設定過小或者多個 gRPC CPU 資源使用不均衡
Apply Log Duration 慢的常見場景:
- TiKV CPU 資源存在瓶頸,排程延遲高
-
raftstore.apply-pool-size
設定過小或者過大(過大也可能導致效能下降) - IO 延遲比較高
示例 1:同一個 OLTP 負載在 v5.3.0 和 v5.4.0 版本的對比
v5.4.0 版本,一個寫密集的 OLTP 負載 QPS 比 v5.3.0 提升了 14%。 對比這三個關鍵延遲:
Avg Duration | v5.3.0(ms) | v5.4.0(ms) |
---|---|---|
Append Log Duration | 0.27 | 0.303 |
Commit Log Duration | 13 | 8.68 |
Apply Log Duration | 0.457 | 0.514 |
因為 v5.4.0 版本中,TiKV 對 gRPC 模組進行了優化,優化了 Raft 日誌複製速度, 相比 v5.3.0 降低了 Commit Log Duration 和 Store Duration。
v5.3.0:
v5.4.0:
示例 2:Commit Log Duration 瓶頸明顯的例子
平均 Append Log Duration = 4.38 ms
- 平均 Commit Log Duration = 7.92 ms
- 平均 Apply Log Duration = 172 us
Store 執行緒的 Commit Log Duration 明顯比 Apply Log Duration 高,並且 Append Log Duration 比 Apply Log Duration 明顯的高,說明 Store 執行緒在 CPU 和 IO 都可能都存在瓶頸。可能降低 Commit Log Duration 和 Append Log Duration 的方式如下:
- 如果 TiKV CPU 資源充足,考慮增加 Store 執行緒,即
raftstore.store-pool-size
。 - 如果 TiDB 為 v5.4.0 及之後的版本,考慮啟用
,Raft Engine 具有更輕量的執行路徑,在一些場景下顯著減少 IO 寫入量和寫入請求的長尾延遲,啟用方式為設定:
raft-engine.enable: true
- 如果 TiKV CPU 資源充足,且 TiDB 為 v5.3.0 及之後的版本,考慮啟用
。啟用方式:
raftstore.store-io-pool-size: 1
。
低於 v6.1.0 的 TiDB 版本如何使用 Performance overview 皮膚
從 v6.1.0 起,TiDB Grafana 元件預設內建了 Performance Overview 皮膚。Performance overview 皮膚相容 TiDB v4.x 和 v5.x 版本。如果你的 TiDB 版本低於 v6.1.0,需要手動匯入
performance_overview.json 3。
匯入方法如圖所示:
3、OLTP 負載效能優化實踐
https:// tidb.net/blog/f1637cfd
4、Performance Overview 皮膚重要監控指標詳解
https:// tidb.net/blog/90492e9b
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70015299/viewspace-2901608/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- TiDB 效能分析&效能調優&最佳化實踐大全TiDB
- Hive效能調優實踐 - VidhyaHive
- DM 中 relay log 效能優化實踐丨TiDB 工具分享優化TiDB
- 【效能調優】效能測試、分析與調優基礎
- 一次效能壓測及分析調優實踐
- 效能優化,實踐淺談優化
- 軟體效能測試分析與調優實踐之路-Java應用程式的效能分析與調優-手稿節選Java
- 效能調優實戰
- Nginx安全優化與效能調優Nginx優化
- 前端效能優化原理與實踐前端優化
- ⚠️Flutter 效能優化實踐 總結⚠️Flutter優化
- FlutterWeb效能優化探索與實踐FlutterWeb優化
- Flutter效能優化實踐之TimelineFlutter優化
- 2022 前端效能優化最佳實踐前端優化
- 讀小程式效能優優化實踐-筆記優化筆記
- 《軟體效能測試、分析與調優實踐之路》簡介
- HybridDBforPostgreSQL,Greenplum寫入效能優化實踐SQL優化
- Vue 專案效能優化 — 實踐指南Vue優化
- Canvas 動畫的效能優化實踐Canvas動畫優化
- HBase最佳實踐-讀效能優化策略優化
- 基於 PageSpeed 的效能優化實踐優化
- 【前端效能優化】vue效能優化前端優化Vue
- 線上Redis高併發效能調優實踐Redis
- Java 應用效能調優最強實踐指南!Java
- 效能調優——SQL最佳化SQL
- Golang效能分析與優化Golang優化
- 《java學習三》jvm效能優化-------調優JavaJVM優化
- Spark 效能調優--資源調優Spark
- golang 效能調優分析工具 pprof(下)Golang
- golang 效能調優分析工具 pprof (上)Golang
- ElasticSearch效能調優Elasticsearch
- adnroid效能調優
- 六、Android效能優化之UI卡頓分析之渲染效能優化Android優化UI
- 【學習效能分析--第二版】如何做好效能測試分析診斷調優-暨《軟體效能測試、分析與調優實踐之路》(第2版)推薦
- ASP.NET Core 效能優化最佳實踐ASP.NET優化
- 【效能優化實踐】優化打包策略提升頁面載入速度優化
- TiDB 查詢優化及調優系列(一)TiDB 優化器簡介TiDB優化
- 記一次介面效能優化實踐總結:優化介面效能的八個建議優化