TiDB v6.5.6 扩容新增TiKV后PD长期不调度Region,新旧TiKV负载严重不均衡

原有6台TiKV承载全量业务读写,使用tiup scale-out新增3台同规格TiKV,节点正常注册加入集群,磁盘、CPU均空闲。等待24小时PD未生成任何Region迁移Operator,原有TiKV读写负载居高不下,新节点无业务流量;集群未手动配置调度黑名单、限速参数,PD进程日志无报错,运行状态正常。咨询如何排查PD不调度的根因。

1 个赞

截图最好。
305课程有个章节的总结:
tikv扩容后,region不均衡,新节点与其它节点的region差距很大。得分也明显差距大。

PD-Store Region Size:Region Size大小差距很大。

1)是否Store的大小不同导致的不均衡

PD-Statistic-balance-Store available|Store capacity 确定Store大小是否相同

2)确认是否产生调度

PD-Schedule-Filter Source|Filter Target

3)Label是否合理

调度是根据Label来进行的,而不是store id。

pd-ctl store命令可以查看store的labels信息。

结论

Label标签设置错误,与现有重复,导致调度不均衡。

1 个赞

抽空重启下pd试试

TiDB v6.5.6 扩容新增 TiKV 后 PD 长期不迁移 Region,新旧节点负载失衡,PD 日志无报错。

新旧 TiKV 节点 Label 配置不统一,PD 严格按照标签做隔离调度,拒绝跨标签搬迁数据,新节点始终无法分到 Region。

自增主键热点本质是Region分裂机制,AUTO_RANDOM通过分布式ID写入分散。

修改新 TiKV 标签为 zone=zone2,重启 tikv 进程;
PD 识别新故障域后,均衡器会自动生成副本搬迁任务;
副本开始跨 zone 分散,新节点逐步接入 Region

扩容后PD不调度是保护机制,PD控制region迁移速率防止影响线上。检查新TiKV的store状态,必要时调低调度的限流参数。

大概率是集群存在热点region或大量空/小region,导致pd的评分机制误判各节点负载已处于均衡状态,从而未触发region迁移调度。

检查一下新节点的权重

先核对新旧TiKV标签是否一致,标签不匹配会直接阻止PD执行Region调度

新增节点后 region 靠 PD 慢慢调度,可调大 region-schedule-limit、leader-schedule-limit 加速均衡。

扩容后 Region 不迁移,本质是 PD 调度决策层面出了问题。

  • 要么它认为"已经均衡"(Store 打分机制)
  • 要么被"规则约束"卡住(label/limit/空间)
  • 要么调度器本身就没开。
    扩容慢则是 PD 调度执行层面的问题——operator 生成速度受 limit 限制,数据传输速度受 Snapshot 并发数和网络限制。
    诊断的起点永远是 pd-ctl scheduler show + pd-ctl operator show all + pd-ctl store --jq 三条命令。

扩容时 TiDB 各模块是如何协同工作的
下面以新增一个 TiKV 节点(store-4)为例,完整走一遍 PD 和 TiKV 的协作流程:

阶段 1 节点注册(TiKV → PD 心跳)

store-4 启动 → TiKV 向 PD 上报 StoreHeartbeat
                        ↓
           PD 注册新 store,状态 = Up
           但此时没有任何数据,region_count = 0

新节点此时处于"空跑"状态,等待 PD 的调度指令。

阶段 2 PD 生成调度指令(PD 内部决策)

PD 调度器(balance-region-scheduler)分析:
  - store-1/2/3:region_score 高,存储压力大
  - store-4:region_score = 0,完全空闲
  - 结论:store-4 需要接收数据,打分差异足够大 → 生成 operator

  每个 operator 包含三个步骤:
  Step1: AddLearner  → 在 store-4 上为 Region X 添加 learner peer
  Step2: SwitchRole  → store-4 的 learner 变成 voter,store-3 的 follower 降级为 learner
  Step3: RemovePeer  → 删除 store-3 上多余的 learner 副本

关键约束检查(每一步都受这些限制):

  • 目标 store 不能是 Down/Offline/Busy/空间不足/正在大量收发 Snapshot
  • 不能破坏 Label 隔离约束
  • region-schedule-limit 控制同时在跑的 operator 数量上限

阶段 3 通过心跳下发指令(PD → TiKV Leader)

PD 将 operator 通过心跳下发给 Region X 的 Leader 所在节点
Leader 节点在 Raft Group 内广播这条消息
所有成员确认后,Step1 开始执行

阶段 4 Snapshot 数据传输(TiKV 之间)

这是最慢的一步,也最容易成为瓶颈:

  store-3(Leader)→ 生成 Region X 的完整 Snapshot
                  → 通过 gRPC 传输给 store-4
                  → store-4 收到后回确认
                  → PD 收到心跳告知 Step1 完成

  Step2(角色互换)是纯元数据变更,毫秒级完成

  Step3(删除旧副本)→ store-3 删除本地副本数据

整个过程耗时取决于:
  - Snapshot 大小(Region 默认约 96 MiB)
  - 网络带宽
  - max-snapshot-count 限制(并发 Snapshot 数上限)
  - TiKV 的 CPU/IO 是否被业务压满

阶段 5 循环往复,直至均衡

PD 持续监控打分差异 → 生成下一批 operator → TiKV 执行
直到所有 store 的 region_score 接近 → operator 生成停止 → 扩容完成