1中间件选型背景
为什么需要数据库中间件?
当业务增长到一定规模,单库单表会面临以下瓶颈:
• 单表数据量过大(千万到亿级),查询性能急剧下降
• 单库连接数耗尽,无法支撑更多并发
• 单机存储容量不足
• 读写混合导致主库压力过大
解决思路:
• 读写分离:读请求分发到从库,减轻主库压力
• 分库分表:将数据水平拆分到多个库/表
• 弹性扩缩容:按需增减数据库节点
三款主流中间件定位:
Apache ShardingSphere(19k+ Stars)
定位:分布式数据库生态系统
模式:Proxy(独立部署)+ JDBC(嵌入应用)
语言:Java
ProxySQL(6k+ Stars)
定位:高性能 MySQL 协议代理
模式:Proxy(独立部署)
语言:C++
Vitess(19k+ Stars)
定位:面向云原生的 MySQL 水平扩展方案
模式:Proxy(独立部署)
语言:Go
来源:YouTube 内部诞生,CNCF 毕业项目
3ProxySQL 深度解析
架构特点:
ProxySQL 是一个轻量级高性能的 MySQL 协议代理,核心设计理念是「做好一件事」。
部署模式:
• 单独部署在应用和 MySQL 之间
• 支持集群模式(ProxySQL Cluster)实现高可用
• 配置持久化在内置 SQLite 中
核心功能:
1. 查询路由(★★★★★)
• 基于正则匹配的灵活路由规则
• 支持读写分离、按用户/Schema/SQL 特征路由
• Query Rules 链式匹配
2. 连接池管理(★★★★★)
• 多路复用:前端 1000 连接 → 后端 50 连接
• 连接预热和重用
• 自动剔除不可用后端
3. 查询缓存(★★★★☆)
• 内置查询结果缓存
• 按规则配置缓存 TTL
• 减少后端数据库压力
4. 监控与统计(★★★★☆)
• 内置 Admin 管理接口(MySQL 协议)
• 实时查询统计和慢查询分析
• 后端健康检查
运维命令示例:
mysql -h127.0.0.1 -P6032 -uadmin -padmin
-- 查看后端状态
SELECT * FROM runtime_mysql_servers;
-- 添加路由规则(读请求走从库)
INSERT INTO mysql_query_rules (rule_id, match_pattern, destination_hostgroup)
VALUES (1, '^SELECT', 20);
-- 加载配置
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
优势:
• 性能极高(C++ 实现,微秒级延迟)
• 配置灵活,热加载无需重启
• 运维友好,通过 SQL 接口管理
• 成熟稳定,生产验证充分
不足:
• 仅支持 MySQL 协议
• 不支持分库分表(只做路由和代理)
• 无内置分布式事务支持
• 分片需要配合其他方案
4Vitess 深度解析
架构特点:
Vitess 诞生于 YouTube,专为超大规模 MySQL 集群设计。2019 年成为 CNCF 毕业项目,是 Kubernetes 原生的数据库扩展方案。
核心组件:
• VTGate:查询路由层(无状态,可水平扩展)
• VTTablet:每个 MySQL 实例的 Sidecar 代理
• Topology Service:拓扑元数据存储(etcd/ZooKeeper/Consul)
• VTAdmin:Web 管理界面
• vtctld:集群管理守护进程
核心功能:
1. 水平分片(★★★★★)
• Keyspace + Shard 概念
• 支持 Range 和 Hash 分片
• 在线 Resharding(不停机重新分片)
• VSchema 定义分片策略
2. 连接池化(★★★★★)
• 大幅减少 MySQL 连接数
• 支持数万前端连接
3. 在线 Schema 变更(★★★★☆)
• 内置 Online DDL(基于 gh-ost/pt-osc)
• 跨 Shard 统一执行 Schema 变更
4. 云原生支持(★★★★★)
• Kubernetes Operator
• Helm Chart 一键部署
• 自动故障转移和修复
适用场景:
• 超大规模 MySQL 集群(TB 到 PB 级)
• Kubernetes 原生环境
• 需要在线 Resharding 的业务
• 已有 YouTube、Slack、GitHub、Square 等生产验证
优势:
• 真正的水平无限扩展
• 云原生 + Kubernetes 深度集成
• 在线 Resharding 能力业界领先
• CNCF 毕业项目,社区生态完善
不足:
• 架构复杂,学习曲线陡峭
• 部署和运维成本高
• 不支持所有 MySQL 语法(如跨 Shard JOIN 有限制)
• 小规模场景大材小用
5三款中间件对比
┌──────────────────┬──────────────────┬──────────────────┬──────────────────┐
│ 对比维度 │ ShardingSphere │ ProxySQL │ Vitess │
├──────────────────┼──────────────────┼──────────────────┼──────────────────┤
│ 核心定位 │ 分布式数据库生态 │ MySQL 高性能代理 │ MySQL 水平扩展 │
│ 分库分表 │ ★★★★★ │ ☆☆☆☆☆ │ ★★★★★ │
│ 读写分离 │ ★★★★☆ │ ★★★★★ │ ★★★★☆ │
│ 连接池 │ ★★★☆☆ │ ★★★★★ │ ★★★★★ │
│ 查询缓存 │ ☆☆☆☆☆ │ ★★★★☆ │ ★★☆☆☆ │
│ 分布式事务 │ ★★★★☆ │ ☆☆☆☆☆ │ ★★★☆☆ │
│ 数据库支持 │ MySQL + PG │ 仅 MySQL │ 仅 MySQL │
│ 部署复杂度 │ 中等 │ 简单 │ 复杂 │
│ 性能开销 │ 中等 │ 极低 │ 低 │
│ 云原生支持 │ ★★★☆☆ │ ★★☆☆☆ │ ★★★★★ │
│ 中文社区 │ ★★★★★ │ ★★★☆☆ │ ★★☆☆☆ │
│ 学习曲线 │ 中等 │ 平缓 │ 陡峭 │
│ 开源协议 │ Apache-2.0 │ GPL-3.0 │ Apache-2.0 │
└──────────────────┴──────────────────┴──────────────────┴──────────────────┘
性能对比(参考值):
• ProxySQL:读请求延迟 < 0.1ms(转发开销)
• ShardingSphere-Proxy:延迟约 1-3ms
• Vitess VTGate:延迟约 0.5-1ms
注意:实际性能取决于查询复杂度、网络环境和配置优化。
6选型建议
场景一:读写分离 + 连接池
推荐:ProxySQL
理由:轻量高效,部署简单,读写分离和连接池是其强项。几分钟即可上线,对应用完全透明。
场景二:分库分表(Java 技术栈)
推荐:ShardingSphere-JDBC
理由:嵌入式集成无额外运维成本,分片策略灵活,中文社区活跃,文档完善。
场景三:分库分表(多语言技术栈)
推荐:ShardingSphere-Proxy
理由:兼容 MySQL/PG 协议,对应用透明。如果团队主要使用 MySQL 且规模不大,ShardingSphere-Proxy 比 Vitess 更容易上手。
场景四:超大规模 + 云原生
推荐:Vitess
理由:专为超大规模设计,在线 Resharding 能力业界领先。如果已经运行在 Kubernetes 上,Vitess 是最佳选择。
场景五:ProxySQL + ShardingSphere 组合
适用场景:需要分库分表 + 极致的连接池管理
架构:应用 → ProxySQL(连接池 + 缓存)→ ShardingSphere-Proxy(分片)→ MySQL 集群
不建议选择中间件的场景:
• 数据量 < 1000 万 → 先优化索引和查询
• 可以用分区表解决 → 分区表比分库分表简单得多
• 可以用读副本解决 → 云数据库自带读副本功能
与 ora100 生态的配合:
• DBCheck 可用于监控中间件后端的数据库健康状态
• 建议先用 MySQLTuner 做性能评估,确认瓶颈后再引入中间件