2. 生产环境架构设计

生产环境架构设计的第一步不是选软件版本,而是把业务负载的“形状”看清楚。PostgreSQL 同一套内核既能支撑高频小额事务,也能承担大规模分析查询,但两者的资源画像、并发模型和优化方向差异极大。架构选型错误,后期往往只能靠堆硬件或拆库来补救,代价很高。

一、先判断负载类型:OLTP 与 OLAP 的核心差异

OLTP(联机事务处理)的典型特征是短事务、高并发、按主键或索引访问少量行,例如订单创建、支付状态更新、库存扣减。它关心的是每秒事务数(TPS)、响应时间 P95/P99、锁等待和连接数。OLAP(联机分析处理)则以大范围扫描、聚合、多表关联为主,例如按月份统计区域销售、用户行为漏斗分析,它关心的是扫描行数、I/O 吞吐、临时文件大小和单条查询耗时。

判断方法可以看三个指标:单条 SQL 平均返回行数、读写比例、并发连接数。若平均返回行数在几十到几百、写占比超过 20%、并发连接数百,基本属于 OLTP;若单条查询扫描百万行以上、读占比超过 90%、并发连接数不高但单查询耗时长,则偏 OLAP。混合负载(HTAP)场景需要进一步拆分:核心交易走 OLTP 主库,报表分析走只读副本或独立分析库,避免大查询拖垮事务。

二、单机、主从与集群架构对比

单机架构部署简单、无复制延迟,适合开发测试、小型内部系统或可接受分钟级停机的业务。它的风险是单点故障:磁盘损坏、主机宕机、误删数据都会直接导致服务中断。生产核心库不建议长期使用单机。

主从架构(流复制)是 PostgreSQL 生产环境最常见的高可用基础。主库承担读写,备库通过 WAL 流式复制保持同步或异步。同步复制可保证 RPO=0,但主库提交需等待备库确认,网络抖动会放大写延迟;异步复制延迟低,但故障切换可能丢失最后一段事务。实际部署中常采用“一主一同步备 + 一异步备”的组合,兼顾数据安全与写性能。

集群架构通常指基于 Patroni、repmgr 或云托管的多节点自动故障转移方案,配合 etcd/Consul 做分布式共识。它解决的是主从架构中“谁来切换、何时切换、如何防止脑裂”的问题。集群并不等于分布式数据库,PostgreSQL 集群仍是单主写入,扩展能力主要体现在读副本和连接层。若需要跨节点写扩展,则要引入分片中间件(如 Citus),复杂度显著上升。

PostgreSQL 生产架构选型对比 单机架构 PostgreSQL 实例 读写同库 · 本地磁盘 ✕ 单点故障 ✓ 部署简单 · 无延迟 适用:测试 / 非核心业务 主从流复制架构 主库 Primary 读写 同步备库 RPO=0 异步备库 只读 / 报表 ✓ 读扩展 · 故障可切换 高可用集群 Patroni 主节点 Patroni 备节点 etcd 共识 防脑裂 ✓ 自动切换 · 秒级 RTO 选型决策与容灾目标 OLTP 核心交易 主从 + 同步复制 RPO=0 · RTO≤60s OLAP 分析报表 只读副本 / 独立库 RPO 可放宽 · RTO≤30min HTAP 混合负载 主库 + 逻辑复制 读写分离 · 资源隔离 跨机房容灾 级联复制 / 异地备库 RPO≤5s · RTO≤5min RPO:恢复点目标(可容忍数据丢失量) | RTO:恢复时间目标(可容忍停机时长) 架构选择 = 业务容忍度 × 成本 × 运维复杂度 的平衡结果

三、高可用与容灾目标定义

高可用(HA)解决的是“故障发生后多快恢复”,容灾(DR)解决的是“灾难发生时数据丢多少、业务停多久”。两者用 RTO 和 RPO 量化:RTO 是恢复时间目标,即业务可接受的最长停机时间;RPO 是恢复点目标,即业务可接受的最大数据丢失量。定义这两个指标时,必须与业务方共同确认,而不是由 DBA 单方面决定。

以某电商订单库为例:核心交易要求 RPO=0、RTO≤60 秒,因此采用同步复制主从 + Patroni 自动切换;订单报表要求 RPO≤5 分钟、RTO≤30 分钟,可接受异步只读副本;历史归档库要求 RPO≤1 小时、RTO≤4 小时,采用每日逻辑备份加异地对象存储。不同等级对应不同成本,不能一刀切。

四、落地检查清单

检查项OLTP 核心库OLAP 分析库
复制模式同步 + 异步备库异步只读副本
故障切换Patroni 自动切换手动或脚本切换
备份策略全量 + WAL 归档,PITR逻辑导出 + 快照
连接管理PgBouncer 事务级池直连或会话级池
监控重点复制延迟、锁等待、TPS临时文件、扫描行数、查询耗时
RPO=0 并不等于“永不丢数据”,它只保证已提交事务在同步备库落盘。若主库和同步备库同时故障,仍可能丢失数据。因此关键系统还需异地异步备库或定期逻辑备份作为最后防线。
不要在主库上直接跑大报表查询。即使有只读副本,也要限制其 work_mem 和 statement_timeout,避免分析查询耗尽 I/O 后反向影响复制延迟。

架构设计完成后,必须通过演练验证:模拟主库宕机,观察 Patroni 是否在 60 秒内完成切换;模拟误删表,验证 PITR 能否恢复到指定时间点;模拟网络分区,确认 etcd 不会产生双主。只有经过验证的 RTO/RPO 才是真实指标,写在文档里的数字没有意义。