跳至内容

17.4 比较分布式候选

候选比较的第一步,是保留“不分布”作为对照组。

如果表格只有三种分布式产品,团队会被迫在它们之间选一个;如果加入:

optimized primary
offline replica
independent analytical PostgreSQL
materialized summary

很多问题会暴露为负载隔离或数据粒度问题,而不是横向分片问题。

本节不替读者宣布一个普遍赢家,而是建立同口径的比较方法。

17.4.1 PostgreSQL 扩展、兼容数据库与专用分析系统

候选地图

可以按“离 PostgreSQL 原生语义有多远”分层:

Layer 0: same PostgreSQL instance
  indexes / partitions / parallel query / summaries

Layer 1: same physical PostgreSQL data
  read replica / offline replica

Layer 2: another PostgreSQL data copy
  logical replication / CDC / ETL to analytical PostgreSQL

Layer 3: PostgreSQL extension or federation
  postgres_fdw / Citus / workload-specific extensions

Layer 4: PostgreSQL-wire or SQL-compatible distributed database
  separate storage, transaction and operations implementation

Layer 5: specialized analytical system
  columnar/vectorized engine, separate ingestion and lifecycle

层数越高不表示越先进,只表示需要重新验证的语义越多。

对照组:优化后的 PostgreSQL

它应包含:

  • 正确 schema 与统计信息;
  • 代表性索引和 partition pruning;
  • 并行计划与并发预算;
  • 合理物化/汇总;
  • workload guardrails;
  • 当前硬件与一个可行纵向规格;
  • offline replica 或独立分析副本候选。

若分布式候选只比未经调优的原表扫描快,比较没有意义。

postgres_fdw:联邦访问与机制实验

postgres_fdw 把远端 PostgreSQL 表映射为 foreign table:

CREATE EXTENSION
  -> CREATE SERVER
  -> CREATE USER MAPPING
  -> CREATE FOREIGN TABLE / IMPORT FOREIGN SCHEMA
  -> SELECT / DML

它能做:

  • 远端过滤和列裁剪;
  • 某些 JOIN/聚合下推;
  • 外表分区;
  • 联邦读取;
  • 迁移期间的过渡;
  • 把远端数据物化到本地;
  • 显示远端 SQL 和数据流。

它不应被默认理解为一个完整的透明分布式数据库。路由、rebalance、全局 约束、协调端 HA、全局备份点和很多运维职责仍需自行设计。PostgreSQL 18 的 postgres_fdw 远端事务也不支持 prepare 为两阶段提交。

本章用它是因为机制透明:

Foreign Scan
Remote SQL
actual rows
user mapping
server failure

都能直接观察。它是很好的教学镜子,不是本章对生产选型的默认推荐。

Citus:PostgreSQL 扩展式分片候选

Citus 把表区分为 distributed、reference、local 等类型,以分布列决定行的 放置;相关表按相同分布键 colocate 后,单租户查询和某些 JOIN 可以在一组 共置分片上执行。跨租户聚合则可由 worker 产生 partial result,再由协调端 合并。

这使它适合评估:

multi-tenant workload with tenant-local transactions
real-time aggregate workload with decomposable computation
PostgreSQL ecosystem continuity

但分布键选择成为 schema 与查询合同。Citus 官方 Choosing Distribution Column 强调 tenant/entity key、co-location 与跨节点数据移动之间的关系;小型共享 维表可评估 reference table。

需要验证:

  • row-based 还是 schema-based sharding;
  • distribution column 是否出现在 PK/FK/查询;
  • colocated tables 与 reference tables;
  • 单租户与全局查询比例;
  • rebalance 与大租户隔离;
  • coordinator/worker HA;
  • distributed DDL;
  • backup/restore;
  • 版本升级和扩展组合;
  • Pigsty L1 的实际拓扑。

本章 loopback FDW 的“同分片 JOIN 未下推”不能直接外推为 Citus 行为;它只 提醒读者对目标产品的目标 SQL 看实际计划。

PostgreSQL-compatible distributed database

这类系统可能支持 PostgreSQL wire protocol、部分 SQL、驱动和工具,让迁移 起步更容易。必须拆开“兼容”:

