跳至内容
19.2 计算、内存、存储与网络

19.2 计算、内存、存储与网络

资源规划不是列一张“推荐配置”。它要把 workload 的每种稀缺资源与一个可 观察的饱和点连接起来。

19.2.1 CPU 核数、频率、NUMA 与虚拟化

核数与单核性能解决不同问题

更多核心有利于:

更多并发 backend
parallel query
autovacuum workers
backup compression
replication/application workers
多个实例/服务

更强单核性能有利于:

单条不可并行执行路径
短 OLTP tail latency
锁临界区
表达式/PL 执行
单 WAL 路径中的部分工作

不能用总 vCPU 数替代 CPU 型号、频率、代际与持续性能。

SMT 线程不等于物理核心

操作系统报告 32 CPU,可能是:

16 physical cores × 2 SMT
32 physical cores
oversubscribed 32 vCPU
burstable quota

基线记录:

lscpu --json
nproc
cat /sys/fs/cgroup/cpu.max

以及 hypervisor/cloud 的:

vCPU entitlement
steal time
credit/burst policy
dedicated/shared
pinning

PostgreSQL 并行 worker 数应基于实测吞吐和并发,不按 nproc 自动拉满。

CPU 饱和要看排队

观察:

utilization
runnable queue
steal/throttle
per-process CPU
context switches
frequency
query latency/throughput

CPU 100% 但吞吐继续线性增长,和 CPU 70% 但 cgroup throttling/steal 很高, 不是同一问题。

NUMA 使“总内存/总核心”失去均匀假设

多 socket/NUMA 系统中:

CPU attached to local memory node
remote memory access latency higher
device/interrupt locality differs
kernel allocation can become uneven

记录:

lscpu
numactl --hardware
cat /sys/devices/system/node/node*/meminfo

还要确认 BIOS/VM 的 NUMA 暴露、进程/IRQ/pinning 策略。

不要无条件“禁用 NUMA”。小单节点、超大多 socket、VM、容器的最佳策略可能 不同。变更要有 workload 实验。

本章 Vagrant VM 每台只报告一个 NUMA node,因此只能验证采集与同构,不能 形成大型 NUMA 结论。

虚拟化要记录资源保证

虚拟机的抽象层可能引入:

CPU oversubscription
steal
memory ballooning
host swap
virtual disk cache
noisy neighbor
live migration pause
shared physical failure
time drift

容器还要记录:

CPU quota/cpuset
memory.max
OOM policy
huge page access
ephemeral filesystem
PID/file limits
host network/storage

“8 vCPU/32 GiB”若没有 guarantee 与 failure domain,只是一个接口数字。

指令集与架构是兼容矩阵的一部分

本章正式 sandbox 是:

architecture=aarch64
OS=Ubuntu 24.04.x

所有节点必须相同。生产扩展 package、JIT、compression、加密库与备份恢复 都要覆盖目标架构。不能假设 x86_64 上测试的二进制扩展会在 ARM 恢复目标上 存在。

CPU 基线不是调优

第 19 章只记录:

logical count
model
NUMA node count
virtualization
kernel/cgroup identity

第 26 章测饱和,第 27 章才改变并行和参数。看到核心数不等于知道 max_parallel_workers_per_gather 应设多少。

19.2.2 内存预算、页缓存与 OOM 边界

PostgreSQL 使用多类内存

shared_buffers
WAL buffers
backend private memory
work_mem per operation
maintenance_work_mem
autovacuum_work_mem
temp_buffers per session
extension/background worker memory
connection/process overhead
OS page cache
kernel/network/filesystem
monitoring/backup/proxy

只算 shared_buffers + max_connections × work_mem 仍然过度简化。

页缓存与 shared buffers 共同工作

PostgreSQL 使用自己的 shared buffer cache,也依赖操作系统 cache。官方 Resource Consumption 给出 shared_buffers 的起始建议,同时说明 PostgreSQL 还依赖 OS cache。

这意味着:

  • 不应把全部 RAM 分给 shared_buffers
  • 文件系统/backup/extension 也需要 cache;
  • database cache hit 不等于没有底层 I/O;
  • VM host cache 还可能再加一层;
  • cold/warm benchmark 要定义清楚。

乘法内存必须按峰值并发

近似账本:

[ M_{total}

M_{shared}

  • M_{OS}
  • N_{backend}M_{backend}
  • \sum work\ nodes
  • M_{maintenance}
  • M_{other}
  • headroom ]

work_mem 是每 sort/hash 节点的基础预算;并行 worker 与多个节点会放大。

平台应按 role/workload class 设置,而不是一个全局大值:

OLTP runtime
admin migration
offline analytics
maintenance

max_connections 是内存与调度承诺

每个 PostgreSQL connection 对应 backend process。大量 idle connection 也有:

process/page table
backend state
locks/proc arrays
TLS/socket
extension/session state

