作者:黃夢龍
本文将詳細介紹 PD 排程系統的原理,并通過幾個典型場景的分析和處理方式,分享排程政策的最佳實踐和調優方式,幫助大家在使用過程中快速定位問題。本文假定你對 TiDB,TiKV 以及 PD 已經有一定的了解,相關核心概念如下:
- Leader/Follower/Learner
- Operator
- Operator Step
- Pending/Down
- Region/Peer/Raft Group
- Region Split
- Scheduler
- Store
注意:
本文内容基于 TiDB 3.0 版本,更早的版本(2.x)缺少部分功能的支援,但是基本原理類似,也可以以本文作為參考。
PD 排程原理
該部分介紹排程系統涉及到的相關原理和流程。
排程流程
宏觀上來看,排程流程大體可劃分為 3 個部分:
- 資訊收集TiKV 節點周期性地向 PD 上報
和StoreHeartbeat
兩種心跳消息。其中RegionHeartbeat
包含了 Store 的基本資訊、容量、剩餘空間、讀寫流量等資料;StoreHeartbeat
包含了 Region 的範圍、副本分布、副本狀态、資料量、以及讀寫流量等資料。PD 将這些資訊梳理并轉存供排程來決策。RegionHeartbeat
- 生成排程不同的排程器從自身的邏輯和需求出發,考慮各種限制和限制後生成待執行的 Operator。這裡所說的限制和限制包括但不限于:
- 不往斷連中、下線中、繁忙、空間不足、在大量收發 snapshot 等各種異常狀态的 Store 添加副本
- Balance 時不選擇狀态異常的 Region
- 不嘗試把 Leader 轉移給 Pending Peer
- 不嘗試直接移除 Leader
- 不破壞 Region 各種副本的實體隔離
- 不破壞 Label property 等限制
- 執行排程生成的 Operator 不會立即開始執行,而是首先會進入一個由 OperatorController 管理的一個等待隊列。OperatorController 會根據配置以一定的并發量從等待隊列中取出 Operator 并執行。執行的過程就是依次把每個 Operator Step 下發給對應 Region 的 Leader。最終 Operator 執行完畢會被标記為 finish 狀态或者逾時被标記為 timeout,并被從執行清單中移除。
負載均衡
Region 負載均衡排程主要依賴
balance-leader
和
balance-region
這兩個排程器。這二者的排程目标是将 Region 均勻地分散在叢集中的所有 Store 上,但它們的側重點又有所不同:
balance-leader
關注 Region 的 Leader,目的是分散處理用戶端請求的壓力;
balance-region
關注 Region 的各個 Peer,目的是分散存儲的壓力,同時避免出現爆盤等狀況。
balance-leader
與
balance-region
有着相似的排程流程,首先根據不同 Store 的對應資源量的情況分别打分,然後不斷從得分較高的 Store 選擇 Leader 或 Peer 遷移到得分較低的 Store 上。這兩者的分數計算上也有一定差異:
balance-leader
比較簡單,使用 Store 上所有 Leader 所對應的 Region Size 加和作為得分。
balance-region
得分因為不同節點存儲容量可能不一緻,會分以下三種情況:
- 當空間富餘時使用資料量計算得分(使不同節點資料量基本上均衡)
- 當空間不足時由使用剩餘空間計算得分(使不同節點剩餘空間基本均衡)
- 處于中間态時則同時考慮兩個因素做權重和當作得分
此外,為了應對不同節點可能在性能等方面存在差異的問題,還可為 Store 設定負載均衡的權重。
leader-weight
和
region-weight
分别用于控制 Leader 權重以及 Region 權重(預設值都為 1)。假如把某個 Store 的
leader-weight
設為 2,排程穩定後,則該節點的 leader 數量約為普通節點的 2 倍;假如把某個 Store 的
region-weight
設為 0.5,那麼排程穩定後該節點的 Region 數量約為其他節點的一半。
熱點排程
熱點排程對應的排程器是 hot-region-scheduler。目前 3.0 版本統計熱點 Region 的方式比較單一,就是根據 Store 上報的資訊,統計出持續一段時間讀或寫流量超過一定門檻值的 Region,然後再用與負載均衡類似的方式把這些 Region 分散開來。
對于寫熱點,熱點排程會同時嘗試打散熱點 Region 的 Peer 和 Leader;對于讀熱點,由于隻有 Leader 承載讀壓力,熱點排程會嘗試将熱點 Region 的 Leader 打散。
叢集拓撲感覺
讓 PD 感覺不同節點分布的拓撲是為了通過排程使不同 Region 的各個副本盡可能分散,保證高可用和容災。PD 會在背景不斷掃描所有 Region,當發現 Region 的分布不是目前的最優化狀态時,會生成排程以替換 Peer,将 Region 調整至最佳狀态。
負責這個檢查的元件叫
replicaChecker
(跟 Scheduler 類似,但是不可關閉)。它依賴于
location-labels
配置項來進行排程。比如配置
[zone, rack, host]
定義了三層的拓撲結構:叢集分為多個 zone(可用區),每個 zone 下有多個 rack(機架),每個 rack 下有多個 host(主機)。PD 在排程時首先會嘗試将 Region 的 Peer 放置在不同的 zone,假如無法滿足(比如配置 3 副本但總共隻有 2 個 zone)則保證放置在不同的 rack;假如 rack 的數量也不足以保證隔離,那麼再嘗試 host 級别的隔離,以此類推。
縮容及故障恢複
縮容是指預備将某個 Store 下線,通過指令将該 Store 标記為 Offline 狀态,此時 PD 通過排程将待下線節點上的 Region 遷移至其他節點。故障恢複是指當有 Store 發生故障且無法恢複時,有 Peer 分布在對應 Store 上的 Region 會産生缺少副本的狀況,此時 PD 需要在其他節點上為這些 Region 補副本。
這兩種情況的處理過程基本上是一樣的。由
replicaChecker
檢查到 Region 存在異常狀态的 Peer,然後生成排程在健康的 Store 建立新副本替換掉異常的。
Region merge
Region merge 指的是為了避免删除資料後大量小甚至空的 Region 消耗系統資源,通過排程把相鄰的小 Region 合并的過程。Region merge 由
mergeChecker
負責,其過程與
replicaChecker
類似,也是在背景周遊,發現連續的小 Region 後發起排程。
查詢排程狀态
檢視排程系統狀态的手段主要包括 Metrics,pd-ctl 和日志,這裡介紹 Metrics 和 pd-ctl 兩種方式。更具體的資訊可以參考官方文檔中 PD 監控以及 PD Control 使用的章節。
Operator 狀态
Grafana PD/Operator 頁面展示了 Operator 的相關統計。其中比較重要的有:
- Schedule Operator Create:Operator 的建立情況。從名稱可以知道 Operator 建立的目标排程器以及建立原因。
- Operator finish duration:Operator 執行耗時的情況
- Operator Step duration:不同 Operator Step 執行耗時的情況
查詢 Operator 的 pd-ctl 指令有:
-
:查詢目前排程生成的所有 Operatoroperator show
-
:按照類型查詢 Operatoroperator show [admin | leader | region]
Balance 狀态
Grafana PD/Statistics - Balance 頁面展示了負載均衡相關的統計資訊,其中比較重要的有:
- Store Leader/Region score:每個 Store 的得分
- Store Leader/Region count:每個 Store 的 Leader/Region 數量
- Store available:每個 Store 的剩餘空間
使用 pd-ctl 的 store 指令可以查詢 Store 的得分,數量,剩餘空間,weight 等資訊。
熱點排程狀态
Grafana PD/Statistics - hotspot 頁面展示了熱點 Region 的相關統計,其中比較重要的有:
- Hot write Region’s leader/peer distribution:寫熱點 Region 的 Leader/Peer 分布情況
- Hot read Region’s leader distribution:讀熱點 Region 的 Leader 分布情況
使用 pd-ctl 同樣可以查詢上述資訊,可以使用的指令有:
-
:查詢讀熱點 Region 資訊hot read
-
:查詢寫熱點 Region 資訊hot write
-
:按 Store 統計熱點分布情況hot store
-
:查詢目前讀流量最大的 Regionregion topread [limit]
-
:查詢目前寫流量最大的 Regionregion topwrite [limit]
Region 健康度
Grafana PD/Cluster/Region health 面闆展示了異常狀态 Region 數的統計,其中包括 Pending Peer,Down Peer,Offline Peer,以及副本數過多或過少的 Region。
通過 pd-ctl 的 region check 指令可以檢視具體異常的 Region 清單:
-
:缺副本的 Regionregion check miss-peer
-
:多副本的 Regionregion check extra-peer
-
:有副本狀态為 Down 的 Regionregion check down-peer
-
:有副本狀态為 Pending 的 Regionregion check pending-peer
排程政策控制
線上調整排程政策主要使用 pd-ctl 工具來完成,可以通過以下三個方面來控制 PD 的排程行為。更具體的資訊可以參考 PD Control。
啟停排程器
pd-ctl 支援動态建立和删除 Scheduler 的功能,我們可以通過這些操作來控制 PD 的排程行為,如下所示:
-
:顯示目前系統中的 Schedulerscheduler show
-
:删除(停用)balance leader 排程器scheduler remove balance-leader-scheduler
-
:添加移除 Store 1 的所有 Leader 的排程器scheduler add evict-leader-scheduler-1
手動添加 Operator
PD 還支援繞過排程器,直接通過 pd-ctl 來建立或删除 Operator,如下所示:
-
:在 Store 5 上為 Region 2 添加 Peeroperator add add-peer 2 5
-
:将 Region 2 的 Leader 遷移至 Store 5operator add transfer-leader 2 5
-
:将 Region 2 拆分為 2 個大小相當的 Regionoperator add split-region 2
-
:取消 Region 2 目前待執行的 Operatoroperator remove 2
排程參數調整
使用 pd-ctl 執行
config show
指令可以檢視所有的排程參數,執行
config set {key} {value}
可以調整對應參數的值。常見調整如下:
-
:控制 Transfer Leader 排程的并發數leader-schedule-limit
-
:控制增删 Peer 排程的并發數region-schedule-limit
-
:停止處理節點下線的排程disable-replace-offline-replia
-
:停止處理調整 Region 隔離級别相關的排程disable-location-replacement
-
:每個 Store 允許的最大收發 Snapshot 的并發數max-snapshot-count
典型場景分析與處理
該部分通過幾個典型場景及其應對方式說明 PD 排程政策的最佳實踐。
Leader/Region 分布不均衡
PD 的打分機制決定了一般情況下,不同 Store 的 Leader Count 和 Region Count 不能完全說明負載均衡狀态,需要從 TiKV 的實際負載或者存儲空間占用來判斷是否有負載不均衡的狀況。
确認存在 Leader/Region 分布不均衡的現象後,首先要觀察不同 Store 的打分情況。
如果不同 Store 的打分是接近的,說明 PD 認為此時已經是均衡狀态了,可能的原因有:
- 存在熱點導緻負載不均衡。需要根據熱點排程相關的資訊進一步分析,可以參考下文熱點排程的部分。
- 存在大量的空 Region 或小 Region,導緻不同 Store 的 Leader 數量差别特别大,導緻 raftstore 負擔過重。需要開啟 Region Merge 并盡可能加速合并,可以參考下文關于 Region Merge 的部分。
- 不同 Store 的軟硬體環境存在差異。可以酌情調整
和leader-weight
來控制 Leader/Region 的分布。region-weight
- 其他不明原因。可以使用調整權重這個兜底的方法,通過調整
和leader-weight
來調整至使用者覺得合理的分布。region-weight
如果不同 Store 的打分差異較大,需要進一步檢查 Operator 相關 Metrics,特别關注 Operator 的生成和執行情況,這時大體上又分兩種情況:
- 一種情況是生成的排程是正常的,但是排程的速度很慢。可能的原因有:
- 排程速度受限于 limit 配置。PD 預設配置的 limit 比較保守,在不對正常業務造成顯著影響的前提下,可以酌情将
或leader-schedule-limit
調大一些。此外,region-schedule-limit
以及max-pending-peer-count
限制也可以放寬。max-snapshot-count
- 系統中同時運作有其它的排程任務産生競争,導緻 balance 速度上不去。這種情況下如果 balance 排程的優先級更高,可以先停掉其他的排程或者限制其他排程的速度。例如 Region 沒均衡的情況下做下線節點操作,下線的排程與 Region Balance 會搶占
配額,此時我們可以把region-schedule-limit
調小将下線排程的速度限制住,或者幹脆設定replica-schedule-limit
來暫時關閉下線流程。disable-replace-offline-replica = true
- 排程執行得太慢。可以檢查 Operator Step 的耗時來進行判斷。通常不涉及到收發 Snapshot 的 Step(比如 TransferLeader,RemovePeer,PromoteLearner 等)的完成時間應該在毫秒級,涉及到 Snapshot 的 Step(如 AddLearner,AddPeer 等)的完成時間為數十秒。如果耗時明顯過高,可能是 TiKV 壓力過大或者網絡等方面的瓶頸導緻的,需要具體情況具體分析。
- 另一種情況是沒能生成對應的 balance 排程。可能的原因有:
- 排程器未被啟用。比如對應的 Scheduler 被删除了,或者 limit 被設定為 0。 由于其它限制無法進行排程。比如系統中有 evict-leader-scheduler,此時無法把 Leader 遷移至對應的 Store。再比如設定了 Label property,也會導緻部分 Store 不接受 Leader。
- 叢集拓撲的限制導緻無法均衡。比如 3 副本 3 資料中心的叢集,由于副本隔離的限制,每個 Region 的 3 個副本都分别分布在不同的資料中心,假如這 3 個資料中心的 Store 數不一樣,最後排程就會收斂在每個資料中心均衡,但是全局不均衡的狀态。
節點下線速度慢
這個場景需要從 Operator 相關的 Metrics 入手,分析 Operator 的生成執行情況。
如果排程在正常生成,隻是速度很慢,可能的原因有:
- 排程速度受限于 limit 配置。下線對應的 limit 參數是
,可以把它适當調大。與 Balance 類似,replica-schedule-limit
以及max-pending-peer-count
限制同樣也可以放寬。max-snapshot-count
- 系統中同時運作有其它的排程任務産生競争,或者排程執行得太慢了。處理方法在上一節已經介紹過了,不再贅述。
- 下線單個節點時,由于待操作的 Region 有很大一部分(3 副本配置下約 1/3)的 Leader 都集中在下線的節點上,下線速度會受限于這個單點生成 Snapshot 的速度。可以通過手動給這個節點添加一個 evict-leader 排程遷走 Leader 來加速。
如果沒有對應的 Operator 排程生成,可能的原因有:
- 下線排程被關閉,或者
被設為 0。replica-schedule-limit
- 找不到節點來轉移 Region。例如相同 Label 的替代節點容量都大于 80%,PD 為了避免爆盤的風險會停止排程。這種情況需要添加更多節點,或者删除一些資料釋放空間。
節點上線速度慢
目前 PD 沒有對節點上線特殊處理。節點上線實際上是依靠 balance region 機制來排程的,是以參考前面 Region 分布不均衡的排查步驟即可。
熱點分布不均勻
熱點排程的問題大體上可以分為以下幾種情況:
- 從 PD 的 metrics 能看出來有不少 hot Region,但是排程速度跟不上,不能及時地把熱點 Region 分散開來。
解決方法 :加大
hot-region-schedule-limit
,并減少其他排程器的 limit 配額,進而加快熱點排程的速度。還可調小
hot-region-cache-hits-threshold
以使 PD 對流量的變化更快做出反應。
- 單一 Region 形成熱點,比如大量請求頻繁 scan 一個小表,這個可以從業務角度或者 metrics 統計的熱點資訊看出來。由于單 Region 熱點現階段無法使用打散的手段來消除,需要确認熱點 Region 後手動添加
排程将這樣的 Region 拆開。split-region
- 從 PD 的統計來看沒有熱點,但是從 TiKV 的相關 metrics 可以看出部分節點負載明顯高于其他節點,成為整個系統的瓶頸。這是因為目前 PD 統計熱點 Region 的次元比較單一,僅針對流量進行分析,在某些場景下無法準備定位出熱點。例如部分 Region 有大量的點查請求,從流量上來看并不顯著,但是過高的 QPS 導緻關鍵子產品達到瓶頸。解決方法:首先從業務層面确定形成熱點的 table,然後添加
來使得這個 table 的所有 Region 均勻分布。TiDB 也在其 HTTP API 中提供了相關接口來簡化這個操作,具體可以參考TiDB HTTP API 文檔。scatter-range-scheduler
Region Merge 速度慢
與前面讨論過的排程慢的問題類似,Region Merge 速度慢也很有可能是受到 limit 配置的限制(
merge-schedule-limit
及
region-schedule-limit
),或者是與其他排程器産生了競争。具體來說,可有如下處理方式:
- 假如已經從統計得知系統中有大量的空 Region,這時可以通過把
和 max-merge-region-size
調整為較小值來加快 Merge 速度。這是因為 Merge 的過程涉及到副本遷移,于是 Merge 的 Region 越小,速度就越快。如果 Merge Operator 生成的速度已經有幾百 opm,想進一步加快 Region Merge 過程,還可以把 max-merge-region-keys
調整為 “10ms” ,這個能加快巡檢 Region 的速度,但是會消耗更多的 CPU。patrol-region-interval
- 曾經建立過大量 Table 然後又清空了(truncate 操作也算建立 Table)。此時如果開啟了 split table 特性,這些空 Region 是無法合并的,此時需要調整以下參數關閉這個特性:
- TiKV:
設為 falsesplit-region-on-table
- PD:
設為 “”namespace-classifier
- 對于 3.0.4 和 2.1.16 以前的版本,Region 的統計 approximate_keys 在特定情況下(大部分發生在 drop table 之後)統計不準确,造成 keys 的統計值很大,無法滿足
的限制,可以把 max-merge-region-keys
這個條件放開,調成很大的值來繞過這個問題。max-merge-region-keys