wire protocol
parser syntax
catalog shape
data types
functions/operators
transaction semantics
isolation/locking
extensions
backup/restore
monitoring
operational commands

一个应用只用简单 SELECT/INSERT,兼容度可能足够;一个应用依赖 PostGIS、 自定义 operator class、logical decoding、advisory lock、trigger、COPY、 RLS 和精细 catalog 查询,迁移面完全不同。

不要用厂商兼容百分比替代自己的 feature inventory。

专用分析系统

专用 OLAP 系统通常优化:

columnar compression
large scans
vectorized execution
distributed aggregation
high analytical concurrency
object storage / tiering

它可能显著优于 PostgreSQL 处理某类宽表聚合,但会引入第二套:

ingestion / CDC
schema mapping
data freshness
deduplication
late-event handling
access control
backup/recovery
monitoring/on-call
cost model
query semantics

如果 OLTP truth 仍在 PostgreSQL,必须定义两个系统不一致时谁是事实来源。

候选能力矩阵

以下不是产品评分,而是评审问题:

维度单机/副本FDWCitus 类扩展兼容分布式库专用 OLAP
原生 PG 语义最高本地/远端 PG高但分片有边界必须实测通常较低
单租户局部性原生手工路由分布键核心依实现依模型
全局聚合单节点可下推/合并分布式 partial/final依实现核心场景
跨分片事务不适用有明显限制需按版本/形状验证需验证通常非 OLTP 重点
扩展生态原生两端一致性需验证组合通常有限不适用/自有
运维体系已有多 PG + 编排coordinator/workers新体系第二套体系
新鲜度即时/复制 lag远端即时视连接即时视事务依实现CDC/批次 lag
退出成本中高

矩阵中的每个“需验证”都要变成 PoC 用例。

所有权边界

候选不仅有技术 owner:

责任必须有人承担
schema 与分布键数据模型 owner
query migration应用 owner
ingestion/CDC数据平台 owner
cluster lifecycleDBA/SRE
correctness reconciliation业务 owner + 数据 owner
incident decisionon-call
cost预算 owner
exit项目 sponsor

缺少 owner 的候选不能因为跑分快进入生产。

17.4.2 SQL 兼容不等于事务、扩展和运维兼容

建立兼容性分层

推荐至少分八层:

L1 protocol
L2 syntax
L3 type and expression semantics
L4 transaction and concurrency
L5 schema objects and extensions
L6 planner/performance behavior
L7 operations and observability
L8 failure/recovery and lifecycle

只有 L1/L2 通过,应用仍可能在 L3–L8 失败。

协议兼容

验证:

  • TLS、SCRAM、GSS/SSO;
  • connection parameters;
  • prepared statements;
  • binary/text format;
  • COPY;
  • cancellation;
  • notices/errors 与 SQLSTATE;
  • connection pool transaction/session mode;
  • driver features;
  • failover reconnect。

能用 psql 登录只是起点。

SQL 与类型语义

测试应用真实使用的:

numeric precision and rounding
timestamp/time zone
collation and locale
NULL ordering
JSON/JSONB
arrays/ranges/multiranges
generated columns
identity/sequence
UPSERT/MERGE/RETURNING
CTE/window/lateral
recursive query

同样语法若类型、collation 或时区不同,会返回不同结果。

postgres_fdw 官方文档也建议 foreign table 的类型和 collation 与远端精确 匹配,否则本地与远端对条件的解释可能不同。它还不会自动导入除 NOT NULL 之外的约束,因为错误约束可能导致规划器做出不安全推断。

事务与并发语义

需要独立验证:

READ COMMITTED snapshot
REPEATABLE READ
SERIALIZABLE
row/table/advisory locks
deadlock detection
savepoints
DDL transactionality
cross-shard transaction
retry error classes
sequence behavior

例如“支持 serializable”不够,要验证:

  • 冲突时 SQLSTATE;
  • 是否需要 client retry;
  • 多分片是否同样保证;
  • range/predicate conflict 如何实现;
  • failover 后 in-flight transaction 的结果;
  • unknown commit 如何对账。