大量 active connection 会导致 CPU 排队与 cache 抖动。

规划顺序:

safe active concurrency
  -> backend budget
  -> reserve admin/monitor/replication
  -> pooler server pool
  -> application pool totals
  -> client queue/timeout

不是先把 max_connections 改成 5000。

OOM 不是一种可接受的流量控制

当 Linux OOM killer 选择 PostgreSQL 进程:

  • backend 被杀;
  • postmaster 可能触发所有 backend 重启;
  • client 事务中断;
  • recovery/checkpoint 增加恢复时间;
  • HA 可能触发切换;
  • evidence 可能被噪声覆盖。

应使用:

capacity headroom
cgroup/systemd memory boundary
connection/active query budget
work/temp limit
load shedding
monitoring

在系统被 OOM 前拒绝或排队。

overcommit 与 swap 要显式

记录:

sysctl vm.overcommit_memory
sysctl vm.overcommit_ratio
sysctl vm.swappiness
cat /proc/meminfo
systemctl show ... memory controls

策略取决于宿主/容器/工作负载,但未知是不可接受的。

本章 sandbox 要求 guest SwapTotal=0,同时承认 macOS host 仍可能压缩/交换 VM 内存;VM 内看到无 swap 不证明物理主机不会产生内存压力。

Transparent Huge Pages 与显式 huge pages 不同

PostgreSQL 18 官方 Resource Consumption 说明 Linux THP 在一些环境中会导致性能下降,目前不鼓励;这与 PostgreSQL 显式 huge_pages 不是同一机制。

采集:

cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
cat /proc/meminfo | grep Huge

Pigsty sandbox 的预期:

THP enabled current=never
THP defrag current=never
explicit hugepage count may remain 0

若要启用显式 huge pages,应按 PostgreSQL Managing Kernel Resourcesshared_memory_size_in_huge_pages 计算并验证,不靠固定百分比模板。

内存 floor 与 production sizing 分离

实验要求 2 GiB 只是部署 floor。production 需要:

working set
peak connections
query node memory
maintenance overlap
HA/failover state
OS/agent budget
growth
headroom

通过 floor 不代表容量 gate 通过。

19.2.3 IOPS、吞吐、时延、容量与冗余

四个存储指标互不等价

IOPS       每秒操作数
throughput 每秒字节
latency    单次完成时间及分布
capacity   可用字节与增长空间

小随机 WAL/fsync、索引随机读、大顺序扫描、backup stream 的瓶颈不同。

“云盘 20,000 IOPS”不说明:

  • block size;
  • read/write mix;
  • queue depth;
  • P99 latency;
  • burst duration;
  • fsync/FUA;
  • shared cap;
  • failure behavior。

PostgreSQL 的典型 I/O 路径

路径特征
WAL write/flush小、顺序、durability latency 敏感
checkpoint大量脏页写、可能 burst
heap/index readrandom/sequential 混合
temp spill大量短寿命读写
vacuum扫描 + index cleanup + WAL
backup大顺序读 + network + repository write
replicaWAL receive/write/replay + data I/O
restorerepository read + data write + WAL replay

需要同时测生产 workload 和维护/故障状态。

平均延迟会隐藏 tail

保存:

P50/P95/P99/max
queue depth
utilization
read/write latency
fsync latency
throughput
errors/timeouts

交易 commit 通常对 tail latency 更敏感;一次 2 秒 flush 可能制造级联 queue。

文件系统与设备语义要完整记录

基线:

lsblk --json -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINTS,ROTA,MODEL
findmnt --json
df -B1
mount

同时从基础设施层记录:

local/network/block/object
RAID/replication
write cache and power-loss protection
discard/TRIM
snapshot behavior
encryption
IO scheduler
cloud volume class
burst/credit
failure domain

数据库内部无法证明底层存储真正持久。

fsync=on 仍依赖硬件诚信

PostgreSQL 发出同步请求后,操作系统/设备必须诚实地把数据持久化。虚假 write cache acknowledgment 会破坏 WAL 设计前提。

验收需要:

  • 合格存储/云服务语义;
  • power-loss protection;
  • 厂商/基础设施保证;
  • 故障测试与恢复;
  • checksums/备份/取证作为纵深。

不要用 fsync=off 解决 production latency;那是在更改持久性合同。

容量要给多个并发动作留空间

磁盘不能规划到 95% 常态:

database growth
index build/reindex
VACUUM FULL/table rewrite
major upgrade copy/link strategy
base backup staging
WAL/archive backlog
logical slot retention
temp spill
log/metrics
filesystem reserve

headroom 应按最坏的已批准维护/故障动作计算。

redundancy 不等于 backup

RAID/云盘副本:

覆盖部分设备故障
不覆盖误删、逻辑错误、很多软件损坏

PostgreSQL replica:

覆盖服务成员故障
复制已提交错误

