Fork me on GitHub

NewSQL 系列(中篇)- 存储引擎与调度机制

NewSQL 系列(中篇)- 存储引擎与调度机制

目录

  1. TiKV 存储引擎详解
  2. 1.1 RocksDB 存储引擎
  3. 1.2 Raft 共识协议
  4. 1.3 MVCC 多版本并发控制
  5. 1.4 分布式事务实现
  6. TiFlash 列式存储
  7. 2.1 架构设计
  8. 2.2 数据同步机制
  9. 2.3 MPP 执行模式
  10. 2.4 算子下推优化
  11. PD 调度机制
  12. 3.1 核心职责
  13. 3.2 心跳机制
  14. 3.3 调度流程
  15. 3.4 平衡策略

1. TiKV 存储引擎详解

TiKV 是 TiDB 的分布式事务键值存储引擎,负责数据的持久化存储、副本管理和事务处理。它是 TiDB 架构中最核心的组件之一。

1.1 RocksDB 存储引擎

嵌入式 KV 存储

TiKV 使用 RocksDB 作为底层存储引擎。RocksDB 是由 Facebook 开发的高性能嵌入式 KV 存储库,基于 LSM-Tree(Log-Structured Merge-Tree)数据结构。

┌──────────────────────────────────────────────────────────────┐
│                    RocksDB 架构                              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                     Write Ahead Log (WAL)            │   │
│   │  • 预写日志,保证数据持久性                            │   │
│   │  • 顺序写入,高性能                                   │   │
│   └─────────────────────────────────────────────────────┘   │
│                           │                                  │
│                           ▼                                  │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                      MemTable                        │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │              内存中的有序数据                   │  │   │
│   │  │  • 跳表 (Skip List) 结构                        │  │   │
│   │  │  • 写入时更新 MemTable                          │  │   │
│   │  │  • 达到阈值后刷写到磁盘                         │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│                           │                                  │
│                           ▼ 刷写 (Flush)                     │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                      SSTable                         │   │
│   │  ┌─────────┐  ┌─────────┐  ┌─────────┐            │   │
│   │  │ Level 0 │  │ Level 1 │  │ Level 2 │  ...       │   │
│   │  │ (无序)   │  │ (有序)   │  │ (有序)   │            │   │
│   │  └─────────┘  └─────────┘  └─────────┘            │   │
│   │       │              │              │               │   │
│   │       └──────────────┴──────────────┘               │   │
│   │                  Compaction (合并)                    │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
└──────────────────────────────────────────────────────────────┘

LSM-Tree 工作原理:

写入流程:
┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐
│  写入    │───▶│   WAL   │───▶│MemTable │───▶│ SSTable │
│  请求    │    │  (日志)  │    │  (内存)  │    │  (磁盘)  │
└─────────┘    └─────────┘    └─────────┘    └─────────┘
     │              │              │              │
     │              │              │              │
     ▼              ▼              ▼              ▼
  追加写         顺序写          内存操作        顺序写
  高性能         可恢复          低延迟         高性能

关键特性:

特性 说明 性能影响
顺序写入 WAL 和 SSTable 都是顺序写 写入性能提升 10-100 倍
批量提交 多次写入合并为一次磁盘操作 减少 I/O 次数
延迟刷写 MemTable 积累到阈值再刷盘 amortize 写入成本
分层存储 多层 SSTable,逐层合并 平衡读写性能
布隆过滤器 快速判断 key 是否存在 减少不必要的磁盘读取

TiKV 中的优化:

┌──────────────────────────────────────────────────────────────┐
│                  TiKV 对 RocksDB 的优化                       │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  1. 分区优化                                                 │
│     ┌────────────────────────────────────────────────────┐  │
│     │  • 每个 Region 独立的 RocksDB 实例                     │  │
│     │  • 避免大 Region 影响整体性能                        │  │
│     │  • 支持 Region 级别的 Compaction                     │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
│  2. 写入优化                                                 │
│     ┌────────────────────────────────────────────────────┐  │
│     │  • 批量写入 (Write Batch)                           │  │
│     │  • 异步刷盘配置                                     │  │
│     │  • 写入限流 (避免 Compaction 风暴)                    │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
│  3. 读取优化                                                 │
│     ┌────────────────────────────────────────────────────┐  │
│     │  • Block Cache (LRU 缓存)                           │  │
│     │  • 布隆过滤器优化                                   │  │
│     │  • 前缀搜索优化                                     │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
│  4. Compaction 优化                                          │
│     ┌────────────────────────────────────────────────────┐  │
│     │  • 分级 Compaction 策略                             │  │
│     │  • 后台线程池管理                                   │  │
│     │  • 动态调整 Compaction 参数                         │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

性能指标:

典型性能数据(SSD 环境):
┌────────────────────────────────────────────────────────┐
│  操作类型          │  延迟 (P99)    │  吞吐量          │
├────────────────────────────────────────────────────────┤
│  点查 (Get)        │  < 5ms         │  50K+ QPS       │
│  范围扫描 (Scan)   │  < 10ms        │  10K+ QPS       │
│  写入 (Put)        │  < 10ms        │  30K+ QPS       │
│  批量写入          │  < 50ms        │  100K+ QPS      │
└────────────────────────────────────────────────────────┘

1.2 Raft 共识协议

分布式一致性保证

TiKV 使用 Raft 协议来保证数据的一致性和高可用性。每个 Region(数据分片)都有多个副本(通常 3 个),通过 Raft 协议保持数据一致。

┌──────────────────────────────────────────────────────────────┐
│                    Raft 协议架构                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│                        Region Group                          │
│  ┌────────────────────────────────────────────────────────┐ │
│  │                                                        │ │
│  │    ┌─────────┐                                         │ │
│  │    │ Leader  │ ◄─── 处理所有读写请求                    │ │
│  │    │ Node 1  │                                         │ │
│  │    └────┬────┘                                         │ │
│  │         │ Replicate                                    │ │
│  │    ┌────┴────┐                                         │ │
│  │    │         │                                         │ │
│  │  ┌─▼─────┐ ┌─▼─────┐                                   │ │
│  │  │Follower│ │Follower│  ◄─── 接收日志复制                │ │
│  │  │Node 2  │ │Node 3  │                                   │ │
│  │  └───────┘ └───────┘                                   │ │
│  │                                                        │ │
│  │  副本数 = 3, 容错 = 1 (多数派 = 2)                       │ │
│  │                                                        │ │
│  └────────────────────────────────────────────────────────┘ │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Raft 核心概念:

┌──────────────────────────────────────────────────────────────┐
│                     Raft 核心概念                            │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  1. 角色 (Roles)                                             │
│     ┌────────────────────────────────────────────────────┐  │
│     │  Leader    │  领导者,处理所有客户端请求              │  │
│     │  Follower  │  跟随者,被动接收日志复制               │  │
│     │  Candidate │  候选人,参与 Leader 选举                │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
│  2. 日志复制 (Log Replication)                               │
│     ┌────────────────────────────────────────────────────┐  │
│     │  1. Leader 接收客户端写入                            │  │
│     │  2. Leader 将日志追加到本地                          │  │
│     │  3. Leader 并行复制给所有 Follower                   │  │
│     │  4. 多数派确认后提交日志                            │  │
│     │  5. Leader 通知 Follower 应用日志                     │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
│  3. 选举机制 (Leader Election)                               │
│     ┌────────────────────────────────────────────────────┐  │
│     │  • 基于任期的选举 (Term-based)                       │  │
│     │  • 随机超时触发选举                                 │  │
│     │  • 多数票当选                                       │  │
│     │  • 日志最新的节点优先                               │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
│  4. 安全性保证 (Safety)                                      │
│     ┌────────────────────────────────────────────────────┐  │
│     │  • 选举限制:只有包含所有已提交日志的节点才能当选     │  │
│     │  • 日志匹配:Follower 日志必须与 Leader 一致          │  │
│     │  • 状态机安全:所有节点按相同顺序应用日志             │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

写入流程详解:

┌──────────────────────────────────────────────────────────────┐
│                    Raft 写入流程                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   客户端                                                      │
│      │                                                       │
│      │ Write(key, value)                                     │
│      ▼                                                       │
│   ┌─────────────┐                                            │
│   │   Leader    │  ① 接收写入请求                            │
│   │   Node 1    │                                            │
│   └──────┬──────┘                                            │
│          │                                                    │
│          │ ② 追加本地日志                                     │
│          ▼                                                    │
│   ┌─────────────┐                                            │
│   │ AppendEntry │  ③ 并行复制到 Follower                      │
│   └──────┬──────┘                                            │
│     ┌────┴────┐                                              │
│     │         │                                              │
│     ▼         ▼                                              │
│ ┌───────┐ ┌───────┐                                          │
│ │Node 2 │ │Node 3 │  ④ Follower 确认接收                       │
│ └───┬───┘ └───┬───┘                                          │
│     │         │                                              │
│     └────┬────┘                                              │
│          │                                                    │
│          │ ⑤ 多数派确认 (2/3)                                  │
│          ▼                                                    │
│   ┌─────────────┐                                            │
│   │   Commit    │  ⑥ 提交日志                                │
│   └──────┬──────┘                                            │
│          │                                                    │
│          │ ⑦ 通知应用日志                                     │
│          ▼                                                    │
│   ┌─────────────┐                                            │
│   │   Respond   │  ⑧ 返回客户端                              │
│   └─────────────┘                                            │
│                                                              │
│   总延迟 = 网络 RTT × 2 + 本地处理时间                        │
│                                                              │
└──────────────────────────────────────────────────────────────┘

故障恢复:

┌──────────────────────────────────────────────────────────────┐
│                    Leader 故障恢复                            │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   正常状态:                                                  │
│   ┌─────────┐                                                │
│   │ Leader  │───▶ 处理请求                                   │
│   └─────────┘                                                │
│                                                              │
│   故障发生:                                                  │
│   ┌─────────┐                                                │
│   │  ✕✕✕   │  ◄─── Leader 宕机                               │
│   └─────────┘                                                │
│                                                              │
│   选举触发:                                                  │
│   ┌─────────┐    ┌─────────┐                                │
│   │Candidate│    │Candidate│  ◄─── Follower 超时转为 Candidate  │
│   └─────────┘    └─────────┘                                │
│                                                              │
│   新 Leader 产生:                                            │
│   ┌─────────┐                                                │
│   │ Leader  │  ◄─── 获得多数票当选                            │
│   │ (New)   │                                                │
│   └─────────┘                                                │
│                                                              │
│   恢复时间:通常 < 10 秒                                       │
│                                                              │
└──────────────────────────────────────────────────────────────┘

TiKV 中的 Raft 实现优化:

优化项 说明 效果
Raft Store 多个 Region 共享 Raft 实例 减少资源消耗
批量复制 多个日志条目批量发送 降低网络开销
异步复制 日志复制异步进行 提高写入吞吐
Read Index 线性一致读优化 减少 Leader 确认开销
Lease Read 租约机制加速本地读 读延迟降低 50%+

1.3 MVCC 多版本并发控制

并发控制核心

MVCC(Multi-Version Concurrency Control)是 TiKV 实现高并发事务的核心机制。它通过维护数据的多个版本,实现读写不阻塞,提高并发性能。

┌──────────────────────────────────────────────────────────────┐
│                      MVCC 数据模型                           │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   每个 Key 在 TiKV 中存储三个 Column Family:                   │
│                                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                    Lock CF                           │   │
│   │  • 存储当前事务的锁信息                               │   │
│   │  • 事务提交或删除时清理                               │   │
│   │  • 格式:key → LockInfo                              │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                    Write CF                          │   │
│   │  • 存储提交记录(版本元数据)                         │   │
│   │  • 包含 start_ts 和 commit_ts                        │   │
│   │  • 格式:key@commit_ts → start_ts                    │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                    Data CF                           │   │
│   │  • 存储实际的数据值                                   │   │
│   │  • 按 start_ts 索引                                  │   │
│   │  • 格式:key@start_ts → value                        │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
└──────────────────────────────────────────────────────────────┘

