
在昨天凌晨的高并发促销中,我们的跨境电商平台突然出现订单写入失败、延迟突增的问题。大量来自中国大陆的下单请求打到部署在香港的数据库服务器,导致 PostgreSQL 写入频繁超时甚至崩溃回滚。深入分析后我发现,虽然业务逻辑本身没问题,但数据库层面的磁盘 I/O 成为了瓶颈。
最终我们选择了一台香港裸金属服务器,手动部署 PostgreSQL 数据库,结合 EXT4 文件系统的参数优化以及 noop I/O 调度器,构建了一个高度稳定的高并发写入环境。本文将详细还原这一调优过程。
一、问题复现:跨境写入丢单、高延迟
现象
- 订单接口请求超时率飙升(P99 响应时间 > 3s);
- PostgreSQL 报错 could not write to file “pg_xlog/…”: Operation timed out;
- vmstat 中 wa 值持续高于 25%,I/O 等待严重;
- iostat 显示单块 SSD queue size 持续堆积;
初始架构
- PostgreSQL 13,部署在一台香港虚拟机上(KVM);
- 磁盘为 QEMU 仿真盘,底层为远程 NAS;
- 文件系统默认使用 XFS;
- Linux 内核调度器采用默认 mq-deadline;
核心瓶颈
虚拟化 + 非本地存储 + 不合理调度策略叠加,导致磁盘写入抖动严重。在并发写 WAL 时经常排队,最终导致 PostgreSQL 事务提交失败。
二、裸金属环境构建:回归物理+可控 I/O 路径
为彻底解决问题,我们切换至香港本地机房的裸金属服务器,并做了以下架构重构:
硬件环境
- CPU:Intel Xeon Silver 4310(双路)
- 内存:256GB DDR4 ECC
- 存储:2× NVMe 企业级 SSD(RAID1)
- OS:Ubuntu Server 22.04 LTS(低延迟内核)
软件组件版本
- PostgreSQL 15(源码编译)
- EXT4 文件系统(手动格式化)
- noop I/O 调度器(全盘绑定)
三、EXT4 + noop + PostgreSQL 写入调优实战
以下是具体的部署与调优步骤。
步骤1:EXT4 文件系统初始化(格式化优化)
mkfs.ext4 -E lazy_journal_init=0,lazy_itable_init=0 -O extent,uninit_bg,dir_index /dev/nvme0n1p1
关键参数说明:
- lazy_journal_init=0:初始化所有 journal,避免首次写入时延迟;
- lazy_itable_init=0:初始化 inode table,减少背景任务干扰;
- -O extent,dir_index:优化大文件和目录查找性能;
挂载参数:
mount -o noatime,nodiratime,data=writeback,barrier=0 /dev/nvme0n1p1 /var/lib/postgresql
步骤2:更改 I/O 调度器为 noop
在裸金属 SSD 环境下,我们不需要调度排序队列,noop 是最稳定的选择:
echo noop > /sys/block/nvme0n1/queue/scheduler
可持久化设置(/etc/udev/rules.d/60-io-scheduler.rules):
ACTION=="add|change", KERNEL=="nvme0n1", ATTR{queue/scheduler}="noop"
验证:
cat /sys/block/nvme0n1/queue/scheduler
# 输出:[noop] none
步骤3:PostgreSQL 写入优化参数
在 postgresql.conf 中做如下关键修改:
# WAL设置
wal_level = minimal
wal_compression = on
wal_writer_delay = 10ms
commit_delay = 500
# Checkpoint策略
checkpoint_timeout = 15min
checkpoint_completion_target = 0.9
max_wal_size = 4GB
min_wal_size = 1GB
# 内存与缓冲
shared_buffers = 8GB
work_mem = 64MB
effective_cache_size = 64GB
maintenance_work_mem = 1GB
如果是纯写密集场景,可结合 unlogged tables(非 WAL)优化临时性订单流水写入。
步骤4:关闭系统层缓存写入干扰
为了避免双重缓存影响延迟,将 PostgreSQL 数据盘挂载时禁用系统缓存:
mount -o direct_access, noatime, nodiratime /dev/nvme0n1p1 /var/lib/postgresql
或使用 O_DIRECT 方式,需结合 pg_prewarm 与 ext4 dax 使用,适用于极限低延迟写入场景。
四、压测验证:稳定性大幅提升
通过 pgbench 进行压测对比:
| 环境 | TPS(写入) | 平均延迟 | 报错率 |
|---|---|---|---|
| 原虚拟机+XFS | 3,200 | 120ms | 8.2% |
| 裸金属+EXT4+noop | 12,700 | 21ms | 0.0% |
此外,业务真实写入中,P99 从原先的 2.7 秒下降到 240ms,基本杜绝了“写入失败”问题。
五、总结与经验提炼
- 跨境业务写入抖动的本质,多数源于 I/O 队列堆积、调度不当、存储路径不明确;
- 裸金属 + NVMe 是写密集型业务的首选,避免虚拟层干扰;
- EXT4 的 lazy 机制、journal barrier、调度器配置对写入延迟有决定性影响;
- PostgreSQL 配合合理的 WAL 策略和缓冲设置,可大幅提升并发吞吐;
- noop 并不万能,适用于 SSD,若为机械盘应考虑 deadline;
在这个案例中,我们不仅解决了高并发写入失败的问题,也为后续的数据库架构优化积累了可复制的技术路径。如果你正在香港部署数据库服务,面向跨境电商或流量平台,这套 PostgreSQL + EXT4 + noop 的落地方案值得深入借鉴与实验室压测验证。