backup/PITR:

提供历史恢复
依赖仓库、WAL、密钥、过程与时间

三者互补。

检查 checksum,但不要过度解读

PostgreSQL 18 initdb 默认启用 data checksums,可用 --no-data-checksums 关闭。checksum 能检测一类 页面静默损坏;它不纠正错误,也不覆盖:

WAL/archive completeness
application logical errors
所有内存/网络/文件损坏
backup recoverability
replica independence

本章要求每个成员 data_checksums=on,并把实际检测与修复留给第 28/35 章。

Vagrant 存储只能做流程验证

本章采集 root 与 /pg mount、总量/free、类型/options,但明确例外:

EX19-VIRTUAL-STORAGE

它不能为 production IOPS、P99、endurance、power-loss 或冗余签字。

19.2.4 时钟、DNS、带宽、防火墙与故障域

时钟是分布式证据的坐标

时钟影响:

TLS/certificate
日志关联
监控窗口
lease/election
backup/PITR target
业务时间
token expiry
incident timeline

每台记录:

timedatectl show
chronyc tracking
chronyc sources -v

验收:

timezone=UTC or Etc/UTC
NTPSynchronized=yes
source/offset within policy

“时间看起来差不多”不够。

数据库通常用 UTC 保存绝对时刻;用户展示时再按业务时区转换。OS 日志也应 统一可换算。

DNS 是服务依赖

记录:

authoritative zone
resolver path
TTL
negative cache
search domain
split-horizon
failover/update authority
monitoring

不要让 PostgreSQL 成员依赖一个单点、不可观察的外部 resolver。

/etc/hosts 适合固定 sandbox,生产服务发现要有 owner 与变更流程。

IP、hostname、service name 分层

node identity     node-1 / host UUID
instance identity pg-test-2
cluster identity  pg-test
service identity  pg-test-primary / replica / offline
business identity pg36_shop

客户端连 service,不连“当前 primary 的 IP”。IP 可以变,service 语义应 稳定。

带宽要算复制与恢复

网络预算:

client request/response
streaming WAL
base backup/rebuild
archive upload
restore download
monitor/log
external CDC/export
package deployment

恢复或新副本同步可能是最大流量。

若:

[ rebuild\ time \approx \frac{data\ bytes}{effective\ bandwidth} ]

还要加 checksum、compression、I/O、WAL catch-up 与争用。链路标称带宽不是 effective。

网络延迟进入同步提交

同步副本确认需要跨 failure domain 往返。距离越远,commit latency 越高; 距离太近,则可能不覆盖目标故障。

所以同步位置不是“同城最好”或“跨区最好”,而是 RPO、延迟、可用性和故障域 共同取舍。第 20 章实测。

防火墙从允许关系生成

不要先“关防火墙排障”,再忘记打开。建立 flow matrix:

sourcedestinationport/protocolpurposeauth
appPG serviceTCPbusiness SQLTLS + role
PG memberPG memberTCPstreamingreplication role
PatronietcdTCP/TLSDCScert/credential
LBPatroni RESTTCProle healthnetwork policy
backuprepositoryTCP/TLSarchive/restorescoped secret
monitoringexportersTCPmetricsnetwork/auth
adminhostsSSHcontroladmin identity

规则要双向核对:inventory 声明、主机 firewall、cloud security group、实际 probe。

Pigsty 4.4 Node Parameters 说明其 firewall 模式与 intranet/public 策略;具体默认仍要从目标配置与主机 事实确认。

“四台机器”不等于四个故障域

故障域清单:

process
instance/VM
host/hypervisor
disk/controller/storage service
rack/power
switch/network
zone/datacenter
region
DNS/IAM/control plane
operator/configuration
backup repository/key

两个 node ID 可能共享除进程外的所有域。

本章四个 machine-id 确实不同,但它们共享:

one physical laptop
one hypervisor
one power source
one physical storage
one host network

所以 validator 同时要求:

machine identities distinct
EX19-SHARED-HYPERVISOR present
production SLO claim false

只通过前一项会制造错误结论。

DCS 与 backup 也有故障域

三节点 PostgreSQL + 单节点 etcd:

data members=3
DCS members=1

不是完整生产 HA。

备份放在同一 control VM/physical host:

backup copy exists
independent disaster copy does not

拓扑图必须画控制与恢复依赖,不只画 PostgreSQL。

本节的验收产物

主机采集器 remote_host_facts.py 只读输出:

hashed machine identity
OS/kernel/architecture/virtualization
CPU/NUMA
memory/swap/THP/overcommit
mount/free space
clock/NTP
addresses/DNS/firewall/listening ports
service and package versions

它记录事实,不自动执行任何 sysctl、mount 或 firewall 调优。


上一节:先写服务需求 · 返回本章目录 · 下一节:操作系统与主机基线 · 查看全书目录 · 查看索引中心

最后更新于