Skip to content

Vitess — MySQL 水平扩展

架构概览

Vitess 是 YouTube 开源的 MySQL 水平扩展方案,现为 CNCF 毕业项目,支持超大规模 MySQL 集群。

应用 ──► VTGate(查询路由层)──► VTTablet(MySQL 代理)──► MySQL
                                ──► VTTablet ──► MySQL
                                ──► VTTablet ──► MySQL
                                
控制平面:
  Topology Service(etcd/ZooKeeper)
    └── 存储集群拓扑、分片信息、Schema
    
VTAdmin(管理界面)
VTOrc(自动故障恢复)

核心组件

组件职责
VTGate无状态查询路由,接受 MySQL 协议连接
VTTablet每个 MySQL 实例的代理,连接池管理、查询重写
VTOrc自动故障检测和主从切换(替代 Orchestrator)
Topology Service存储集群元数据(etcd/ZooKeeper)
VTAdminWeb 管理界面

核心概念

Keyspace(键空间):逻辑数据库,类似 MySQL 的 database
  ├── Unsharded Keyspace:不分片,单个 MySQL
  └── Sharded Keyspace:分片,多个 MySQL

Shard(分片):Keyspace 的一个分区
  ├── Primary Tablet(主)
  └── Replica Tablet(从)

Vindex(虚拟索引):分片键的映射关系
  ├── Primary Vindex:决定数据路由到哪个分片
  └── Secondary Vindex:辅助查询路由

VSchema(虚拟 Schema)

json
{
  "sharded": true,
  "vindexes": {
    "hash": {
      "type": "hash"
    },
    "lookup_unique": {
      "type": "consistent_lookup_unique",
      "params": {
        "table": "order_lookup",
        "from": "email",
        "to": "user_id"
      },
      "owner": "user"
    }
  },
  "tables": {
    "user": {
      "column_vindexes": [
        {
          "column": "user_id",
          "name": "hash"
        },
        {
          "column": "email",
          "name": "lookup_unique"
        }
      ]
    },
    "order": {
      "column_vindexes": [
        {
          "column": "user_id",
          "name": "hash"
        }
      ]
    }
  }
}

分片操作

初始化分片

bash
# 创建 Keyspace
vtctldclient CreateKeyspace --keyspace-type=SHARDED order_keyspace

# 创建分片(-80 和 80-)
vtctldclient CreateShard order_keyspace/-80
vtctldclient CreateShard order_keyspace/80-

# 应用 VSchema
vtctldclient ApplyVSchema --vschema-file vschema.json order_keyspace

在线重新分片(Resharding)

Vitess 支持在线不停机重新分片:

bash
# 1. 创建新分片
vtctldclient CreateShard order_keyspace/-40
vtctldclient CreateShard order_keyspace/40-80
vtctldclient CreateShard order_keyspace/80-c0
vtctldclient CreateShard order_keyspace/c0-

# 2. 启动数据复制(从旧分片复制到新分片)
vtctlclient Reshard -- --source_shards='-80,80-' \
  --target_shards='-40,40-80,80-c0,c0-' \
  Create order_keyspace.reshard1

# 3. 验证数据一致性
vtctlclient Reshard -- SwitchTraffic order_keyspace.reshard1

# 4. 切换流量
vtctlclient Reshard -- Complete order_keyspace.reshard1

连接与查询

python
# Python 客户端(标准 MySQL 驱动)
import mysql.connector

conn = mysql.connector.connect(
    host='vtgate',
    port=3306,
    user='vitess',
    password='password',
    database='order_keyspace'
)

cursor = conn.cursor()

# 带分片键的查询(路由到单分片)
cursor.execute("SELECT * FROM order WHERE user_id = %s", (123,))

# 跨分片查询(VTGate 自动路由并合并)
cursor.execute("SELECT COUNT(*) FROM order WHERE status = 'pending'")

# 散射查询(所有分片)
cursor.execute("SELECT * FROM order WHERE create_time > '2024-01-01'")

连接池管理

VTTablet 提供连接池,减少 MySQL 连接数:

yaml
# VTTablet 配置
--queryserver-config-pool-size=16          # 事务连接池
--queryserver-config-stream-pool-size=200  # 流式查询连接池
--queryserver-config-transaction-cap=20    # 最大并发事务数
--queryserver-config-query-timeout=30s     # 查询超时

故障自动恢复(VTOrc)

yaml
# VTOrc 配置
--topo-implementation=etcd2
--topo-global-server-address=etcd:2379
--topo-global-root=/vitess/global

# VTOrc 自动处理:
# - 主库宕机 → 自动选举新主
# - 从库延迟过高 → 告警
# - 复制中断 → 自动修复

与 ShardingSphere/MyCat 对比

维度VitessShardingSphereMyCat
规模超大规模(YouTube 级)大规模中等规模
在线重分片原生支持支持(Scaling)不支持
连接池VTTablet 统一管理应用侧应用侧
自动故障转移VTOrc依赖外部有限支持
学习曲线
适用场景超大规模,K8s 原生通用分库分表老项目改造

PaaS 中间件生态系统深度学习文档