版本管理:

┌──────────────────────────────────────────────────────────────┐
│                    MVCC 版本链                              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   Key: "user:1001"                                           │
│                                                              │
│   Write CF (提交记录):                                        │
│   ┌────────────────────────────────────────────────────┐    │
│   │ "user:1001"@100  →  start_ts=90, type=PUT          │    │
│   │ "user:1001"@80   →  start_ts=70, type=PUT          │    │
│   │ "user:1001"@60   →  start_ts=50, type=PUT          │    │
│   │ "user:1001"@40   →  start_ts=30, type=PUT          │    │
│   │ "user:1001"@20   →  start_ts=10, type=PUT          │    │
│   └────────────────────────────────────────────────────┘    │
│                                                              │
│   Data CF (实际数据):                                         │
│   ┌────────────────────────────────────────────────────┐    │
│   │ "user:1001"@90  →  {"name": "Alice", "age": 25}    │    │
│   │ "user:1001"@70  →  {"name": "Alice", "age": 24}    │    │
│   │ "user:1001"@50  →  {"name": "Alice", "age": 23}    │    │
│   │ "user:1001"@30  →  {"name": "Alice", "age": 22}    │    │
│   │ "user:1001"@10  →  {"name": "Alice", "age": 21}    │    │
│   └────────────────────────────────────────────────────┘    │
│                                                              │
│   读取时:根据读版本号,找到对应的历史版本                      │
│   例如:read_ts=85 → 找到 commit_ts=80 的版本                  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

读写流程:

┌──────────────────────────────────────────────────────────────┐
│                    MVCC 读写流程                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  【写事务】                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  1. 获取 start_ts (从 PD)                               │  │
│  │  2. 检查冲突 (检查 Lock CF 和 Write CF)                  │  │
│  │  3. 写入 Lock CF (加锁)                                 │  │
│  │  4. 写入 Data CF (实际数据)                            │  │
│  │  5. 提交事务                                           │  │
│  │  6. 获取 commit_ts (从 PD)                             │  │
│  │  7. 写入 Write CF (提交记录)                           │  │
│  │  8. 删除 Lock CF (解锁)                                │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  【读事务】                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  1. 获取读版本号 (start_ts 或当前时间戳)                │  │
│  │  2. 检查 Lock CF (是否有未提交的写)                     │  │
│  │  3. 扫描 Write CF (找到 ≤ 读版本的最大 commit_ts)        │  │
│  │  4. 根据 Write CF 的 start_ts 读取 Data CF               │  │
│  │  5. 返回数据                                          │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

隔离级别:

TiKV 支持两种事务隔离级别:

┌──────────────────────────────────────────────────────────────┐
│                    事务隔离级别                              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  1. SI (Snapshot Isolation, 快照隔离)                         │
│     ┌────────────────────────────────────────────────────┐  │
│     │  • 读操作看到事务开始时的快照                        │  │
│     │  • 写操作检查写冲突                                 │  │
│     │  • 允许写偏斜 (Write Skew) 异常                       │  │
│     │  • 性能较高,适合大多数场景                         │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
│  2. SSI (Snapshot Isolation + Serializable)                   │
│     ┌────────────────────────────────────────────────────┐  │
│     │  • 在 SI 基础上增加写冲突检测                         │  │
│     │  • 防止写偏斜异常                                   │  │
│     │  • 严格可串行化                                     │  │
│     │  • 性能略低,适合金融等强一致场景                   │  │
│     └────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

1.4 分布式事务实现

Percolator 事务模型

TiKV 使用改进的 Percolator 事务模型来实现分布式事务。Percolator 是 Google 提出的分布式事务协议,基于乐观并发控制和两阶段提交。

┌──────────────────────────────────────────────────────────────┐
│                  Percolator 事务模型                         │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   两阶段提交 (2PC):                                          │
│                                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                   Phase 1: Prewrite                  │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  1. 选择 Primary Key (通常是第一个 Key)          │  │   │
│   │  │  2. 对 Primary Key 进行 Prewrite                 │  │   │
│   │  │  3. 对其他 Key 进行 Prewrite (并行)              │  │   │
│   │  │  4. 所有 Prewrite 成功后进入 Phase 2              │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                   Phase 2: Commit                    │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  1. 提交 Primary Key                           │  │   │
│   │  │  2. 异步提交其他 Key (后台进行)                  │  │   │
│   │  │  3. Primary Key 提交成功后,事务即视为成功        │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
└──────────────────────────────────────────────────────────────┘

事务流程详解:

┌──────────────────────────────────────────────────────────────┐
│                    分布式事务完整流程                         │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   客户端                                                      │
│      │                                                       │
│      │ BEGIN TRANSACTION                                     │
│      ▼                                                       │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Step 1: 获取时间戳                                    │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  Client ──▶ PD (Get Timestamp)                │  │   │
│   │  │  Client ◀── PD (start_ts = 100)               │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│      │                                                       │
│      │ WRITE key1, key2, key3                                │
│      ▼                                                       │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Step 2: Prewrite 阶段                                │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  • 选择 key1 为 Primary Key                      │  │   │
│   │  │  • Prewrite(key1, start_ts=100) ──▶ TiKV1     │  │   │
│   │  │  • Prewrite(key2, start_ts=100) ──▶ TiKV2     │  │   │
│   │  │  • Prewrite(key3, start_ts=100) ──▶ TiKV3     │  │   │
│   │  │  • 所有节点返回成功                              │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│      │                                                       │
│      │ COMMIT                                                │
│      ▼                                                       │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Step 3: Commit 阶段                                  │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  Client ──▶ PD (Get Timestamp)                │  │   │
│   │  │  Client ◀── PD (commit_ts = 110)              │  │   │
│   │  │  Commit(key1, start_ts=100, commit_ts=110)    │  │   │
│   │  │  Async Commit(key2, key3) ──▶ 后台进行         │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│      │                                                       │
│      │ TRANSACTION COMMITTED                                 │
│                                                              │
└──────────────────────────────────────────────────────────────┘