schema 与扩展兼容

列清单:

SELECT
  extname,
  extversion
FROM pg_catalog.pg_extension
ORDER BY extname;

对每个扩展检查:

  • 是否可安装;
  • exact version;
  • trusted/non-trusted;
  • shared preload;
  • 类型、函数、operator、index AM;
  • logical/physical replication;
  • backup/restore;
  • rolling upgrade;
  • 每个节点一致性。

不能把“兼容 PostgreSQL”理解为兼容任意 PostgreSQL 扩展。

catalog 兼容

许多工具读取:

pg_catalog
information_schema
pg_stat_*
pg_locks
pg_settings
pg_extension
pg_class/pg_attribute/pg_index

候选可能接受这些查询但字段为空、语义不同或只反映 coordinator。验证:

  • migration tool;
  • ORM introspection;
  • monitoring exporter;
  • backup tool;
  • schema diff;
  • incident runbook;
  • 自定义运维脚本。

planner 兼容

相同 SQL 的计划可以完全不同。需要观察:

where execution happens
which shards are pruned
which filters/joins/aggregates push down
how many rows cross network
how coordinator merges
what spills
what happens under skew

本章同一个 FDW 月报有两种 SQL:

parent aggregate:
  fetch 240,000 facts
  aggregate locally

explicit per-shard daily aggregate:
  fetch 480 + 480 aggregate rows
  aggregate monthly locally

语义相同,执行位置不同。兼容性测试不能只检查最终 rows。

运维兼容

对比日常动作:

动作问题
provision声明、包、密钥、节点身份如何?
scale加节点是否自动,旧数据如何移动?
backup一致点、加密、保留、校验如何?
restore空环境恢复、route metadata 如何?
failovercoordinator/worker 谁仲裁?
upgraderolling、停机、扩展顺序?
schema changefan-out、失败补偿?
observability全局与每 shard 指标?
securityHBA、证书、user mapping、secret?
decommission数据擦除与证明?

工具名字相同也不表示语义相同。例如在 coordinator 执行 VACUUM 是否覆盖 所有 shard,要由目标产品和版本证明。

错误兼容

应用通常围绕 SQLSTATE 决定:

retry
abort
return conflict
mark dependency unavailable

候选必须保留或重新映射这些错误语义。测试:

  • unique violation;
  • serialization failure;
  • deadlock;
  • lock timeout;
  • statement timeout;
  • connection failure;
  • read-only transaction;
  • insufficient privilege;
  • disk/full or quota;
  • shard unavailable。

只测试成功路径会让第一场故障变成兼容性测试。

精度与顺序

分析结果的隐性差异:

floating aggregate order
approximate distinct
collation sort
NULL order
time zone database version
decimal scale
non-deterministic top-N ties

冻结输出应:

  • 使用 exact numeric 或定义误差;
  • 明确 ORDER BY 与 tie-breaker;
  • 固定时区/locale;
  • 记录 approximate 算法/version/seed;
  • 对 checksum 使用稳定序列化。

17.4.3 用同一工作负载和失败条件比较

先冻结语义

比较协议应先固定:

schema
data generator / snapshot
business queries
expected results
freshness point
concurrency schedule
failure schedule
versions/config
measurement method

本章:

fixture = ch17-analytics-v1
frozen_at = 2026-07-29T00:00:00Z
monthly rows = 32
monthly checksum = 644d45544ebbc2a80c42270c38ac6885

任何候选先生成同一月报,再谈性能。

workload suite

至少包含:

  1. 高选择性单租户读

    WHERE tenant_id = 3
      AND occurred_on >= DATE '2026-04-01'

    验证 pruning、index、route、read amplification。

  2. 全局可分解聚合

    count/sum 按租户和月份,验证 partial/final 与传输。

  3. 同分片 JOIN

    account + sales,验证真实 join pushdown。

  4. 非分布键 JOIN

    故意触发 shuffle 或拒绝,量化代价。

  5. 小写入与幂等重试

    验证事务、unique、retry。

  6. 批量装载

    验证 ingest、WAL/replication、rebalance。

  7. schema change

    增列、建索引、backfill,验证 mixed-version。

  8. backup/restore

    从空环境恢复并跑 checksum。

