当我们谈论 PostgreSQL 可扩展性时,脑海中浮现的通常是垂直扩容的硬件上限、读写分离的延迟代价、抑或是 Citus 分片带来的运维复杂度。然而,DBOS(Database-Oriented Operating System)项目提出了一个根本性的问题:为什么不能把操作系统层面的调度、持久化、故障恢复全部交给数据库来完成?这一理念并非天方夜谭,而是基于 MIT 与 Stanford 多年研发积累的实际系统,其核心思想是将传统操作系统提供的各种服务重新定义为数据库事务操作,从而在 PostgreSQL 之上构建一个去中心化、高可用的应用编排层。
传统 PostgreSQL 扩展范式的结构性困境
在深入 DBOS 的技术细节之前,有必要梳理传统 PostgreSQL 扩展方案所面临的核心挑战。垂直扩展受限于单机硬件资源的物理上限,无论是内存、磁盘 IO 还是网络带宽,当单实例达到数万 TPS 时,成本收益比会急剧恶化。水平扩展方案则引入了分布式系统的固有复杂性:读写分离需要处理复制延迟导致的一致性问题,Citus 分片需要预先规划数据分布策略并承担跨分片查询的额外开销,而基于中间件的方案则在故障恢复、事务边界管理上带来了沉重的运维负担。
更值得关注的是,即便采用了上述扩展手段,应用层仍然需要独立的任务队列系统(如 Celery、Sidekiq)、工作流编排框架(如 Temporal、Airflow)以及配置管理服务(如 etcd、Consul)。这些组件各自维护独立的状态存储、引入额外的网络跳数、且需要专门的故障恢复逻辑。DBOS 的核心理念正是要消解这种复杂性:将所有状态集中到 PostgreSQL 一个数据源中,由数据库的事务机制统一保证持久性与一致性。
DBOS 架构的技术解析
DBOS 的技术架构可以概括为「无 orchestrator 设计」—— 应用代码通过装饰器声明工作流与步骤,DBOS 运行时在 PostgreSQL 中自动为每次步骤执行创建检查点。当工作流因崩溃、网络中断或服务重启而中断时,DBOS 利用已持久化的检查点信息,从最后一个成功完成的步骤处恢复执行,整个过程对业务代码透明无感知。这种设计将传统上需要外部编排服务才能实现的工作流持久化能力,下沉到了数据库层面。
在具体实现上,每个工作流的输入、每个步骤的输出都会被作为 JSON 或二进制数据写入 PostgreSQL 表。DBOS 运行时在执行工作流前先写入一条 PENDING 记录,步骤完成后写入该步骤的输出作为检查点,工作流完成后再写入 FINISHED 记录标记终结。这一切操作都嵌入在标准数据库事务中,利用 PostgreSQL 的 MVCC 机制保证并发安全。值得注意的是,这种检查点策略天然满足「幂等性」要求 —— 如果步骤执行成功但事务提交前发生故障,重启后的工作流会检测到检查点已存在,直接返回缓存结果而非重复执行。
分布式场景下的工作流恢复则依赖 DBOS Conductor 组件。Conductor 通过 WebSocket 与应用服务器保持长连接,当检测到某台服务器失联(连接断开且超过 grace period)时,自动将该服务器上正在执行的工作流重新调度到其他健康节点。整个恢复过程不涉及数据库状态的额外修改,因为所有执行上下文早已持久化在 PostgreSQL 中。Conductor 本身是「带外」服务,仅负责观测与恢复调度,不参与工作流的实际执行路径,这意味着即使 Conductor 完全不可用,工作流仍能正常运行 —— 这是一条关键的架构设计原则。
可扩展性参数与基准数据
DBOS 官方公布的基准测试数据为工程决策提供了重要参考。在单 PostgreSQL 实例配置下(具体硬件未披露,但推测为通用云服务器规格),DBOS 应用可以持续达到每秒超过 4 万个工作流或步骤的执行吞吐量。这一数字远高于大多数业务场景的实际需求 —— 即便对于日处理数千万请求的中大型互联网平台,单实例也已足够支撑绝大多数业务线的工作流编排需求。
当单实例吞吐量不足以满足需求时,DBOS 支持水平扩展到多个 PostgreSQL 数据库。分片策略基于工作流标识符的哈希值进行路由,不同工作流写入不同的数据库实例。分片数量可以根据吞吐量增长平滑扩展,无需修改业务代码。这种「数据库即编排层」的架构,使得整个系统可以在不引入 Redis、Kafka、etcd 等额外组件的情况下,达到传统分布式系统难以企及的简化程度。
对于并发控制,DBOS 队列提供了细粒度的流量控制参数。每个队列可以独立设置 worker concurrency(单个服务器上该队列的并发工作流数量)以及总体的分发速率限制。例如,一个索引任务队列可以配置为每个 worker 节点最多并发执行 10 个工作流,同时限制全局新任务启动速率不超过每秒 1000 个。这些参数通过 DBOS SDK 在应用层声明,无需修改数据库配置或引入额外中间件。
工程落地的关键参数建议
基于 DBOS 架构特性和实际生产经验,以下参数配置可以作为初始上线的参考基准。对于大多数 Web 应用场景,建议将单 PostgreSQL 实例的连接池上限设置为 100 至 200 之间 —— 这个数值足以支撑数十台应用服务器每台 5 至 10 个并发工作流的执行密度,同时避免连接耗尽。如果业务特征是大量短时工作流(执行时间小于 1 秒),可以适当提高连接池上限;如果是少量长时运行的工作流,则应降低并发连接数,为每个工作流预留更长的持有时间。
检查点大小的控制是另一个关键的工程考量。DBOS 默认会将步骤的返回值完整写入数据库,如果步骤返回大型对象(如文件内容、复杂 JSON),会导致数据库写入量激增进而影响吞吐量。建议的工程实践是:步骤仅返回指向数据的指针(如 S3 对象键、数据库记录 ID),大型数据存储在对象存储服务中。这一原则与「小状态写入」的数据库设计最佳实践一脉相承。
在分片扩展的决策上,建议以单实例吞吐量降至每秒 2 万工作流作为扩容触发阈值。由于 DBOS 的分片是逻辑层面的路由策略而非物理数据迁移,分片数量的调整可以在运行时动态完成而无需停机。但需要注意的是,分片后的跨分片查询与事务一致性需要应用层额外处理 —— 这与 Citus 等分片方案的约束一致,只是在 DBOS 场景下,分片的目的是分离工作流调度负载而非分离数据本身。
小结
DBOS 代表了一种将数据库角色从「数据持久化层」扩展为「应用编排层」的范式转变。它利用 PostgreSQL 成熟的 ACID 事务能力,在不引入外部编排服务的前提下,实现了工作流的自动检查点、故障恢复与分布式调度。其单实例超 4 万 TPS 的吞吐量,对于绝大多数企业级应用已经充足;水平扩展通过多 PostgreSQL 分片实现,保留了数据库运维经验的延续性。对于正在构建高可靠、低运维复杂度系统的团队,DBOS 提供了一条值得认真评估的技术路径。
参考资料
- DBOS Architecture Documentation: https://docs.dbos.dev/architecture
- DBOS: A DBMS-oriented Operating System (VLDB 2022): http://www.vldb.org/pvldb/vol15/p21-skiadopoulos.pdf