分布式 PostgreSQL 架构概述
分布式系统是计算机科学中充满魅力的分支,其核心挑战在于必须在物理世界的限制下做出各种权衡。本文回顾了多种分布式 PostgreSQL 架构,重点并非算法细节,而是每一层级上所需进行的艰难权衡,以及这些权衡对性能、可用性和操作复杂性的影响。
单机 PostgreSQL
单机 PostgreSQL 具有极低的延迟和极高的性能,是成本效益高的选择。但其主要缺点在于操作风险:服务器故障会导致停机,磁盘故障可能导致数据丢失,系统过载时难以扩展,且受限于单磁盘容量。
分布式数据库的目标与机制
分布式架构旨在满足高可用性、持久性、性能、合规性和扩展性要求,同时尽可能保持单机 RDBMS 的功能与事务语义。主要机制包括:
- 复制:在不同机器上放置数据副本。
- 分片:在不同机器上放置数据分区。
- 去中心化:在不同机器上处理不同的数据库活动。
每种机制都不可避免地需要在性能、事务语义、功能或操作复杂性上做出让步。
OLTP 系统中延迟的重要性
在分布式数据库中,延迟是关键的权衡因素。PostgreSQL 使用同步交互协议,任何网络延迟都会显著增加事务总时长。事务耗时增长会直接降低单个会话的事务吞吐量(TPS),而为了提升总吞吐量就需要大量并发会话,这消耗更多资源并受限于服务器配置,最终限制了整体事务吞吐能力。
主要的分布式 PostgreSQL 架构
1. 网络附加块存储
常见于云环境,数据库文件存储在外部块设备上。服务内部会进行数据复制以保证持久性。
- 优点:持久性高、可用性高(可快速替换虚拟机)、备份和创建副本快(基于快照)、磁盘易扩展。
- 缺点:磁盘延迟显著增加(从微秒级到毫秒级)、IOPS 大幅降低(约降低两个数量级)、崩溃恢复耗时、成本可能较高。
- 指南:其带来的高持久性和可用性通常能抵消性能损失,但需知其并非最快方案。
2. 读副本
利用 PostgreSQL 内置的物理复制,创建只读副本,通常用于高可用故障转移或扩展读吞吐量。
- 优点:读取吞吐量可线性扩展;若副本比主库更靠近用户,可提供低延迟的“过时”读取;减轻主库负载。
- 缺点:存在“最终读己所写”一致性问题;无法保证单调读一致性;当工作集超出内存时,各副本可能执行大量冗余 I/O。
- 指南:适用于需要超过 10万次/秒读取或读取导致 CPU 瓶颈的场景,但需避免用于存在依赖关系的事务和大型工作集。
3. DBMS 优化云存储(如 Aurora, AlloyDB)
一种针对数据库优化的网络存储层,由存储层根据 WAL 日志来执行后台的数据页写入。
- 优点:理论上通过减少主节点的页面写入来提升性能;副本可共享存储层。
- 缺点:默认写入延迟较高;成本高昂;PostgreSQL 原生并非为此设计。
- 指南:可能对复杂工作负载有益,但需实际测量其在负载下的性价比是否优于使用更大规格的单机。
4. 双活架构
任何节点均可在本地直接接受写入,无需与其他节点协调。
- 优点:读写可用性极高;读写延迟低;读吞吐量可线性扩展。
- 缺点:存在最终一致性问题;无法保证单调读;不提供线性历史记录(更新可能在提交后发生冲突,例如并发更新同一计数器导致结果错误)。
- 指南:仅适用于非常简单的工作负载(如队列),且确需其极高可用性优势时。
5. 透明分片(如 Citus)
通过分片键将表分布到多个主节点,或在节点间复制表。查询和事务对应用透明。
- 优点:可水平扩展读写吞吐量(CPU 和 IOPS);通过扩展节点增加内存,支持大型工作集;可并行化分析查询和批量操作。
- 缺点:读写延迟较高;数据模型设计对性能影响巨大;快照隔离的限制(仅限分片级别);对 SQL 功能(如某些关联查询、唯一/外键约束)有限制。
- 指南:最适用于多租户应用。其他场景下,适用于工作集大于 100GB 或需要处理计算密集型查询的情况。通常需要调整应用以适应更高延迟和更严格的数据模型。
6. 具备 SQL 功能的分布式键值存储(如 Yugabyte)
基于分布式键值存储(使用 Paxos/Raft 实现可用性和扩展性),在其上构建 SQL 引擎。
- 优点:读写可用性好(基于分片级别的故障转移);单表、单键操作扩展性好;无需额外数据建模或牺牲快照隔离。
- 缺点:许多内部操作延迟高;当前实现不支持本地连接操作;并非真正的 PostgreSQL,生态成熟度和优化程度较低。
- 指南:对于简单应用,其可用性和扩展性优势可能有用。但通常,直接使用原生 PostgreSQL 是更优选择。
总结
分布式 PostgreSQL 可在不同层面实现,每种架构都引入了显著的权衡。选择架构时需反复思考:
- 我的真正需求是什么?
- 哪种架构能实现该目标?
- 其缺点是什么?
- 我的应用能否容忍这些缺点?(我是否愿意修改应用?)
部署分布式数据库系统始终是一个需要理解权衡的复杂问题,而非已解决的难题。