把PostgreSQL部署在云服务器上跑业务,性能表现往往和本地物理机差别很大。同样的数据库版本、同样的表结构,在腾讯云CVM上可能就跑不出预期的吞吐量。这背后的原因涉及云主机的虚拟化开销、云硬盘的IO特性、网络延迟以及PostgreSQL自身的配置习惯。本文基于腾讯云CVM的实际测试环境,对PostgreSQL做一次从底层硬件到上层参数的完整性能评测,并给出针对性的调优建议。

测试环境与硬件选型对性能的影响
本次测试选用腾讯云CVM的两种典型机型做对比:标准型S5(4核8GB,SSD云硬盘)和计算型C5(8核16GB,增强型SSD云硬盘)。操作系统统一为OpenCloudOS 8,PostgreSQL版本为16.2,编译参数保持默认,数据目录放在独立的云硬盘上,避免与系统盘争抢IO资源。
云主机的CPU虽然标称核数与物理机一致,但存在虚拟化调度带来的抖动。测试中用pgbench做纯计算型的简单查询压测,标准型S5的单核TPS稳定在计算型C5的85%左右,这说明如果业务是CPU密集型(大量复杂聚合、排序),选计算型或内存优化型实例更划算。而如果业务以简单读写为主,瓶颈往往先出现在磁盘IO上,此时把钱花在更好的云硬盘上收益更大。
云硬盘的选择尤为关键。SSD云硬盘提供约260MB/s的顺序读带宽和2万左右的随机IOPS,而增强型SSD可以到几十万IOPS。PostgreSQL的写入路径依赖WAL日志的fsync,随机写能力直接决定了事务提交延迟。以下是一个简单的对比数据:
| 存储类型 | 随机写IOPS | pgbench TPS(32并发) | P99延迟 |
|---|---|---|---|
| SSD云硬盘 | 约18000 | 4200 | 18ms |
| 增强型SSD | 100000+ | 11500 | 6ms |
可以看到存储升级带来的TPS提升接近三倍,比升级CPU划算得多。对于OLTP场景,强烈建议直接使用增强型SSD或极速型SSD,并把WAL目录与数据目录分盘存放。
PostgreSQL核心参数调优实测
PostgreSQL默认配置非常保守,是为低配置机器准备的,直接在CVM上跑默认值会浪费大量硬件资源。第一个要调整的是shared_buffers,它类似Oracle的SGA,一般设置为内存的25%左右。8GB内存的机器设为2GB,16GB内存的机器设为4GB是比较稳妥的起点。
第二个关键参数是effective_cache_size。它不实际占用内存,只是告诉优化器操作系统层面有多少缓存可用,直接影响执行计划的选择。设置过小会导致优化器认为数据都在磁盘上,从而倾向于走索引扫描而放弃更优的顺序扫描。建议设为总内存的50%到75%。此外work_mem控制排序和哈希操作的内存上限,默认4MB在复杂查询下完全不够,可以按并发数估算:总内存 * 0.25 / 最大并发数。
# postgresql.conf 关键参数示例(16GB内存机器) shared_buffers = 4GB effective_cache_size = 12GB work_mem = 32MB maintenance_work_mem = 1GB wal_compression = on max_wal_size = 8GB checkpoint_completion_target = 0.9 random_page_cost = 1.1 synchronous_commit = on
其中random_page_cost从默认的4.0降到1.1是SSD环境的标配操作,因为SSD上随机读和顺序读的成本差距已经很小,不调整会导致优化器严重低估索引扫描的价值。checkpoint_completion_target设为0.9可以让检查点摊平写入,避免IO尖刺。实测调整这批参数后,混合读写场景的TPS从5100提升到9800,效果显著。
操作系统层面的优化细节
很多性能问题不在数据库本身,而在操作系统配置。首先是I/O调度器,云硬盘环境下建议使用none或mq-deadline,因为云硬盘后端已经做了调度,虚拟机内再做一次排队反而增加延迟。可以通过cat /sys/block/vdb/queue/scheduler查看并修改。
其次是透明大页(THP)。PostgreSQL官方建议关闭透明大页,因为它会在内存整理时引入难以预测的延迟抖动,对延迟敏感的业务影响明显。关闭方法是在内核启动参数中加入transparent_hugepage=never,或者运行时执行:
# 关闭透明大页 echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag # 持久化可写入 rc.local 或 systemd 服务
再者是NUMA问题。多核CVM实例通常呈现NUMA拓扑,PostgreSQL进程跨NUMA节点访问内存会导致性能下降,建议在BIOS或系统层面开启numa interleaving,或使用numactl --interleave=all启动数据库进程。最后别忘了文件系统的选择,XFS在并发写入场景下比ext4表现更稳定,挂载时加上noatime选项可以减少无谓的元数据写入。
压测方法与连接池的使用
压测工具首选PostgreSQL自带的pgbench。标准测试使用内置脚本模拟转账事务,也可以自定义脚本模拟真实业务。压测前需要初始化数据并预热缓存,否则第一次测试的数字会严重偏低。建议至少跑10分钟再取数据,观察TPS曲线是否平稳。
# 初始化 1 亿行测试数据 pgbench -i -s 1000 -h 127.0.0.1 -U postgres testdb # 64 并发压测 10 分钟 pgbench -c 64 -j 16 -T 600 -h 127.0.0.1 -U postgres testdb
压测中一个常见现象是:并发数从64涨到256,TPS不升反降,延迟暴涨。这通常不是硬件不够,而是PostgreSQL每个连接一个进程的架构导致的。几百个连接意味着几百个进程在CPU上争抢,上下文切换开销吞掉了吞吐量。解决办法是在数据库前面加连接池,推荐使用PgBouncer,事务级池化模式下几百个客户端连接只需要几十个数据库连接。
实测在同一台机器上,直连256并发TPS约7600,而经过PgBouncer用32个数据库连接承接256个客户端,TPS提升到12400,延迟下降超过一半。对于Web应用这种连接数多但每个连接活跃度低的场景,连接池几乎是必备组件。
监控与持续优化建议
性能调优不是一次性工作,需要持续监控。PostgreSQL的pg_stat_statements扩展可以统计每类SQL的执行次数和耗时,是定位慢SQL的第一入口。系统层面建议部署Prometheus加postgres_exporter,监控连接数、缓存命中率、checkpoint频率和复制延迟等核心指标。缓存命中率低于95%通常意味着shared_buffers不足或业务访问模式过于分散;checkpoint过于频繁则说明max_wal_size偏小。
最后总结几条实践建议:一是OLTP场景优先投入存储而不是CPU;二是参数调优先做shared_buffers、effective_cache_size和random_page_cost这三项;三是高并发业务必上连接池;四是定期用pg_stat_statements审查TOP SQL。把这些做扎实,腾讯云CVM上的PostgreSQL完全可以承载企业级业务负载。
腾讯云CVMPostgreSQL性能数据库调优修改时间:2026-09-06 12:48:40