乐观事务 vs 悲观事务:

┌──────────────────────────────────────────────────────────────┐
│                  乐观事务 vs 悲观事务                         │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  乐观事务 (Optimistic Transaction)                           │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 假设冲突很少发生                                   │  │
│  │  • 提交时才检查冲突                                   │  │
│  │  • 冲突时回滚重试                                     │  │
│  │  • 适合读多写少场景                                   │  │
│  │  • 性能较高                                           │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  悲观事务 (Pessimistic Transaction)                          │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 假设冲突经常发生                                   │  │
│  │  • 写入前先加锁                                       │  │
│  │  • 减少提交时的冲突                                   │  │
│  │  • 适合写多写冲突多场景                               │  │
│  │  • 性能略低但更稳定                                   │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  选择建议:                                                  │
│  • 默认使用乐观事务                                          │
│  • 写冲突频繁时切换为悲观事务                                 │
│  • 可通过 SQL Hint 指定:/*+ TIDB_TXN_MODE = 'pessimistic' */ │
│                                                              │
└──────────────────────────────────────────────────────────────┘

事务性能优化:

优化技术 说明 效果
Async Commit 异步提交 Secondary Keys 减少提交延迟
1PC 单 Region 事务优化为 1PC 降低 50% 延迟
大事务优化 大事务分批处理 避免超时和内存溢出
事务批处理 批量提交多个事务 提高吞吐量

2. TiFlash 列式存储

TiFlash 是 TiDB 的列式存储扩展,提供 HTAP(混合事务/分析处理)能力,支持实时分析查询。

2.1 架构设计

存算分离架构

┌──────────────────────────────────────────────────────────────┐
│                     TiFlash 整体架构                         │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│                        TiDB Server                           │
│                           │                                  │
│                           │ SQL                              │
│                           ▼                                  │
│  ┌────────────────────────────────────────────────────────┐ │
│  │                   优化器层                              │ │
│  │  • 自动选择 TiKV (行式) 或 TiFlash (列式)                 │ │
│  │  • 基于成本和统计信息决策                               │ │
│  └────────────────────────────────────────────────────────┘ │
│                           │                                  │
│                           ▼                                  │
│  ┌────────────────────────────────────────────────────────┐ │
│  │                   TiFlash 节点                          │ │
│  │  ┌──────────────────────────────────────────────────┐ │ │
│  │  │                 MPP 引擎                          │ │ │
│  │  │  ┌─────────┐  ┌─────────┐  ┌─────────┐         │ │ │
│  │  │  │ Exchange│  │ Exchange│  │ Exchange│         │ │ │
│  │  │  └────┬────┘  └────┬────┘  └────┬────┘         │ │ │
│  │  │       │            │            │               │ │ │
│  │  │  ┌────▼────┐  ┌────▼────┐  ┌────▼────┐        │ │ │
│  │  │  │ Compute │  │ Compute │  │ Compute │        │ │ │
│  │  │  │ Thread  │  │ Thread  │  │ Thread  │        │ │ │
│  │  │  └─────────┘  └─────────┘  └─────────┘        │ │ │
│  │  └──────────────────────────────────────────────────┘ │ │
│  │                         │                              │ │
│  │  ┌──────────────────────────────────────────────────┐ │ │
│  │  │               列式存储引擎                        │ │ │
│  │  │  ┌─────────┐  ┌─────────┐  ┌─────────┐         │ │ │
│  │  │  │  列 A   │  │  列 B   │  │  列 C   │  ...    │ │ │
│  │  │  │ Delta   │  │ Delta   │  │ Delta   │         │ │ │
│  │  │  │ Main    │  │ Main    │  │ Main    │         │ │ │
│  │  │  └─────────┘  └─────────┘  └─────────┘         │ │ │
│  │  └──────────────────────────────────────────────────┘ │ │
│  └────────────────────────────────────────────────────────┘ │
│                           │                                  │
│                           │ Raft Learner                     │
│                           ▼                                  │
│                      TiKV 集群                                │
│                                                              │
└──────────────────────────────────────────────────────────────┘

列式存储结构:

┌──────────────────────────────────────────────────────────────┐
│                    列式存储 vs 行式存储                       │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  行式存储 (TiKV):                                            │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Row 1: [id=1, name=Alice, age=25, city=BJ]          │  │
│  │  Row 2: [id=2, name=Bob,   age=30, city=SH]          │  │
│  │  Row 3: [id=3, name=Carol, age=28, city=GZ]          │  │
│  │  Row 4: [id=4, name=David, age=35, city=SZ]          │  │
│  └──────────────────────────────────────────────────────┘  │
│  适合:点查、事务更新                                        │
│                                                              │
│  列式存储 (TiFlash):                                         │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  id:   [1, 2, 3, 4]                                  │  │
│  │  name: [Alice, Bob, Carol, David]                    │  │
│  │  age:  [25, 30, 28, 35]                              │  │
│  │  city: [BJ, SH, GZ, SZ]                              │  │
│  └──────────────────────────────────────────────────────┘  │
│  适合:聚合查询、分析扫描                                    │
│                                                              │
│  性能对比 (SUM(age) 查询):                                   │
│  • 行式存储:读取 4 行 × 4 列 = 16 个字段                        │
│  • 列式存储:读取 1 列 × 4 行 = 4 个字段                         │
│  • 性能提升:3-10 倍                                         │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Delta-Tree 存储引擎:

┌──────────────────────────────────────────────────────────────┐
│                   Delta-Tree 存储结构                        │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   每个列由两部分组成:                                         │
│                                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                    Delta Layer                       │   │
│   │  • 存储最近的增量数据                                  │   │
│   │  • 内存或 SSD 存储                                     │   │
│   │  • 快速写入,延迟合并                                   │   │
│   │  • 格式:[新增数据]                                    │   │
│   └─────────────────────────────────────────────────────┘   │
│                          │                                   │
│                          │ 定期合并                           │
│                          ▼                                   │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                     Main Layer                       │   │
│   │  • 存储稳定的历史数据                                  │   │
│   │  • 压缩存储,高压缩比                                  │   │
│   │  • 优化读取性能                                        │   │
│   │  • 格式:[压缩后的列数据]                              │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
│   读取时:合并 Delta + Main 层返回结果                          │
│                                                              │
└──────────────────────────────────────────────────────────────┘

