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) |
| VTAdmin | Web 管理界面 |
核心概念
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 对比
| 维度 | Vitess | ShardingSphere | MyCat |
|---|---|---|---|
| 规模 | 超大规模(YouTube 级) | 大规模 | 中等规模 |
| 在线重分片 | 原生支持 | 支持(Scaling) | 不支持 |
| 连接池 | VTTablet 统一管理 | 应用侧 | 应用侧 |
| 自动故障转移 | VTOrc | 依赖外部 | 有限支持 |
| 学习曲线 | 高 | 中 | 低 |
| 适用场景 | 超大规模,K8s 原生 | 通用分库分表 | 老项目改造 |