近年来,随着业务规模的不断扩展,传统的单一Postgres数据库面临着性能瓶颈和可扩展性限制。尤其是在大型促销活动和流量激增期间,单库的架构难以满足高并发请求和海量数据处理的需求。Gadget作为一家服务成千上万电商应用的平台,深刻感受到垂直扩展的瓶颈以及升级数据库版本的压力。为了突破困境,Gadget团队选择了数据库分片,并制定了零停机分片的战略目标,保障用户应用在此过程中持续稳定运行。本文将揭秘Gadget利用维护模式原语,分阶段拆分Postgres数据库,实现零停机横向扩展的实践经验和技术细节。 在Gadget的系统架构中,最初所有业务数据均驻留于单一的Postgres实例中,包括平台自身的控制信息和各个用户应用的数据。
虽然单库架构便于管理和访问,但随着数据量和访问峰值的增加,这种"巨兽"数据库逐渐暴露出性能瓶颈。尤其是在像2025年黑色星期五、网购星期一这类流量暴涨达400%的关键时刻,Gadget意识到单实例数据库已无法承载未来的发展需求。同时,Postgres 13版本的生命周期将至,也迫使团队必须进行数据库版本升级。 面对这双重挑战,Gadget的技术团队决定采用水平拆分(sharding)的策略,将庞大且不可预测的数据平面从控制平面中剥离出来。数据平面中包含成千上万个应用的数据,结构多样、操作复杂且访问高频,而控制平面相对固定且访问量较低。通过此举,团队能够保持相对轻量的控制平面数据库,方便升级和维护,同时将数据平面分散到多台Postgres实例中,实现真正的负载均衡和弹性扩展。
传统的数据库分片往往伴随着极具风险的"万湖大改"式切换,即在某一时刻强制所有服务指向新的分片结构,一旦操作出现差错,便可能导致请求中断甚至数据不一致。回顾以往的经验,Gadget团队深知这种"一刀切"式方案名副其实"艰苦且危险",因此拒绝采用这种高风险方案。相反,团队设计了一个按应用逐步迁移的增量式分片流程,既能够安全验证切换的正确性,又极大降低了切换风险。 整个迁移方案分为两大阶段。第一阶段是将用户应用的数据从核心数据库分片到新的Postgres集群。该步骤包含复制应用的数据库模式和数据,确保目标数据库能够完全承接原有数据写入和读取请求。
第二阶段则是对精简后的控制平面进行无感知、零停机的版本升级,进一步提升整体系统的稳定性与性能。 在第一阶段,核心挑战在于如何保证迁移过程中的数据一致性、请求不断和业务无感知。Gadget团队结合Postgres强大的逻辑复制功能,通过逻辑复制流实时同步源数据库和目标数据库的数据变动,确保新库的数据始终与旧库保持接近实时同步。迁移时,针对每个应用,先准备目标库的schema结构,启动复制流,将数据和后续变更及时复制过去。复制延迟的监控和管理成为保障数据完整性的关键环节。 真正的难题在于切换时的数据库访问控制。
因为要实现切换瞬间数据同步且请求不中断,必须保证无新的写请求同时进行在旧数据库。为此,Gadget团队巧妙设计了维护模式原语(maintenance mode),作为一个轻量级但极其重要的工程工具。维护模式可以在不引发服务错误或丢失请求的情况下,对指定应用的数据库流量施加短暂且瞬时的"暂停",即让后续数据库请求排队等待。整个暂停过程长度往往仅数秒,处于绝大多数用户几乎不可觉察的时间范围内。 维护模式通过Postgres的顾问锁(advisory locks)实现排他访问机制。普通数据访问持有共享锁,允许并发读取和写入;而需要执行维护活动时的操作会尝试获取排他锁,确保在该期间没有其他流量进入数据库。
一旦排他锁获得,所有共享锁请求自动进入等待队列,数据库访问"暂停"。维护活动完成后,排他锁释放,请求恢复并行处理。该机制依托于Postgres已有的锁模型,保证了极高的可靠性和一致性,无需为维护窗口额外引入复杂中间件。 维护模式的另一个核心设计是尽量减少对正常工作流程的影响。为此,团队将所有数据库访问统一封装在内部的AppWorkUnit上下文对象中,所有数据库连接请求均通过该对象进行。这样一来,可以在单一代码路径中注入维护模式的锁检测逻辑,杜绝绕过维护检查的潜在风险,确保每个访问都受控且受保护。
这种设计不仅方便代码管理,也提升了系统的整体健壮性。 当数据库切换启动时,维护模式首先将"接近维护窗口"的标志设为真,通知系统所有参与者即将进入维护状态。随后,系统等待足够时间,确保所有已有请求完成,缓存的环境状态更新。之后,切换过程通过获取排他锁正式开始,所有并发请求被短暂停止。此时,复制流经过验证已完全同步最新数据,控制平面指向新数据库作为数据的唯一来源。切换完成后释放排他锁,业务请求恢复正常。
通过以上方案,Gadget实现了对每个应用独立分片的迁移,支持将小批量不重要的应用先行迁移验证流程,再逐步扩大至核心客户和关键应用。这种"分而治之"的策略极大降低了风险,保证了系统的高可用性和业务的连续性。迁移过程中最长的维护模式等待时间不过4秒,95%的维护窗口在250毫秒以内,极大提升了用户体验和系统可靠度。 此外,逻辑复制的灵活性也帮助团队实现了Postgres的平滑版本升级。相比传统的二进制复制只能在同版本间进行,逻辑复制支持跨主版本复制,保障了数据迁移和环境切换的无缝衔接。其与维护模式的协同使用,使得数据库升级成为可控的低风险事件。
Gadget团队在实际迁移过程中也遇到了许多挑战。其中,监控复制流的实时状态、判断何时真正追平源端数据、清理残留数据以及优化最大复制工作线程数等均需要深厚的数据库专业知识和细致的运维经验。团队通过大量内部测试和反复的演练,打造出一套成熟、可复用的数据库分片迁移流程。 当前,Gadget已成功完成所有环境的分片迁移,不仅实现了水平扩展,使系统更具弹性和可伸缩性,也为即将到来的流量高峰奠定了坚实基础。新硬件提供了更优的性能表现和更高的稳定性,整个过程避免了显著维护窗口和用户体验的突然下降。 总结来看,Gadget利用维护模式原语,结合Postgres逻辑复制技术,打破了传统数据库分片的高风险"魔咒",实现了零停机、无缝迁移。
其创新设计和稳健流程,为同样面临高流量挑战和数据库升级压力的企业提供了宝贵的实践参考。通过细致的环境划分、增量式的迁移策略,以及精巧的锁机制管理,Gadget不仅保障了数据安全和业务连续,也为后续功能迭代和架构演进提供了坚实的技术基础。在未来,随着业务不断发展,类似的维护模式和分片思路将在更多场景中发挥更大价值,为现代数据库架构的发展注入新的活力。 。