数据规模阶梯

不要只跑一个尺寸:

S: fits in memory
M: working set near memory
L: exceeds memory
XL: near storage/maintenance target

观察曲线和拐点,而不是挑一张最好看的柱状图。

冷暖缓存

至少区分:

warm repeated query
cold/evicted data
after restart
after rebalance
after restore
after schema/index build

专用分析系统和 PostgreSQL 对缓存、编译、数据格式转换的预热不同。只比较 第十次执行或只比较第一次执行都可能偏颇。

并发与到达模型

开放环和封闭环会得出不同结论:

closed-loop:
  client waits for response, then sends next
  overloaded system self-throttles

open-loop:
  requests arrive by schedule independent of completion
  queueing and overload become visible

生产若有固定到达率,基准不能只用少量客户端闭环。还要记录 client queue 与 server queue,避免 coordinated omission。

资源和成本同报

每个结果同时报告:

latency distribution
throughput
error rate
CPU seconds
memory peak
storage read/write
temp/spill
network bytes
WAL/replication
storage footprint
node count
operator time
license/cloud cost

“P95 快 2 倍但使用 8 倍节点”与“同成本快 2 倍”不是同一结论。

失败矩阵

对每个候选执行:

故障验证
query cancel远端工作是否停止、资源是否释放
worker/shard down单分片与全局查询如何返回
coordinator down新连接、已有事务、恢复
network partitiontimeout、unknown commit、重试
disk pressurebackpressure 与告警
replica lagfreshness 标识与路由
rebalance interruptedresume、重复/遗漏
schema node drift拒绝、修复与可见性
backup during load恢复一致性

失败结果必须是验收的一部分,不是“以后做 chaos”。

本章的最小失败条件

冻结 PoC 至少证明:

application write -> SQLSTATE 42501
shard B unreachable -> global query SQLSTATE 08001
shard B unreachable -> tenant 2 scoped read = 30000
server catalog after rollback = before failure

它没有证明:

  • 真实网络分区;
  • process kill;
  • WAL/replica behavior;
  • coordinator HA;
  • shard failover;
  • in-flight distributed write;
  • rebalance resume。

这些是生产 PoC 的追加用例。

benchmark result template

每条结论写成:

claim:
  two-stage aggregation reduces coordinator input

environment:
  PostgreSQL 18.4, postgres_fdw 1.2
  same-host/same-instance loopback

input:
  ch17-analytics-v1, 240,000 facts

evidence:
  naive Append actual rows=240000
  two-stage Append actual rows=960
  both byte-identical to frozen monthly CSV

scope:
  row-transfer shape only

not proven:
  network bytes, latency, throughput, HA, scaling

这个模板迫使作者把结论和外推边界放在一起。

评分前设置 veto

某些条件不应靠加权平均掩盖:

incorrect result
cannot meet RPO/RTO
unsupported mandatory extension
unacceptable data residency
no recoverable backup
license conflict
no exit path
unknown-commit without business reconciliation

任何 veto 失败,候选退出;不能用“查询快 30%”抵消。

决策表

通过 veto 后再评分:

维度权重证据分数不确定性
correctnessvetogolden/checksumpasslow
workload SLO25representative replay
failure/RPO/RTO20drills
operability15day-2 tasks
compatibility15feature inventory
cost10same horizon/TCO
migration10rehearsal
exit5reverse rehearsal

“不确定性”单列,避免没有验证的候选因为乐观估分胜出。

本节结论

比较方法的输出不是产品排行榜,而是:

baseline
candidate contract
evidence bundle
known limitations
veto results
cost/ownership
migration and exit
decision trigger

下一节构造一个最小 FDW PoC,目的不是给候选打性能分,而是验证“租户路由、 远端聚合、权限和部分失败能否被证据化”这一个关键假设集合。


上一节:何时需要分布式 · 返回本章目录 · 下一节:部署最小分布式 PoC · 查看全书目录 · 查看索引中心

最后更新于