本页是译文,以英文原文为准。 阅读原文
写作Vitess vs Aurora:MySQL 扩展该怎么选
Vitess 和 Aurora 的对比,结论经过生产验证:性能基准、成本账,还有一套从 3 年运维里长出来的决策框架。
单实例 MySQL 一旦到顶,你手上就只剩三条路,哪条都不轻松:给应用写自研分片逻辑、 换一套数据库系统,或者上一套 Vitess 这样的集群方案。
先说结论,你据此决定要不要往下读:在生产环境跑了 3 年 Vitess 之后,我们把它换掉了 — — 换成 Aurora。 不是 Vitess 不行,而是撑起它运维成本的那项能力 —— 横向写分片 — — 我们从来就没真正需要过。你的写流量确实超过一台大规格主库的上限 —— 指的是持续每秒几万次写, 不是突发峰值 —— 那 Vitess 很可能就是你的答案,这篇文章会说清运维它要付什么代价。 低于这条线,Aurora 几乎肯定是更优解,这篇文章会说清为什么。
Vitess —— YouTube、Slack、GitHub 背后那套开源系统 —— 负责横向分片、跨数据中心故障转移和大规模连接池。 但它不简单。它是一套分布式系统,把应用和 MySQL 打交道的方式整个改掉了。
接下来是:核心架构取舍、那次迁移真实的性能与成本数字,还有那套决策框架 —— 当初我要是有就好了。
Vitess 要解决的扩展问题
多数应用都从一台 MySQL 实例起步。这套跑得挺好,直到某天开始不好使。撑不住的样子 通常有三种:
1. 数据集大到一台实例扛不住
越过 2-5TB,纵向扩展既贵,运维风险也高。备份一跑就是几个小时,schema 变更得开维 护窗口,硬件一坏,恢复要停机很久。
真实案例: 我们最大的那套库,18 个月里从 800GB 长到 4.2TB。备份窗口从 45 分 钟拉到 6 小时以上。schema 变更以前几分钟做完,后来要开 4 小时的维护窗口。
2. 写吞吐把单台主库跑满
MySQL 复制单线程跑了很多年(并行回放直到 MySQL 8.0.27 才成为默认)。写 QPS 一旦 超过副本回放速度,延迟就堆起来。写后读一致性被破坏,应用行为也跟着变差。
生产数据: 写到 12,000 QPS,只读副本上稳定出现 30-60 秒复制延迟,那时并行复 制已经开着。凡是靠「读到自己刚写的数据」的功能,开始间歇性出错。
3. 连接数成为瓶颈
每条 MySQL 连接都占内存。云原生架构动辄拉起几百上千个应用 pod,于是你还没撞上 CPU 或磁盘上限,就先被连接数卡住了。
我们的约束: 450 个应用 pod(弹性伸缩区间 200-800)。应用层连接池做得很激进, 还是撞上了 MySQL 的 1,000 连接上限。想加应用容量,得先改数据库。
flowchart TD
A[MySQL Scaling Pain Points] --> B{What's Breaking?}
B -->|Dataset > 5TB| C[Sharding Required]
B -->|Writes > 10K QPS| D[Horizontal Scaling]
B -->|Connections > 1K| E[Connection Pooling]
B -->|Multi-Region HA| F[Failover Automation]
C --> G{Solution Options}
D --> G
E --> G
F --> G
G -->|Custom| H[App-Level Sharding]
G -->|Managed| I[Aurora]
G -->|Platform| J[Vitess]
style C fill:#fee2e2
style D fill:#fee2e2
style E fill:#fee2e2
style F fill:#fee2e2传统做法: 手工分片。数据拆到多台 MySQL 实例上,分片路由逻辑硬编码进应用,故 障转移自动化自己写。
Vitess 的做法: 加一层标准化集群层,把分片、路由和运维复杂度收进一套可复用的 平台。
托管服务的做法: Aurora(provisioned 或 I/O-Optimized),多区域变体是 Aurora Global Database。高可用、只读副本、存储扩展都由托管方接手,不用自己运维这套平台。 有一点和这个决策直接相关:Aurora Global 解决的是灾备和就近读 —— 它不给任何写扩展 空间,每个区域仍然只有一个逻辑写节点。
架构上的取舍
Vitess 把数据库架构整个改掉了。应用不再直连 MySQL,而是连到 VTGate —— 一层无状态的查询路由, 夹在应用和数据库实例中间。
flowchart LR
subgraph Apps["Application Layer"]
A1["App Server 1"]
A2["App Server 2"]
A3["App Server N"]
end
subgraph VTG["Query Routing Layer"]
VG1["VTGate 1"]
VG2["VTGate 2"]
VG3["VTGate N"]
end
subgraph Shards["Sharded MySQL"]
subgraph S1["Shard 1 (-80)"]
VT1["VTTablet"] --> M1["MySQL Primary"]
M1 --> R1["MySQL Replica"]
end
subgraph S2["Shard 2 (80-)"]
VT2["VTTablet"] --> M2["MySQL Primary"]
M2 --> R2["MySQL Replica"]
end
end
subgraph Topo["Coordination"]
ETCD["etcd Cluster<br/>(5 nodes)"]
end
A1 & A2 & A3 --> VG1 & VG2 & VG3
VG1 & VG2 & VG3 --> VT1 & VT2
VT1 & VT2 -.->|health checks| ETCD这个架构选下来,有得有失:
得到什么:
- 透明分片(应用不用知道分片拓扑)
- 连接池(1000 台应用服务器可以共用 100 条 MySQL 连接)
- 自动故障转移(换主库不用改应用)
- 跨数据中心协调(区域故障时查询仍能正确路由)
- 计划内故障转移期间的查询缓冲(需要显式开启;它只平滑切换,不保证零丢写)
牺牲什么:
- 增加延迟(每个查询都要走 应用 → VTGate → VTTablet → MySQL)
- 运维复杂度(你现在运维的是一套分布式系统)
- SQL 兼容性(部分 MySQL 特性行为不同,或者根本不工作)
- 排障难度(慢查询可能慢在 3 层里的任何一层)
- 基础设施成本(要跑的组件更多)
性能影响:真实数字
生产环境测出来的 p50/p95/p99 延迟如下:
| 查询类型 | 直连 MySQL | 经 Vitess | 额外开销 |
|---|---|---|---|
| 简单 SELECT (p50) | 2.1ms | 3.8ms | +1.7ms(增加 81%) |
| 简单 SELECT (p99) | 8.3ms | 11.2ms | +2.9ms(增加 35%) |
| 单行 UPDATE (p50) | 3.2ms | 5.1ms | +1.9ms(增加 59%) |
| 复杂 JOIN (p50) | 45ms | 48ms | +3ms(增加 7%) |
| 跨分片查询 (p50) | 不适用 | 67ms | 不适用 |
几个要点:
- 多数查询经过 VTGate/VTTablet 这两层,会多出 1-3ms
- 越是快查询(< 5ms),这笔开销占比越显眼
- 复杂查询的百分比开销反而更小
- 跨分片查询天生更慢,但横向扩展必须付这个代价
连接池收益: 我们把 MySQL 连接从 800+(直连)降到 120(经 Vitess),同时撑着 400 个应用 pod。 连接耗尽消失了,MySQL 内存占用降了 60%。
核心组件到底在做什么
搞清楚每个 Vitess 组件在干什么,出问题时才用得上 —— 分布式系统里,总有某个地方正 在出问题。
VTGate:查询路由
VTGate 是应用侧的数据库入口。它解析 SQL,判断数据落在哪个分片(或哪几个),再据 此路由查询。
关键点: VTGate 无状态。哪个机房跑应用,就在那儿放 VTGate 实例,它们靠拓扑服 务互相协调。所以 VTGate 本身永远不会成为单点。
资源需求: 常规负载下,每个 VTGate 实例约占 2GB 内存、0.5 vCPU。我们在每个机 房跑 3 个实例做冗余。
常见错误: 一个区域只跑一套 VTGate,其他区域跨 WAN 连过去。每个查询凭空多 50-200ms。VTGate 应该和应用部署在一起。
VTTablet:MySQL 侧的 agent
VTTablet 挡在每台 MySQL 实例前面。它不只是一个 proxy —— 它还主动管着身后那台 MySQL 实例。
VTTablet 做了哪些原生 MySQL 不做的事:
- 连接池: 维护一个固定的 MySQL 连接池,靠复用承接 VTGate 过来的大批请求
- 查询安全: 检查查询是不是漏了 LIMIT,拦下返回行数过多的查询,强制超时
- 执行计划缓存与合并: 缓存执行计划(同一种查询形态不重复解析),并把并发的相同查询合并成一次上游执行
- 健康监控: 把 tablet 状态上报给拓扑服务,供故障转移决策使用
资源开销: 每台 MySQL 实例上,VTTablet 多占约 1GB 内存、0.3 vCPU。不算小,但换来这些收益可以接受。
拓扑服务:事实来源
拓扑服务(etcd 或 ZooKeeper)存放集群元数据:有哪些 tablet、哪台是主库、分片怎么 归属、schema 版本是多少。
架构上的关键点: 拓扑服务必须扛得住机房级故障。我们跨 3 个机房跑了一个 5 节 点的 etcd 集群 —— 整个机房没了,quorum 还在。
运维教训: etcd 对节点之间网络延迟很敏感。跨区域延迟超过 50ms,就会引发 leader 选举、集群不稳 —— 这个坑我们踩过。etcd 节点要么放同一个区域,要么给它一条 专用的低延迟链路。
Orchestrator:自动故障转移
Orchestrator(较新的 Vitess 版本里是 VTOrc)负责发现主库故障,协调一个副本升成主 库。和 Vitess 集成之后,它会自动更新拓扑服务,VTGate 随即把流量切过去。
故障转移表现: 从检测到流量完全恢复,我们的自动故障转移通常 30-45 秒。上 Vitess 之前手工做,要 15-45 分钟。
拆开看:
- 检测:5-10 秒(健康检查间隔)
- 选举:10-15 秒(共识)
- 提升:5-10 秒(MySQL 操作)
- 拓扑更新:2-5 秒(etcd 写入)
- 流量重路由:5-10 秒(VTGate 刷新)
成本分析:Vitess vs Aurora vs 自建
来比一比总拥有成本。场景统一:2TB 数据库、8,000 QPS(70% 读、30% 写)。
EC2 上自建 MySQL
| 组件 | 实例类型 | 月成本 |
|---|---|---|
| 主库 | r5.4xlarge(16 vCPU、128GB) | $950 |
| 2 台只读副本 | r5.4xlarge | $1,900 |
| EBS 存储(预置 6TB) | io2, 10K IOPS | $1,260 |
| 备份存储(S3) | 约 3TB | $70 |
| 小计 | $4,180 | |
| 工程时间 | 40 小时/月 @ $150/小时 | $6,000 |
| 合计(自建) | $10,180/月 |
自建基础设施上的 Vitess
| 组件 | 实例类型 | 数量 | 月成本 |
|---|---|---|---|
| MySQL 主库 | r5.2xlarge | 2 | $950 |
| MySQL 副本 | r5.2xlarge | 4 | $1,900 |
| VTGate | c5.2xlarge | 3 | $600 |
| VTTablet(额外开销) | 已含在实例内 | - | $0 |
| etcd 集群 | c5.large | 5 | $400 |
| EBS 存储 | io2, 10K IOPS 合计 | - | $1,260 |
| 备份存储 | S3 | - | $70 |
| 小计 | $5,180 | ||
| 工程时间 | 60 小时/月 @ $150/小时 | $9,000 | |
| 合计(自建 Vitess) | $14,180/月 |
Aurora MySQL
| 组件 | 配置 | 月成本 |
|---|---|---|
| 主库(Writer) | db.r5.4xlarge | $1,160 |
| 2 台只读(Reader) | db.r5.4xlarge | $2,320 |
| 存储 | 2TB + 增长量 | $260 |
| 备份存储 | 集群卷大小的 100% 以内免费,超出部分另计 | $0(在免费额度内) |
| I/O 操作 | 每 1M 次请求 $0.20 | $200 |
| 小计 | $3,940 | |
| 工程时间 | 10 小时/月 @ $150/小时 | $1,500 |
| 合计(Aurora) | $5,440/月 |
Aurora Global Database(多区域)
| 组件 | 配置 | 月成本 |
|---|---|---|
| 主区域 | Writer + 2 台只读 | $3,940 |
| 备用区域 | 3 台只读副本(无本地写入方) | $3,940 |
| 跨区域复制 | 约 500GB/月 | $90 |
| 小计 | $7,970 | |
| 工程时间 | 15 小时/月 @ $150/小时 | $2,250 |
| 合计(Aurora Global) | $10,220/月 |
成本对比小结
graph TD
A[2TB Database, 8K QPS] --> B{Requirement}
B -->|Single Region<br/>High Control| C[Self-Managed: $10,180/mo<br/>+ High Ops Burden]
B -->|Single Region<br/>Managed Service| D[Aurora: $5,440/mo<br/>+ Low Ops Burden]
B -->|Multi-Region<br/>Sharding Needed| E[Vitess: $14,180/mo<br/>+ Very High Ops]
B -->|Multi-Region<br/>No Sharding| F[Aurora Global: $10,220/mo<br/>+ Medium Ops]
style C fill:#fef3c7
style D fill:#bbf7d0
style E fill:#fecaca
style F fill:#bfdbfe**关键结论:**1. 单区域、不需要分片,Aurora 最省钱2. 自建 Vitess 比 Aurora 贵约 40%(含工程时间) 3. Aurora Global vs Vitess 取决于要不要分片 4. 工程时间是笔大钱 —— 常常超过基础设施本身的费用
Vitess vs Aurora:能力对比
| 能力 | Vitess | Aurora MySQL | 胜出方 |
|---|---|---|---|
| 横向分片 | 原生、自动 | 靠 proxy 手工实现 | Vitess |
| 连接池 | 内置(VTGate) | 有限(RDS Proxy) | Vitess |
| 跨区域故障转移 | 自动,30-45s | 自动,60-120s | Vitess |
| 查询缓冲 | 有(故障转移期间) | 无 | Vitess |
| 运维复杂度 | 非常高 | 低 | Aurora |
| 成本(单区域) | 更高 | 更低 | Aurora |
| MySQL 兼容性 | 95-98% | 99.9% | Aurora |
| 时间点恢复 | 需手工搭建 | 内置 | Aurora |
| 自动备份 | 自己搞 | 自动 | Aurora |
| 性能(p99 延迟) | +2-3ms 开销 | 原生 | Aurora |
| 存储自动扩展 | 手工 | 自动 | Aurora |
| 学习曲线 | 陡(3-6 个月) | 很小 | Aurora |
| 所需团队规模 | 5+ 名工程师 | 1-2 名工程师 | Aurora |
| 厂商锁定 | 无(开源) | AWS | Vitess |
| schema 变更 | 在线(gh-ost) | 在线(instant DDL) | 平手 |
各自什么时候赢
选 Vitess,当:
- 你要跨 10+ 个分片做横向分片
- 连接池是硬需求(>10K 并发连接)
- 需要多云或本地部署
- 计划内故障转移时的查询缓冲(需显式开启)对你有价值 —— 它减少丢写,但不消除
- 团队有 5+ 名工程师能长期维护它
- 故障转移必须压进 60 秒
选 Aurora,当:
- 单集群数据库规模 < 10TB
- 单主库写吞吐 < 10K QPS
- 你本来就在 AWS 上
- 团队规模 < 5 名工程师
- 成本优化是首要目标
- 运维负担越少越好
两者都考虑(混合)当:
- 有些负载需要分片,有些不需要
- 各服务的 SLA 要求不同
- 想要渐进式的迁移路径
迁移故事:从 Vitess 到 Aurora
为什么换
Vitess 稳定跑了 3 年,之后我们迁到了 Aurora。不是因为 Vitess 不行 ——它跑得相当好。 变的是这几件事:
1. Aurora Global Database 成熟了
我们上 Vitess 那会儿,Aurora Global Database 还很新,缺我们需要的那几项能力。到 2022 年, Aurora Global 已经具备:
- 跨区域复制,典型延迟 < 1 秒
- 把备用区域提升上来,实现快速的区域故障转移(通常一分钟内可写)
- 时间点恢复(区域内;跨区域恢复靠快照拷贝还原)
- 合理的成本结构
时间线上补一句:Aurora Global 的托管(用户发起)故障转移 —— 也就是能让旧主库以备用身份继续活着的那套 — — 上线得很晚:2023 年八月。在那之前,跨区域故障转移是「提升 + 重建」。今天再评估它, 真正买到的就是这条托管路径。
2. 我们从来没用上分片
Vitess 的杀手锏是横向分片。我们照着它做了设计、做了准备,但始终没跨过真正需要它的那条线。 最大的库 4.2TB —— 大,但纵向还扩得动。
3. 工程团队换人
当初落地 Vitess 的工程师走了。新人得吃 6 个月的学习曲线。Aurora 运维起来更简单, 上手更快。
4. 成本优化压力
把工程时间算进去,Aurora 便宜 30-40%。我们没法为一堆用不上的能力付这个钱。
迁移过程
阶段 1:规划(6 周)
- 用生产负载评估 Aurora 性能
- 测试应用兼容性
- 设计迁移 runbook
- 培训团队做 Aurora 运维
阶段 2:测试迁移(4 周)
- 迁移开发环境
- 迁移 staging 环境
- 对 Aurora 集群做压力测试
- 验证故障转移场景
阶段 3:生产迁移(12 周)
- 先迁最小的生产库
- 每周一套库的节奏
- Vitess 和 Aurora 并行跑做验证
- 每次迁移都演练回滚方案
阶段 4:下线(8 周)
- 盯 Aurora 性能
- 核对成本节省
- 下线 Vitess 基础设施
- 更新 runbook 和文档
结果:
- 迁移了 16 套生产库
- 零停机迁移(靠并行运行)
- 成本下降 35%(含工程时间)
- 运维事故减少 70%- 团队交付变快了(花在数据库运维上的时间少了)
决策框架:什么时候该上 Vitess
不是每个 MySQL 扩展问题都需要 Vitess。下面这套框架来自我们踩过的坑,也来自行业里的 常见模式:
flowchart TD
Start[MySQL Scaling Challenge] --> Q1{Need horizontal<br/>write scaling?}
Q1 -->|Yes, >10K writes/s<br/>per primary| Q2{Multi-cloud or<br/>on-premises?}
Q1 -->|No| Simple[Use Aurora or<br/>managed MySQL]
Q2 -->|Yes| Q3{Team has 5+<br/>engineers?}
Q2 -->|No, AWS only| Aurora["Aurora (single-region)"]
Q3 -->|Yes| Q4{3-6 month<br/>investment OK?}
Q3 -->|No| Planet[PlanetScale<br/>Managed Vitess]
Q4 -->|Yes| Vitess[Self-Hosted<br/>Vitess]
Q4 -->|No| Planet
style Vitess fill:#bbf7d0
style Planet fill:#bfdbfe
style Aurora fill:#bbf7d0
style Simple fill:#bbf7d0详细决策矩阵
| 你的处境 | 建议 | 理由 |
|---|---|---|
| 数据集 < 2TB、单区域 | Aurora 或 RDS | 纵向扩展够用,托管服务更省心 |
| 数据集 2-10TB、单区域 | Aurora,考虑加只读副本 | Aurora 处理这个量级很稳,存储自动扩展 |
| 数据集 > 10TB、单区域 | Aurora + 只读副本,或 Vitess | 先判断你需要的是分片还是读扩展 |
| Aurora 负载 I/O 很重 | Aurora I/O-Optimized(东西向流量另看 Network Optimized) | 在考虑换平台之前,这一项能明显压低 Aurora 成本 |
| 写 QPS < 5K | 单主库 + 副本 | 传统架构够用 |
| 写 QPS 5-10K | 更大规格的实例,或 Aurora | 仍在单主库能力范围内 |
| 写 QPS > 10K | Vitess 或应用层分片 | 必须横向扩展 |
| 连接数 < 1K | 常规连接池 | ProxySQL 或 RDS Proxy 够用 |
| 连接数 1K-10K | VTGate 或更强的连接池方案 | 连接管理成了关键 |
| 连接数 > 10K | 推荐 Vitess | VTGate 就是为这个量级设计的 |
| 多区域、不需要分片 | Aurora Global Database | 比 Vitess 简单,成本更低 |
| 多区域、需要分片 | Vitess 或 PlanetScale | Vitess 在这一格优势明确 |
| 团队 < 5 名工程师 | 托管服务(Aurora/PlanetScale) | 运维负担太重 |
| 团队 5-10 名工程师 | 有需要就上 Vitess,否则 Aurora | 只要理由成立,人手上够 |
| 团队 > 10 名工程师 | 需求匹配的话 Vitess 可行 | 吃得下那份运维复杂度 |
Vitess 评估清单
决定上 Vitess 之前,先拿这份清单过一遍准备度:
技术要求 ✓
- 确实需要分片 —— 写吞吐超过单主库能力(>10K QPS)
- 需要多区域 HA —— 需要跨机房故障转移,最好有查询缓冲(仅限计划内事件) 来平滑切换
- 连接池是关键 —— 应用需要 >5K 并发连接
- SQL 兼容性已验证 —— 应用查询都在 Vitess 上测过,没有阻塞项
- 分片键已确定 —— 基于访问模式的清晰分片策略
运维准备度 ✓
- 团队专业度 —— 2+ 名有分布式系统经验的工程师
- 团队投入 —— 实施期 6 个月内每周 40+ 小时专职投入
- 持续支持 —— 每周 20+ 小时的日常运维投入
- 监控基础设施 —— Prometheus、Grafana、告警体系就位
- On-call 轮值 —— 有 24/7 on-call 覆盖
- Runbook 纪律 —— 团队维护详细的运维 runbook
基础设施前提 ✓
- 有 Kubernetes —— 首选部署平台(或等价的编排方案)
- etcd 经验 —— 团队熟悉 etcd 或 ZooKeeper 运维
- 网络可靠 —— 组件之间低延迟网络(< 10ms)- [ ] 成本预算 —— 能接受高 40-60% 的基础设施成本
- 工程预算 —— 能接受 2-3 倍的运维时间
业务对齐 ✓
- 时间线现实 —— 接受 6-12 个月达到生产可用
- 战略一致 —— 和多云或本地部署战略一致
- 替代方案评估过 —— 托管方案(Aurora、 PlanetScale)考虑过,且有站得住的理由否决
- 管理层支持 —— 领导层理解复杂度与成本上的取舍
给准备度打分
- 15-20 项: Vitess 是很有力的候选
- 10-14 项: 考虑托管版 Vitess(PlanetScale)或 Aurora
- 5-9 项: 建议 Aurora 或托管 MySQL
- < 5 项: 维持现有架构, 6-12 个月后再说
团队常低估的运维现实
Vitess 在超大规模生产环境里确实能用 —— YouTube、Slack、GitHub 都靠它。但它不是「装完就不用管」的 基础设施。
学习曲线是实打实的
查询一慢,你要排查的是一条三层栈:
- VTGate(查询路由、连接池)
- VTTablet(查询执行、缓存、安全校验)
- MySQL(传统数据库运维)
需要的培训投入:
- 第 1-2 个月: 核心概念、架构理解
- 第 3-4 个月: 运维流程、监控搭建
- 第 5-6 个月: 排障、性能调优
- 第 6 个月起: 独立运维
给团队留 3-6 个月,才能独立、顺手地运维 Vitess。团队以前没运维过分布式系统的话, 这个时间线算是现实的。
监控没得商量
Vitess 每个组件都暴露 Prometheus 指标。下面这几张 dashboard 跑不掉:
| 组件 | 关键指标 | 告警阈值 |
|---|---|---|
| etcd | 共识健康度、leader 选举 | > 2 次选举/小时 |
| VTGate | 查询延迟(p50/p95/p99)、错误率 | p99 > 100ms,错误率 > 0.1% |
| VTTablet | 复制延迟、查询拒绝率 | 延迟 > 30s,拒绝率 > 0.5% |
| Orchestrator | 故障转移事件、提升失败 | 任何一次提升失败 |
| MySQL | 常规指标、慢查询日志 | 慢查询 > 1s |
Dashboard 举例: 我们维护了 8 个 Grafana dashboard,覆盖不同运维场景:
- 总览 dashboard(一眼看健康度)
- VTGate 性能
- 每个分片的 VTTablet 健康度
- etcd 集群状态
- MySQL 复制延迟
- 按类型划分的查询性能
- 故障转移历史和耗时
- 成本与资源利用率
生产经验: 监控要在切换之前搭好,不是切换之后。等 VTGate 第一次因为缺 LIMIT 拒掉查询,你会希望告警早配好了。
SQL 兼容性必须测
把这条当成准入门槛,不是脚注:应用要是在 Vitess 上过不了完整查询兼容性测试,这篇 文章里其他论证都不成立。VTGate 得先解析 SQL,才能正确路由查询。常见 MySQL 语法它 基本都支持,但确实有差异:
| 特性 | MySQL | Vitess 行为 | 变通办法 |
|---|---|---|---|
SET 语句 | 按连接生效 | 有些不会往下传 | 改用 session 变量 |
| 跨分片事务 | 不适用 | 两阶段提交,更慢 | 尽量减少跨分片写 |
| Prepared statements | 标准行为 | 缓存行为不同 | 充分测试 |
SHOW 命令 | MySQL 元数据 | Vitess 拓扑信息 | 要按不同方式解析 |
| 存储过程 | 完整支持 | 支持有限 | 要么别用,要么充分测试 |
LOCK TABLES | 支持 | 不支持 | 在应用层加锁 |
建议: 切换之前,把应用查询全部拿到 Vitess staging 上跑一遍。我们在测试阶段 发现了 8 个不兼容查询 —— 都能改,但在生产之前处理起来容易得多。
升级需要协调
Vitess 升级有固定顺序:拓扑服务 → vttablet → vtctld → vtgate(先 tablet,最后 gate,官方 升级文档就是这么写的)。
典型的升级时间线:
- 规划和测试:2-4 周
- staging 部署:1 周
- 生产铺开:2-3 周(分批)
- 验证和观察:1 周
每个组件都有版本兼容要求。不查兼容矩阵,就不能把 VTTablet 升到比 VTGate 高出三个版本。
这和托管数据库不一样 —— 托管那边升级是透明发生的。用 Vitess,可能上百个组件 要跟着一起升。
我们的升级流程:
- 读 release notes 和兼容矩阵
- 在开发环境测(1 周)
- 升级 staging(1 周,带监控)
- 升级生产 etcd 集群(维护窗口)
- 滚动升级 vttablet(一个分片一个分片来)
- 滚动升级 vtctld(不停机)
- 滚动升级 vtgate(一台一台来)
现在的 Vitess 比早期好了什么
如果你 3-5 年前评估过 Vitess,觉得它太复杂,有几处改进值得重新看看:
Kubernetes 上的 Vitess Operator
早期采用者要扛的部署复杂度,大部分被 Vitess Operator 干掉了。它管 VTTablet 生命周期、 拓扑更新和自动扩缩容。
以前(2019): 手工配每个 VTTablet、搭 etcd 集群、配网络、编排升级现在(2024+) : 用 Kubernetes Custom Resource 声明式地定义集群。实现细节交给 operator。
CRD 示例:
apiVersion: planetscale.com/v2
kind: VitessCluster
metadata:
name: production-cluster
spec:
cells:
- name: us-east
gateway:
replicas: 3
keyspaces:
- name: commerce
shards:
- name: "-80"
tabletPools:
- cell: us-east
type: replica
replicas: 2
如果你本来就在 Kubernetes 上跑,这点很关键 —— 运维模型和你现有平台一致。
PlanetScale 的托管方案
PlanetScale 提供基于 Vitess 的托管 MySQL。想要 Vitess 那套语义(分片、连接池、在线 schema 变更) ,又不想自己运维基础设施,它是现成的选择。
价格(大致,截至 2026 年):
- 免费的 Hobby 档在 2024 年四月下线 —— 已经没有永久免费档了
- 单节点生产配置大约 $30–40/月起
- Scaler Pro 和多节点/集群配置:按用量计费,成本随节点和存储很快涨上去
取舍: 用控制权和一部分定制能力,换运维简单。10 人以下的团队,这通常就是对的。
SQL 兼容性改善了
早期 Vitess 版本里的很多 SQL 怪癖已经处理掉了。VTGate 的查询规划器变聪明了,以前要改应用才跑得动的复杂 JOIN、 子查询,现在直接能处理。
兼容性改进(v15+):
- 子查询支持更好
- JOIN 优化改进
- 更多
SET语句能被正确路由 - 存储过程支持增强
- 多语句查询处理更好
剩下的缺口: 现在最常撞上的兼容问题集中在存储过程的边界情况,还有某些 SHOW命令变体 —
— 都不是基础 CRUD。
文档和社区更好了
Vitess 文档进步很大。getting-started 指南照着就能跑通,架构文档也把取舍讲得更清楚。
资料层面的改进:
- 完整的架构文档
- 手把手的 operator 部署指南
- 从原生 MySQL 迁移的指南
- 排障 playbook
- 性能调优指南
Vitess Slack 社区很活跃,里面全是在大规模跑 Vitess 的公司的工程师。文档覆盖不到的运维问题, 在这里能问到。
什么时候 Vitess 大概不适合你
Vitess 解决的是真问题,但它不是哪儿都合适:
以下情况先别上 Vitess
团队很小(< 5 名工程师):
运维开销是实打实的。用托管服务,或者在单实例 MySQL 上再待一阵,更划算。凌晨 2 点
来一次够格触发告警的事故,就能把整个团队的带宽占满。
你还在学 MySQL:
先把纵向扩展、复制和基础运维模式练熟。Vitess 是在 MySQL 基本功之上,再加一层分布
式系统的复杂度。先学会走,再学跑。
托管服务已经能满足你:
Aurora、Cloud SQL、Azure Database for MySQL 都做得相当好了。不用自建分片就能解决,
那这份运维上的省心很难被超越。诚实地问自己一句:你真的需要这份复杂度吗。
你的写模式是超大规模只追加:
该去看为这类负载设计的系统(Cassandra、ScyllaDB),而不是给 MySQL 做分片。MySQL
的事务语义和关系模型未必合适。
你可以在应用层分片:
天然就有分片边界(tenant ID、地理区域),团队又小,应用层分片可能比上 Vitess 更
简单。自写分片工作量比 Vitess 大,但只有 2-3 个分片,也许可以接受。
成本是首要考虑:
把工程时间算进去,Vitess 比托管方案贵 40-60%。成本优化排第一,那就选托管服务。
做决定
Vitess 相当复杂精密,解决的确实是 MySQL 真实存在的扩展难题:横向分片、跨数据中心故障转移, 还有大规模连接池。
要不要上,归结为几件事:
**1. 你真的需要分片吗?**纵向扩展够用,或者托管服务已经满足需求,Vitess 多半是杀鸡用牛刀。 诚实面对真实规模,不是你预期中的规模。
**2. 你的团队运维得了它吗?**要预留 3-6 个月的学习曲线,配上完整监控和持续的运维专业能力。 团队现在已经绷得很紧,这份负担可能会把你们压垮。
**3. 替代方案更差吗?**自己往应用里写分片逻辑,又复杂又容易出错。真走到那个临界点, Vitess 至少把别人验证过的模式标准化了。
**4. 收益对得起成本吗?**Vitess 会比 Aurora 贵 40-60%(含工程时间)。收益得压过这个溢价。
从生产经验看,Vitess 把 Vitess 用好的团队都有几个共同点:
- 需求明确,而且正是 Vitess 能解决的(通常是分片 + 多区域)
- 切换之前就在运维准备上投入(监控、 runbook、培训)
- 把它当成跨季度的平台投资,不是速效药
- 工程团队足够大,排得开 on-call、接得住事故
- 持续衡量这份复杂度是不是还值得
如果说的就是你,Vitess 值得认真评估。如果不是,Aurora、PlanetScale 这类托管服务大概是更好的选择。
相关阅读
- 把 50 套生产数据库迁到 Aurora —— 迁移方法和踩过的坑
资源
- Vitess 文档 —— 概念指南把架构讲得很清楚
- Vitess Slack 社区 —— 活跃的社区,适合问运维问题
- PlanetScale 博客 —— 案例研究和迁移模式
- Aurora vs Vitess 对比 —— AWS Aurora 特性对比
- 扩展 YouTube 后端:Vitess 的取舍 — — Vitess 作者的奠基性演讲
- GitHub 的 Vitess 迁移博客系列 —— 真实的迁移经验
正在评估用 Vitess 还是 Aurora 做 MySQL 扩展?欢迎聊聊架构上的取舍。