让 MySQL 的水平分片变得简单
对于开发人员来说,构建应用程序时选择事务型数据存储显然是一个成熟的选择。然而,随着应用成功,规模也随之扩大。单一的数据库在初期运作良好,但随着应用的增长,其数据规模最终会超出单台服务器的优化范围。
引入读实例(Read Replica)能提高性能,但可能会带来主数据库与读实例之间的延迟,从而导致应用的性能或数据正确性问题。这些复杂情况有时需要进行重大架构调整,迫使开发团队在应用性能与数据一致性之间作出困难的取舍。而扩展写入流量的挑战则更为严峻,例如,即使是最大的 MySQL 数据库在某个临界点也会遇到性能瓶颈。
水平分片
这并不是什么新问题,企业多年都在面对这种挑战,而水平分片(Horizontal Sharding)是解决它的核心模式之一。水平分片是指将一个 MySQL 数据库的数据划分到多个数据库服务器中,每个服务器拥有相同的架构。这样可以将单个数据库的工作负载分布到多个数据库服务器上,优点是可以线性扩展,通过添加更多数据库服务器解决性能瓶颈。
每台数据库服务器被称为一个“分片”(Shard)。拥有多个分片可以减少单服务器处理的读写流量,并使数据保持在单服务器的优化尺寸范围内。然而,处理多台服务器而不是单台服务器则会增加诸如查询路由、备份与恢复、架构迁移和监控等运维复杂度。
MySQL 数据库的垂直扩展与水平扩展
在初期阶段,通常通过垂直扩展数据库来提高性能,比如增加云实例的容量或购买更强大的机器(具有更多 CPU 核心、RAM 和存储空间)。这可以提高 MySQL 数据库的速度和容量,使其能够处理更多连接、更快执行查询,并有效扩展。
虽然看上去是个简单的解决方案,但却是一个短期的方式:只需购买更多资源即可解决扩展问题。然而,当应用数据规模进一步增长时,基于性能和成本方面的原因,以水平扩展的方式对数据库进行扩展会带来更多收益。
数据库过度配置的成本
为可能的流量激增或者使用情况预留过度配置的硬件是非常低效的。使用这种方式,你最终可能会支付许多短期不需要的资源成本,仅仅是为了应对预计的流量高峰。一旦当前的机器超出容量,下次升级的硬件可能会增加 50% 的容量,而实际情况下你可能只使用其中的 10%。
当基础设施成本因为不断的过度配置而与业务需求脱节时,团队通常会探索水平扩展的方法。与增加单台服务器的资源不同,水平扩展是通过增加更多服务器实例来承载增长的工作负载。这种更加细粒度的方式使得可以选择较小的主机,从而更高效地投资于基础设施。
应用层的分片问题
一些公司选择在应用层实现水平分片。在这种方法中,所有将查询路由到正确数据库服务器的逻辑都存在于应用中。这需要在应用中增加额外逻辑,每当添加新功能时都必须进行更新。除此之外,应用还需要实现跨分片功能。此外,随着数据的增长和初始分片容量耗尽,“重新分片”(Resharding,即增加分片数量)成为一个极为复杂的运维挑战,且必须在持续服务流量的状态下完成。
Pinterest 曾尝试此方法。在尝试使用主流 NoSQL 技术后发现它们当时尚不成熟,于是选择应用层分片的方法。Pinterest 通过主键将数据映射到分片中实现扩展,但这种方式牺牲了跨分片联结(Cross-shard Join)的功能和外键支持。同样,Etsy 在迁移到分片数据库系统时采用了类似方法,增加了一种双向查找主键机制,将 shard_id
与主键绑定,并将分片打包到主机上以简化分片管理。然而,两个案例都表明,持续的分片管理,比如在初始重新分片后进一步拆分分片,操作起来非常复杂。
从这些尝试中可以看到,将分片逻辑放到应用层会引入大量复杂性,导致应用和数据库的管理变得更加困难。这不仅耗费开发人员的时间,也会使团队无法专注于为客户构建和改进产品。
使用 Vitess 进行水平分片
除了应用层的分片,还出现了一种新的水平分片方式。2010 年,YouTube 的工程师开始构建开源项目 Vitess。Vitess 位于应用和 MySQL 数据库之间,使水平分片数据库对应用看起来像是一个单体数据库。Vitess 不仅从应用中移除了查询路由的复杂性,还提供了主故障转移、备份解决方案,以降低操作分片系统的复杂性,同时还具备连接池(Connection Pooling)和查询重写(Query Rewriting)等功能以提高性能。
像 Square(可以阅读他们对 Cash App 分片方法的探索) 、Slack、京东、Hubspot 等许多企业都使用 Vitess 来扩展 MySQL 数据库。京东(中国最大的在线零售商之一)在双十一期间,使用 Vitess 处理了每秒 3500 万的查询流量(QPS)。Slack 将所有数据库迁移到 Vitess 平台,在 2020 年的居家办公流量高峰中依然能稳定运行。Etsy 和 Pinterest 也将部分工作负载迁移到 Vitess,因为它提供了比应用层分片更好的管理体验。Vitess 已一次次证明它能够在超高负载的生产环境中运行,并且比应用层分片提供了更好的使用体验。
使用 PlanetScale 实现 MySQL 水平分片
“我们希望 PlanetScale 和 Vitess 为 MyFitnessPal 带来与 Kubernetes 对应用交付和部署所带来的便利相似的效用。数据库管理是复杂的,我们更愿意让 PlanetScale 管理它。”
然而,即使使用 Vitess 在大规模情况下运行,依然需要一支拥有相关经验的工程团队。并非所有公司都像 Slack 和 Square 那样具备这种深度。因此,PlanetScale 将 Vitess 的许多功能和能力进行了简化和民主化,包括水平分片、在线架构迁移等。在 PlanetScale 中,你可以无需全面了解 Vitess 即获得其全部功能,避开构建和运行 Vitess 可能存在的风险和错误。PlanetScale 是唯一一个基于 Vitess 构建的、兼容 MySQL 的数据库平台。
PlanetScale 提供了一个托管数据库平台,目前支持 Postgres 和 Vitess。通过 Vitess,任何人都可以访问这种高扩展性来扩展他们的 MySQL 数据库。你可以从一个单一的 MySQL 实例开始,随着业务增长而逐步扩展。当需要水平分片时,你可以直接在现有的 PlanetScale 数据库上设计分片方案,无需因为扩展而更换数据库。同时,你还可以享受 PlanetScale 数据库平台带来的功能,比如数据库分支、无阻塞架构更改、架构撤销、内置查询性能分析(Insights)等等,以及 Vitess 带来的扩展性。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
本文链接:http://folen.top/2025/09/13/horizontal-sharding-for-mysql-made-easy/