2.2 数据同步机制

Raft Learner 模式

TiFlash 通过 Raft Learner 模式从 TiKV 实时同步数据,保证数据最终一致性。

┌──────────────────────────────────────────────────────────────┐
│                   数据同步流程                               │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   TiKV (Raft Leader)                                         │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                                                     │   │
│   │  写入请求                                            │   │
│   │      │                                              │   │
│   │      ▼                                              │   │
│   │  ┌─────────┐                                        │   │
│   │  │ Raft    │                                        │   │
│   │  │ Log     │                                        │   │
│   │  └────┬────┘                                        │   │
│   │       │ Replicate                                   │   │
│   │  ┌────┴────┐                                        │   │
│   │    │     │                                          │   │
│   │    ▼     ▼                                          │   │
│   │ ┌─────┐ ┌──────────┐                                │   │
│   │ │Follower│ │ Learner │  ◄─── TiFlash                 │   │
│   │ └─────┘ └──────────┘                                │   │
│   │              │                                       │   │
│   │              │ 异步应用日志                           │   │
│   │              ▼                                       │   │
│   │       ┌─────────────┐                                │   │
│   │       │ 列式存储引擎 │                                │   │
│   │       └─────────────┘                                │   │
│   │                                                     │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
│   同步延迟:通常 < 1 秒                                       │
│   一致性:最终一致性                                         │
│                                                              │
└──────────────────────────────────────────────────────────────┘

同步流程详解:

┌──────────────────────────────────────────────────────────────┐
│                   数据同步详细流程                           │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   Step 1: Region 分裂                                        │
│   ┌──────────────────────────────────────────────────────┐  │
│   │  • TiKV Region 分裂时,通知 PD                           │  │
│   │  • PD 更新 Region 元数据,添加 TiFlash 副本信息            │  │
│   │  • TiFlash 感知新 Region,开始同步                      │  │
│   └──────────────────────────────────────────────────────┘  │
│                                                              │
│   Step 2: 日志复制                                           │
│   ┌──────────────────────────────────────────────────────┐  │
│   │  • TiKV Leader 将 Raft 日志复制给 TiFlash (Learner)      │  │
│   │  • TiFlash 接收日志,但不参与投票                       │  │
│   │  • 不影响 TiKV 的写入性能                              │  │
│   └──────────────────────────────────────────────────────┘  │
│                                                              │
│   Step 3: 日志应用                                           │
│   ┌──────────────────────────────────────────────────────┐  │
│   │  • TiFlash 异步应用 Raft 日志                           │  │
│   │  • 将行式数据转换为列式存储                            │  │
│   │  • 更新 Delta Layer 或触发合并                         │  │
│   └──────────────────────────────────────────────────────┘  │
│                                                              │
│   Step 4: 状态上报                                           │
│   ┌──────────────────────────────────────────────────────┐  │
│   │  • TiFlash 定期向 PD 上报同步进度                       │  │
│   │  • PD 跟踪每个 Region 的同步状态                        │  │
│   │  • TiDB 优化器根据同步状态选择执行引擎                  │  │
│   └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

2.3 MPP 执行模式

大规模并行处理

MPP(Massively Parallel Processing)是 TiFlash 的核心执行引擎,支持分布式并行计算。

┌──────────────────────────────────────────────────────────────┐
│                      MPP 执行架构                            │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│                        TiDB Driver                           │
│                           │                                  │
│                           ▼                                  │
│  ┌────────────────────────────────────────────────────────┐ │
│  │                    TiDB Server                          │ │
│  │  • 生成 MPP 执行计划                                      │ │
│  │  • 协调 MPP 任务                                         │ │
│  └────────────────────────────────────────────────────────┘ │
│                           │                                  │
│              ┌────────────┼────────────┐                    │
│              │            │            │                    │
│              ▼            ▼            ▼                    │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐        │
│  │  TiFlash 1   │ │  TiFlash 2   │ │  TiFlash 3   │        │
│  │  ┌────────┐  │ │  ┌────────┐  │ │  ┌────────┐  │        │
│  │  │Segment │  │ │  │Segment │  │ │  │Segment │  │        │
│  │  │ Scan   │  │ │  │ Scan   │  │ │  │ Scan   │  │        │
│  │  └───┬────┘  │ │  └───┬────┘  │ │  └───┬────┘  │        │
│  │  ┌───▼────┐  │ │  ┌───▼────┐  │ │  ┌───▼────┐  │        │
│  │  │ Filter │  │ │  │ Filter │  │ │  │ Filter │  │        │
│  │  └───┬────┘  │ │  └───┬────┘  │ │  └───┬────┘  │        │
│  │  ┌───▼────┐  │ │  ┌───▼────┐  │ │  ┌───▼────┐  │        │
│  │  │ Agg    │  │ │  │ Agg    │  │ │  │ Agg    │  │        │
│  │  └───┬────┘  │ │  └───┬────┘  │ │  └───┬────┘  │        │
│  └──────│───────┘ │  ┌─────│──────┘ │  ┌─────│──────┘        │
│         │         │        │        │        │               │
│         └─────────┼────────┴────────┘        │               │
│                   │                          │               │
│                   ▼                          ▼               │
│         ┌─────────────────┐        ┌─────────────────┐      │
│         │   Exchange      │        │   Exchange      │      │
│         │   (Shuffle)     │        │   (Shuffle)     │      │
│         └─────────────────┘        └─────────────────┘      │
│                   │                          │               │
│                   └────────────┬─────────────┘               │
│                                │                             │
│                                ▼                             │
│                     ┌─────────────────┐                     │
│                     │   Final Agg     │                     │
│                     │   (汇总结果)     │                     │
│                     └─────────────────┘                     │
│                                                              │
└──────────────────────────────────────────────────────────────┘

