Hotdry.

Article

Postgres 作为工作流持久化底座:无编排器的 Exactly-Once 语义实现

以 Postgres 事务与 CDC 为持久化底座,实现工作流状态机与 exactly-once 语义,避免专用编排服务的运维负担。

2026-05-28systems

Postgres 作为工作流持久化底座:无编排器的 Exactly-Once 语义实现

传统的工作流编排方案(如 Temporal、Camunda)通常要求部署独立的状态服务器集群,这不仅增加了基础设施复杂度,还引入了额外的运维负担和网络延迟。DBOS Transact 提出了一种截然不同的思路:利用现有的 Postgres 数据库作为持久化底座,通过轻量级装饰器实现工作流的 durable execution,让应用在崩溃后能从最后一个完成的步骤自动恢复。

核心设计:数据库即状态机

DBOS 的核心洞察在于将工作流状态直接持久化到 Postgres 的系统数据库中,而非依赖外部协调服务。每个被 @DBOS.workflow() 装饰的函数及其内部的 @DBOS.step() 步骤,都会在执行前后自动记录状态检查点。

这种设计的关键优势在于零基础设施增量:如果你的应用已经在使用 Postgres,只需配置系统数据库连接串即可启用持久化能力,无需部署新的中间件。DBOS 支持 Python、TypeScript、Go 和 Java,通过语言原生的装饰器模式侵入业务代码。

@DBOS.step()
def process_payment(order_id: str):
    # 支付逻辑
    pass

@DBOS.step()
def send_confirmation_email(order_id: str):
    # 邮件发送逻辑
    pass

@DBOS.workflow()
def checkout_workflow(order_id: str):
    process_payment(order_id)
    send_confirmation_email(order_id)

当应用在执行过程中崩溃(如进程被终止或节点故障),重启后 DBOS 会自动从系统数据库读取检查点,识别出哪些步骤已完成,并从下一个待执行步骤恢复。这意味着已完成的支付操作不会被重复执行,实现了 exactly-once 语义。

技术实现:事务边界与 CDC

DBOS 的持久化机制建立在 Postgres 的事务保证之上。每个步骤的执行被包装在数据库事务中,步骤完成时状态变更与业务数据写入原子性提交。这种设计利用了 Postgres 的 MVCC 和 WAL(Write-Ahead Log)机制,确保即使在极端故障场景下也不会丢失状态。

对于事件驱动场景,DBOS 结合 CDC(Change Data Capture)实现可靠的事件处理。当外部事件(如 Kafka 消息)触发工作流时,DBOS 确保每个事件被处理且仅被处理一次 —— 通过在工作流开始时记录事件 ID 到系统数据库,并在 Postgres 层面实现幂等性检查。

@DBOS.workflow()
def on_customer_registered(event: dict):
    # 事件 ID 自动去重
    create_user_profile(event['customer_id'])
    send_welcome_email(event['email'])

可落地参数与配置清单

要在生产环境部署基于 DBOS 的持久化工作流,需要关注以下配置参数:

系统数据库配置

  • DBOS_SYSTEM_DATABASE_URL: 指向专用 Postgres 实例的连接串,建议与业务数据库分离
  • 默认使用 SQLite(开发环境),生产环境必须配置 Postgres
  • 连接池大小:根据并发工作流数量调整,建议初始值 10-20

并发与队列

  • DBOS.enqueue_workflow(): 异步执行步骤,支持并发度控制
  • 队列注册:DBOS.register_queue("queue-name") 启用分布式队列
  • 并发限制:通过队列配置限制同时执行的步骤数,避免资源过载

恢复与监控

  • 自动恢复:应用启动时自动扫描未完成的 workflow,从最后检查点恢复
  • OpenTelemetry 集成:自动生成日志、追踪和指标,无需额外配置
  • 超时处理:长时间运行的步骤可配置超时和重试策略

高可用考虑

  • 系统数据库需配置主从复制,避免单点故障
  • 应用实例可横向扩展,多个实例共享同一系统数据库
  • DBOS Conductor(可选):提供图形化界面管理工作流状态,支持手动暂停、恢复、分叉

与专用编排器的对比

相比 Temporal 等方案,DBOS 的最大区别在于架构简洁性

维度 Temporal DBOS Transact
基础设施 需部署独立服务器集群 仅依赖 Postgres
运维负担 高(需维护状态服务) 低(复用现有数据库)
延迟 网络 RPC 到状态服务 本地数据库写入
语言支持 需 SDK 适配 原生装饰器
适用规模 超大规模分布式 中小型到大型

DBOS 特别适合以下场景:

  • 已有 Postgres 基础设施,希望最小化工作流引入成本
  • 需要 exactly-once 语义但不想维护复杂的状态服务
  • AI Agent 工作流,需要可靠的步骤执行和恢复能力
  • 定时任务和 Cron Job,需保证不重复执行

限制与注意事项

尽管 DBOS 简化了基础设施,仍需注意以下限制:

  1. 数据库依赖:系统数据库成为关键路径,需确保 Postgres 的高可用性
  2. 步骤粒度:检查点只在步骤边界写入,长步骤内的崩溃会导致重新执行整个步骤
  3. 外部副作用:如果步骤包含无法回滚的外部调用(如发送邮件),需自行实现幂等性
  4. 性能边界:虽然官方宣称支持每日 40 亿工作流,但超大规模场景仍需基准测试验证

结语

DBOS Transact 展示了一种回归本质的工作流设计哲学:利用数据库的 ACID 特性实现状态持久化,而非构建复杂的分布式状态机。对于希望引入工作流能力又不想承担专用编排服务运维负担的团队,这种 "Postgres 即状态机" 的模式提供了一个务实的中间路线。

随着 AI Agent 和自动化工作流的普及,轻量级、低运维的持久化执行方案将越来越受关注。DBOS 的开源策略(100% 开源,可本地或自托管运行)也降低了采用门槛,值得在下一个需要可靠工作流的项目中评估。


资料来源

systems

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com