一百万连接
无服务器计算架构的一个强大功能是能够设计并横向扩展栈中的各个组件,从而动态分配更多计算资源,仅在需要时使用。数据库是无服务器栈的重要组成部分,但使用无服务器函数的用户发现一个非常普遍的问题:连接限制。用户不得不使用诸如 pgBouncer 之类的代理来处理即使是很小的工作负载。对于使用 MySQL 的开发人员而言,由于用户突然激增,他们常常遭遇令人生畏的“连接过多”错误。
单机数据库在很大程度上依赖于其对内存使用进行分区的能力,以提供我们所期待的强隔离性,因此它需要为每个连接分配一定的内存缓冲区。在我们创建的连接越多时,整体缓冲池可用的内存就越少,因此 MySQL 内置了一个名为 max_connections 的变量,作为一种“最后防线”。该设置会在达到配置的上限后阻止新的连接被建立,这对避免数据库层面因内存相关问题导致的宕机级别的情况(例如意外的拒绝服务攻击)至关重要。虽然最开始可能觉得提高此变量似乎没什么害处(您可能还未达到实例的内存限额),但让 MySQL超负荷工作(即内存资源超分配)会带来危险的崩溃和潜在的停机风险,因此这不是推荐的做法。
应用程序连接池
建立连接和清理连接同样需要时间和计算资源,因此许多开发框架提供了内置功能,例如连接池。连接池允许事先建立一批连接,并让应用程序在这端排队等待数据库请求。这种方式对优化性能以及作为数据库端的保护功能非常有效。但是,当试图扩展无服务器栈时,应用程序端连接池也会成为一个类似具有挑战性的问题领域。
PlanetScale 连接池
为了保护并优化 MySQL 的连接管理,Vitess 和 PlanetScale 提供了 VTTablet 级别的连接池功能。这能够随您的集群规模进行扩展,同时也可以在应用程序突然扩展时,将来自大量水平启动进程的查询在这一侧排队。这在内存管理角度上保障了底层 MySQL 的进程安全,并且允许您根据需求增加工作线程以扩展应用程序。
除此之外,PlanetScale 的全球路由基础设施提供了另一个横向可扩展的连接层,我们最近测试了这一功能,为更广泛地推出我们的无服务器驱动程序做好准备。
PlanetScale 的连接基础设施示意图
一百万个 MySQL 连接
Vitess 连接池与 PlanetScale 全球路由基础设施的结合使我们能够维持几乎无限的连接。我们决定通过在 PlanetScale 数据库上运行一百万个活动连接来验证这一点。按照我们的“一百万”主题博客,这个目标本质上只算是一个随意的数字。当然,我们的架构设计旨在横向扩展到远超这一点。但这个数量足够满足我们大部分用户的需求,同时也展示了该架构的能力。
为了隔离连接层,我们设计了一个测试环境,使用 AWS Lambda,并采用扇出模式运行一个简单的 Go 可执行文件,该文件使用 go-sql-driver 来建立多个并行连接。
在这里我们发现一个有趣的事实:默认情况下,Lambda 运行时环境有一个硬性 open_files 限制为 1024,函数并发限制为 1000。因此,我们将测试设置为总计运行完全 1000 个“工作函数”,每个函数建立 1000 个连接,以保持在 Lambda 运行时限制范围内。
每个工作循环执行以下操作:
- 打开一个新的 MySQL 连接
- 一旦建立连接,就发送一个简单查询来验证我们可以与底层数据库通信
- 等待其他循环完成创建它们的连接
- 一旦达到期望的并发性,所有工作线程被指示额外等待几分钟保持开放连接,然后再关闭,以便我们可以在监控中轻松观察到稳定的并行性。我们能够在不到两分钟内扩展到总共一百万个开放连接,并保持稳定运行。
图表显示总开放连接从 0 上升到一百万,用时两分钟,在接下来的五分钟内保持稳定,然后回落至 0
PlanetScale 全球路由基础设施已准备好处理您的无服务器函数工作负载。注册尝试,或联系我们了解如何让我们的可扩展性为您的应用程序服务。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
本文链接:http://choupangxia.cn/2025/09/10/one-million-conections/