MPP 执行流程:

┌──────────────────────────────────────────────────────────────┐
│                    MPP 查询执行流程                          │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   1. 查询提交                                                 │
│      ┌───────────────────────────────────────────────────┐  │
│      │  SELECT COUNT(*), city FROM users WHERE age > 25  │  │
│      └───────────────────────────────────────────────────┘  │
│                                                              │
│   2. 执行计划生成                                             │
│      ┌───────────────────────────────────────────────────┐  │
│      │  TiDB 优化器分析查询,决定使用 MPP 执行                │  │
│      │  生成 MPP Fragment 计划                             │  │
│      └───────────────────────────────────────────────────┘  │
│                                                              │
│   3. 任务分发                                                 │
│      ┌───────────────────────────────────────────────────┐  │
│      │  TiDB 将 MPP 任务分发给各个 TiFlash 节点                │  │
│      │  每个节点处理本地数据分片                            │  │
│      └───────────────────────────────────────────────────┘  │
│                                                              │
│   4. 并行执行                                                 │
│      ┌───────────────────────────────────────────────────┐  │
│      │  各 TiFlash 节点并行执行:                            │  │
│      │  • Segment Scan (读取本地数据)                      │  │
│      │  • Filter (过滤 age > 25)                          │  │
│      │  • Local Agg (本地聚合)                            │  │
│      └───────────────────────────────────────────────────┘  │
│                                                              │
│   5. 数据交换                                                 │
│      ┌───────────────────────────────────────────────────┐  │
│      │  通过 Exchange 算子进行数据 Shuffle                   │  │
│      │  按 city 分组的数据发送到对应节点                    │  │
│      └───────────────────────────────────────────────────┘  │
│                                                              │
│   6. 结果汇总                                                 │
│      ┌───────────────────────────────────────────────────┐  │
│      │  Final Agg 汇总各节点结果                            │  │
│      │  返回最终结果给客户端                               │  │
│      └───────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

2.4 算子下推优化

计算下推(Push Down)

TiFlash 支持将计算算子下推到存储层执行,减少数据传输量,提高查询性能。

┌──────────────────────────────────────────────────────────────┐
│                    算子下推对比                              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  无下推 (传统方式):                                          │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                                                      │  │
│  │  TiKV/TiFlash           TiDB Server                  │  │
│  │  ┌─────────┐            ┌─────────┐                 │  │
│  │  │ 全量    │ ──────────▶│ 过滤     │                 │  │
│  │  │ 数据    │  大量数据   │ 聚合     │                 │  │
│  │  │ 扫描    │            │ 计算     │                 │  │
│  │  └─────────┘            └─────────┘                 │  │
│  │                                                      │  │
│  │  缺点:网络传输量大,TiDB 负载高                        │  │
│  │                                                      │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  算子下推 (优化方式):                                        │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                                                      │  │
│  │  TiKV/TiFlash           TiDB Server                  │  │
│  │  ┌─────────┐            ┌─────────┐                 │  │
│  │  │ 过滤     │ ──────────▶│ 聚合     │                 │  │
│  │  │ 聚合     │  少量数据   │ 汇总     │                 │  │
│  │  │ 扫描     │            │         │                 │  │
│  │  └─────────┘            └─────────┘                 │  │
│  │                                                      │  │
│  │  优点:减少网络传输,降低 TiDB 负载                       │  │
│  │                                                      │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

支持下推的算子:

┌──────────────────────────────────────────────────────────────┐
│                    可下推算子列表                            │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  过滤类算子                                            │  │
│  │  • Selection (WHERE 条件过滤)                          │  │
│  │  • Partition Selection (分区裁剪)                      │  │
│  │  • Index Range Scan (索引范围扫描)                     │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  聚合类算子                                            │  │
│  │  • Hash Aggregation (哈希聚合)                         │  │
│  │  • Stream Aggregation (流式聚合)                       │  │
│  │  • COUNT, SUM, AVG, MIN, MAX                          │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  连接类算子                                            │  │
│  │  • Hash Join (哈希连接)                                │  │
│  │  • Merge Join (归并连接)                               │  │
│  │  • Index Join (索引连接)                               │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  其他算子                                              │  │
│  │  • Projection (投影)                                   │  │
│  │  • Sort (排序)                                        │  │
│  │  • Limit (限制)                                       │  │
│  │  • TopN (前 N 条)                                      │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

下推决策流程:

┌──────────────────────────────────────────────────────────────┐
│                    下推决策流程                              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   TiDB 优化器                                                 │
│      │                                                       │
│      ▼                                                       │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Step 1: 分析查询                                    │   │
│   │  • 识别可下推的算子                                   │   │
│   │  • 评估下推收益                                       │   │
│   └─────────────────────────────────────────────────────┘   │
│      │                                                       │
│      ▼                                                       │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Step 2: 检查存储引擎能力                            │   │
│   │  • TiFlash 支持哪些算子                               │   │
│   │  • 算子下推的版本兼容性                               │   │
│   └─────────────────────────────────────────────────────┘   │
│      │                                                       │
│      ▼                                                       │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Step 3: 成本评估                                    │   │
│   │  • 下推后的网络传输量                                 │   │
│   │  • 存储引擎计算负载                                   │   │
│   │  • TiDB 服务器负载                                    │   │
│   └─────────────────────────────────────────────────────┘   │
│      │                                                       │
│      ▼                                                       │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  Step 4: 生成执行计划                                │   │
│   │  • 决定哪些算子下推                                   │   │
│   │  • 生成最优执行计划                                   │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
└──────────────────────────────────────────────────────────────┘

3. PD 调度机制

PD(Placement Driver)是 TiDB 集群的调度中心,负责元数据管理、集群调度和全局时间戳分配。

3.1 核心职责

┌──────────────────────────────────────────────────────────────┐
│                      PD 核心职责                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌─────────────────┐  ┌─────────────────┐                 │
│  │   元数据管理     │  │     集群调度     │                 │
│  │  ─────────────  │  │   ────────────  │                 │
│  │                 │  │                 │                 │
│  │ • Region 映射    │  │ • 负载均衡       │                 │
│  │   - Key Range   │  │   - Region 平衡   │                 │
│  │   - Peer 分布    │  │   - Leader 平衡   │                 │
│  │ • Store 信息     │  │ • 热点调度       │                 │
│  │   - 容量         │  │   - 热点识别     │                 │
│  │   - 状态         │  │   - 热点均衡     │                 │
│  │   - 标签         │  │ • 故障恢复       │                 │
│  │ • 副本规则       │  │   - 副本补充     │                 │
│  │   - 副本数       │  │   - Leader 转移   │                 │
│  │   - 位置约束     │  │ • 扩缩容调度     │                 │
│  │ • 配置管理       │  │   - 自动平衡     │                 │
│  │   - 调度策略     │  │   - 数据迁移     │                 │
│  │   - 调度开关     │  │                 │                 │
│  └─────────────────┘  └─────────────────┘                 │
│                                                              │
│  ┌─────────────────┐  ┌─────────────────┐                 │
│  │   全局时间戳     │  │     自治管理     │                 │
│  │  ─────────────  │  │   ────────────  │                 │
│  │                 │  │                 │                 │
│  │ • TSO 服务        │  │ • 自动故障转移   │                 │
│  │   - 单调递增     │  │ • 配置热更新     │                 │
│  │   - 全局唯一     │  │ • 监控告警       │                 │
│  │   - 高可用       │  │ • 性能分析       │                 │
│  │ • 事务版本       │  │ • Dashboard      │                 │
│  │   - start_ts    │  │   - 可视化界面   │                 │
│  │   - commit_ts   │  │   - 实时监控     │                 │
│  └─────────────────┘  └─────────────────┘                 │
│                                                              │
└──────────────────────────────────────────────────────────────┘

3.2 心跳机制

Region 心跳

TiKV 定期向 PD 发送 Region 心跳,上报 Region 状态和统计信息。

┌──────────────────────────────────────────────────────────────┐
│                    Region 心跳流程                           │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   TiKV                               PD                      │
│    │                                 │                       │
│    │  Region Heartbeat (每 10 秒)       │                       │
│    │────────────────────────────────▶│                       │
│    │                                 │                       │
│    │  上报内容:                       │                       │
│    │  • Region ID                    │                       │
│    │  • Key Range                    │                       │
│    │  • Peer 列表                     │                       │
│    │  • Leader Peer                  │                       │
│    │  • 近似大小                      │                       │
│    │  • 近似行数                      │                       │
│    │  • 写入流量                      │                       │
│    │  • 读取流量                      │                       │
│    │                                 │                       │
│    │                                 │ 更新元数据            │
│    │                                 │ 更新统计信息          │
│    │                                 │ 触发调度决策          │
│    │                                 │                       │
│    │  调度指令 (可选)                  │                       │
│    │◀────────────────────────────────│                       │
│    │                                 │                       │
│    │  指令类型:                       │                       │
│    │  • Transfer Leader              │                       │
│    │  • Add Peer                     │                       │
│    │  • Remove Peer                  │                       │
│    │  • Merge Region                 │                       │
│    │  • Split Region                 │                       │
│    │                                 │                       │
│    │  执行调度指令                    │                       │
│    │                                 │                       │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Store 心跳

TiKV 定期向 PD 发送 Store 心跳,上报节点状态。

┌──────────────────────────────────────────────────────────────┐
│                    Store 心跳上报内容                        │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  基础信息                                              │  │
│  │  • Store ID                                          │  │
│  │  • 地址 (IP:Port)                                     │  │
│  │  • 版本信息                                          │  │
│  │  • 标签 (Labels)                                      │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  容量信息                                              │  │
│  │  • 总容量                                            │  │
│  │  • 已用容量                                          │  │
│  │  • 可用容量                                          │  │
│  │  • 容量使用率                                        │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  负载信息                                              │  │
│  │  • Region 数量                                        │  │
│  │  • Leader 数量                                        │  │
│  │  • 写入 QPS                                           │  │
│  │  • 读取 QPS                                           │  │
│  │  • CPU 使用率                                         │  │
│  │  • 内存使用率                                        │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  状态信息                                              │  │
│  │  • Up / Down                                         │  │
│  │  • Offline                                           │  │
│  │  • Tombstone                                         │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

3.3 调度流程

调度决策流程

┌──────────────────────────────────────────────────────────────┐
│                    PD 调度决策流程                           │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │              Step 1: 信息收集                         │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  • 接收 Region 心跳                             │  │   │
│   │  │  • 接收 Store 心跳                              │  │   │
│   │  │  • 更新元数据缓存                               │  │   │
│   │  │  • 更新统计信息                                 │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│                          │                                   │
│                          ▼                                   │
│   ┌─────────────────────────────────────────────────────┐   │
│   │              Step 2: 调度检查                         │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  检查项:                                      │  │   │
│   │  │  • Region 副本数是否正确                        │  │   │
│   │  │  • Leader 分布是否均衡                          │  │   │
│   │  │  • Region 大小是否超限                          │  │   │
│   │  │  • Store 容量是否均衡                           │  │   │
│   │  │  • 是否存在热点 Region                          │  │   │
│   │  │  • 是否有节点故障                               │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│                          │                                   │
│                          ▼                                   │
│   ┌─────────────────────────────────────────────────────┐   │
│   │              Step 3: 调度决策                         │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  调度器 (Scheduler):                          │  │   │
│   │  │  • Balance Leader Scheduler                   │  │   │
│   │  │  • Balance Region Scheduler                   │  │   │
│   │  │  • Hot Region Scheduler                       │  │   │
│   │  │  • Replica Checker                            │  │   │
│   │  │  • Merge Scheduler                            │  │   │
│   │  │  • Evict Leader Scheduler                     │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│                          │                                   │
│                          ▼                                   │
│   ┌─────────────────────────────────────────────────────┐   │
│   │              Step 4: 指令下发                         │   │
│   │  ┌───────────────────────────────────────────────┐  │   │
│   │  │  • 生成调度操作 (Operator)                      │  │   │
│   │  │  • 通过心跳响应下发给 TiKV                       │  │   │
│   │  │  • TiKV 执行调度操作                            │  │   │
│   │  │  • PD 跟踪操作进度                              │  │   │
│   │  └───────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
└──────────────────────────────────────────────────────────────┘

3.4 平衡策略

Region 平衡

┌──────────────────────────────────────────────────────────────┐
│                    Region 平衡策略                           │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  平衡目标:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 各 Store 的 Region 数量尽量均衡                       │  │
│  │  • 各 Store 的容量使用率尽量均衡                        │  │
│  │  • 避免频繁迁移 (设置容忍阈值)                          │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  平衡算法:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  1. 计算各 Store 的得分                                 │  │
│  │     Score = f(Region 数,容量,负载)                     │  │
│  │                                                      │  │
│  │  2. 选择源 Store 和目标 Store                           │  │
│  │     Source = 得分最高的 Store                          │  │
│  │     Target = 得分最低的 Store                          │  │
│  │                                                      │  │
│  │  3. 选择迁移的 Region                                  │  │
│  │     • 优先选择大 Region                               │  │
│  │     • 避免迁移热点 Region                             │  │
│  │     • 考虑副本位置约束                                │  │
│  │                                                      │  │
│  │  4. 执行迁移                                          │  │
│  │     • Add Peer (在目标 Store 添加副本)                  │  │
│  │     • Remove Peer (在源 Store 删除副本)                 │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  平衡阈值:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 默认容忍度:5%                                     │  │
│  │  • 即当 Store 间差异 > 5% 时才触发平衡                   │  │
│  │  • 可配置:schedule.max-snapshot-count               │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Leader 平衡

┌──────────────────────────────────────────────────────────────┐
│                    Leader 平衡策略                           │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  平衡目标:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 各 Store 的 Leader 数量尽量均衡                       │  │
│  │  • 减少 Leader 热点                                    │  │
│  │  • 优先保证高可用                                     │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  平衡方式:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Transfer Leader (不迁移数据,只转移 Leader 角色)         │  │
│  │                                                      │  │
│  │  优点:                                               │  │
│  │  • 快速 (秒级完成)                                   │  │
│  │  • 不消耗网络带宽                                    │  │
│  │  • 不影响数据副本                                    │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  平衡策略:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  1. 计算 Leader 分布                                   │  │
│  │  2. 识别 Leader 过多的 Store                            │  │
│  │  3. 选择可转移的 Leader                               │  │
│  │  4. 执行 Transfer Leader 操作                          │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

热点调度

┌──────────────────────────────────────────────────────────────┐
│                    热点调度机制                              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  热点识别:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 基于心跳统计信息                                   │  │
│  │  • 检测 QPS 显著高于平均水平的 Region                   │  │
│  │  • 阈值:QPS > 平均 QPS × 3 (可配置)                    │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  热点类型:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 读热点:读取 QPS 高                                  │  │
│  │    解决:增加副本,分散读负载                          │  │
│  │                                                      │  │
│  │  • 写热点:写入 QPS 高                                  │  │
│  │    解决:Region 分裂,分散写负载                        │  │
│  │                                                      │  │
│  │  • Leader 热点:Leader 所在 Store 负载高                 │  │
│  │    解决:Transfer Leader                              │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  调度流程:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  1. 检测热点 Region                                    │  │
│  │  2. 分析热点类型                                       │  │
│  │  3. 生成调度策略                                       │  │
│  │  4. 执行调度操作                                       │  │
│  │  5. 验证效果                                          │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

副本规则与位置约束

┌──────────────────────────────────────────────────────────────┐
│                  副本规则与位置约束                          │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  副本规则 (Replication Config):                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 副本数:默认 3 副本                                   │  │
│  │  • 可配置:replication.max-replicas                  │  │
│  │  • 支持:3 副本、5 副本等奇数配置                         │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  位置约束 (Location Labels):                                 │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  配置示例:                                            │  │
│  │  location-labels: ["zone", "rack", "host"]           │  │
│  │                                                      │  │
│  │  效果:                                               │  │
│  │  • 副本分布在不同 Zone (机房级容灾)                     │  │
│  │  • 副本分布在不同 Rack (机架级容灾)                     │  │
│  │  • 副本分布在不同 Host (节点级容灾)                     │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  隔离级别:                                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  • 最大隔离:副本尽可能分散                           │  │
│  │  • 最小隔离:满足约束即可                             │  │
│  │  • 可配置:replication.strictly-match-label          │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

总结

本文作为 NewSQL 技术系列的中篇,深入探讨了 TiDB 的存储与调度核心:

核心要点回顾:

  1. TiKV 存储引擎
  2. RocksDB LSM-Tree 提供高性能存储
  3. Raft 协议保证数据一致性和高可用
  4. MVCC 实现高并发读写
  5. Percolator 模型支持分布式事务

  6. TiFlash 列式存储

  7. 列式存储优化分析查询性能
  8. Raft Learner 实现实时数据同步
  9. MPP 引擎支持大规模并行计算
  10. 算子下推减少数据传输

  11. PD 调度机制

  12. 元数据管理和全局时间戳服务
  13. 心跳机制收集集群状态
  14. 智能调度实现负载均衡
  15. 热点检测和自动优化

下篇预告:

在下篇《执行框架与实战》中,我们将深入探讨: - 分布式执行框架(执行计划、算子下推、并行执行) - 最佳实践与运维(部署、优化、监控、故障排查) - 应用场景与案例(典型场景、性能对比、迁移指南)

敬请期待!


参考文献:

  1. TiKV Documentation. https://tikv.org/docs
  2. Raft Consensus Algorithm. https://raft.github.io
  3. Percolator: Large-scale Incremental Processing. Google
  4. TiFlash Architecture. https://docs.pingcap.com/tidb/stable/tiflash-overview
  5. PD Scheduler Design. https://github.com/tikv/pd
posted @ 2026-03-28 00:10  JackpotHan  阅读(3)  评论(0)    收藏  举报