上一篇 下一篇 分享链接 返回 返回顶部

WordPress百万级访问出现内存告警,香港AMD 4584PX如何排查DDR5瓶颈?

发布人:Minchunlin 发布时间:2026-10-05 21:19 阅读量:13

WordPress 流量上升时出现“可用内存不足”告警,不一定说明 DDR5 性能不足。告警可能来自 PHP-FPM 子进程同时增多、数据库缓存增长、容器内存上限、持续交换,或内核触发 OOM;内存带宽或 NUMA 访问问题也可能拖慢请求,但通常需要结合性能指标判断,不能仅凭“内存用得多”下结论。

排查时先确认告警对应的时间、主机或容器范围,再按“系统是否持续承压 → 交换与 OOM 是否发生 → 哪类进程占用上升 → PHP 和数据库是否放大并发 → 是否存在内存带宽或 NUMA 瓶颈”的顺序定位。先采集只读信息,不要一发现 swap 就清空缓存或重启服务;修复后应在相近流量条件下复测内存、响应时间和错误率。

引言与总体排查顺序配图

一、先判断告警是不是持续性内存压力

先记录告警发生时间、访问量变化、页面响应时间、PHP 错误日志和服务器可用内存。单次采样只能说明当时状态,建议至少比较告警前后几分钟到十几分钟的数据;如果网站运行在容器中,还要确认告警是宿主机发出的,还是容器达到自己的内存限额。

在常见 Linux 发行版上,可先执行:

date
free -h
grep -E 'MemTotal|MemAvailable|Cached|Buffers|SwapTotal|SwapFree' /proc/meminfo
vmstat 1 10

free -h 中的 available,以及 /proc/meminfo 中的 MemAvailable,比单看 free 更适合判断系统还能否为新进程分配内存。Linux 会把空闲内存用于页缓存和缓冲区,这部分通常能在需要时回收;因此 free 数值偏低,不代表内存已经耗尽。

vmstat 1 10 会每秒输出一次采样。重点看:

  • si、so:分别表示每秒从交换空间读入、写出的大致活动量。持续非零并伴随响应变慢,说明系统可能在频繁换页;偶发小值不能单独证明故障。
  • r:等待 CPU 的运行队列长度。它持续偏高可能是 CPU 竞争,不一定是内存问题。
  • wa:等待 I/O 的时间比例。如果偏高,需结合磁盘延迟判断;交换读写也可能加重 I/O 等待。
  • free:当前空闲内存,不能单独作为容量结论。

可参考下面的判断表。具体阈值应结合机器内存总量、业务基线和告警规则调整,不宜用单一百分比对所有环境一刀切。

观察结果更可能的含义下一步
available 较充足,si/so 长时间为零,网站响应正常页缓存占用或告警阈值过于敏感对照告警规则和历史基线,不急于扩容
available 持续下降,si/so 持续非零,响应时间变长真实内存压力,系统正在换页检查进程占用、容器限制和并发配置
available 下降很快,随后服务进程消失或请求报错可能触发 OOM 或容器限额查内核日志、容器事件和进程重启记录
内存看起来充足但吞吐下降、CPU 等待或延迟升高可能是 CPU、I/O、锁竞争或内存访问效率问题先排除上游瓶颈,再检查 NUMA 和内存带宽

如系统安装了 sysstat,可用 sar -r 1 10 观察内存随时间的变化;若命令不存在,不必为一次排查立即安装软件,先用 free、vmstat 和系统监控中的历史曲线即可。

二、确认交换活动与 OOM 是否发生

存在 swap 不等于正在发生故障。交换空间可以作为短时缓冲,但如果页面反复在内存和磁盘之间换入换出,PHP 请求和数据库查询会受到明显影响。以下命令只读取状态:

swapon --show
cat /proc/swaps
vmstat 1 10

重点是“是否持续换页”,而不是只看 swap 使用量。某些长期未访问的内存页可能留在 swap 中,即使当前业务没有明显压力;反过来,swap 占用不高也不能排除短时间内的内存峰值。应把 si/so、MemAvailable、磁盘 I/O 和请求延迟放在一起看。

接着检查内核日志中是否记录了 OOM:

sudo journalctl -k --since "1 hour ago" | grep -Ei 'oom|out of memory|killed process'

如果系统没有使用 systemd,可在确认发行版和日志服务后检查对应的内核日志;不要因为某个发行版没有 journalctl 就直接套用其他系统的日志路径。日志中若出现类似 Killed process ... (php-fpm) 或数据库进程名称,表示内核在内存压力下终止了该进程。被终止的不一定是占用最大的进程,内核会根据当时条件选择目标,因此还要结合告警时间、进程监控和应用日志判断。

容器环境需要额外检查容器级限制。宿主机仍有可用内存时,容器也可能因为自身限额被 OOM 杀死。Docker 环境可先只读查看:

docker stats --no-stream
docker inspect --format '{{.HostConfig.Memory}}' <容器名或ID>

HostConfig.Memory 为 0 通常表示没有设置该容器级内存上限,不代表宿主机有无限内存。若使用 Kubernetes,应同时查看 Pod 的内存使用、requests、limits 和事件中的 OOMKilled 记录。修改限额前需先确认节点可用容量、同机其他工作负载和调度策略,不能只为消除告警而盲目提高上限。

如果发现 OOM,先保留日志和监控,再判断是总量不足、某个进程异常增长,还是容器限额过低。 不建议把“关闭 OOM 机制”或“增加 swap”当作根因修复:前者可能让系统陷入长时间失去响应,后者也不能替代足够的物理内存。

三、按进程定位内存增长来源

确认压力发生后,查看进程占用。以下命令适用于常见 Linux 系统,按常驻内存 RSS 从高到低列出进程:

三、按进程定位内存增长来源配图

ps -eo pid,ppid,comm,rss,%mem,%cpu --sort=-rss | head -n 20

RSS 单位为 KB,是进程当前驻留在物理内存中的页面估算值。它适合快速找出高占用进程,但多个进程可能共享同一批内存映射,不能简单把 RSS 相加当作精确总量。若已安装 smem,可用它查看 PSS 等共享内存分摊指标;没有安装时,先按进程类别和趋势定位即可。

常见的 WordPress 服务进程包括 PHP-FPM、数据库、缓存服务和 Web 服务器。排查时不要只看单个进程的最大值,还要检查进程数量是否在流量高峰同时上升:

pgrep -a php-fpm
pgrep -a mysqld
pgrep -a mariadbd

某些系统的进程名或服务实现不同,pgrep 无输出不等于服务未运行,可通过 systemctl --type=service --state=running 核对实际服务名称。不要在未核实服务名和配置路径时直接复制重启命令。

对 PHP-FPM,可先确认实际加载的配置文件和进程管理模式,再查看 pm.max_children、pm.max_requests 等设置。不同 PHP 版本、发行版和安装方式的配置路径可能不同,先用以下方式核对:

php-fpm -tt 2>&1 | head -n 40

若系统使用版本化命令,例如 php-fpm8.2,应替换为实际命令;该命令的作用是检查配置,不要将输出中的路径当作所有环境通用的路径。也可查看服务状态和启动参数:

systemctl status php-fpm --no-pager
systemctl cat php-fpm

PHP-FPM 子进程数过高时,单个进程的内存看似不大,乘以并发数量后也可能压垮整机。可以在高峰期采集 PHP-FPM 子进程 RSS 的中位数或较高分位,再估算可承受进程数:

可用于 PHP-FPM 的内存 ≈ 总内存 − 操作系统与文件缓存余量 − 数据库及其他常驻服务内存
估算的 pm.max_children 上限 ≈ 可用于 PHP-FPM 的内存 ÷ PHP-FPM 子进程的典型 RSS

这只是容量估算,不是直接可用的配置值。举例来说,如果某个环境在高峰期 PHP 子进程的典型 RSS 约为 120 MB,计划留给 PHP 的内存约为 12 GB,简单相除得到约 100 个进程;但还需留出峰值余量,并观察进程内存分布、数据库增长和请求排队情况。把最大进程数设置成计算结果的上限,可能让所有进程同时达到高占用,从而触发 OOM。

当 PHP 进程过多时,优先核对实际并发、慢请求、队列和单进程内存,而不是单纯增加 pm.max_children。 并发数过低会造成排队,过高则会扩大内存峰值。pm.max_requests 可用于让处理一定请求数后的子进程退出并重建,可能缓解特定扩展或代码导致的渐进式增长,但会增加进程周转,不能代替定位内存泄漏或异常请求。

数据库占用上升时,应区分缓存设计和异常工作集增长。数据库为提高查询效率使用缓冲池是正常现象;需要观察的是总内存是否留有余量、连接数是否异常、临时表或查询是否在高峰期增加,以及是否和 PHP 并发同时增长。不要为了让系统监控中的“已用内存”下降而随意减小数据库缓存,缓存过小可能导致更多磁盘读取,反而增加查询延迟。调整前应保存原配置,并在低峰期分项修改;如延迟或错误率恶化,按备份恢复原参数并重新加载或重启对应服务,具体操作取决于配置项和数据库版本。

如果使用 Redis 等对象缓存,也需关注其自身内存上限、淘汰策略和实际键增长。缓存可以减少数据库查询,但缓存无限增长同样会挤占 PHP 和系统所需内存。应检查缓存占用趋势、命中率和淘汰情况,确认配置与业务需求匹配;不要将清空全部缓存作为常规排查手段,因为这可能造成回源和数据库请求瞬间增加。

四、分清缓存占用、并发峰值与真正的容量不足

判断内存压力时,应把“内存被使用”拆解为可回收缓存、常驻服务、短时峰值和持续增长。Linux 的页缓存本身并非浪费;数据库缓存也可能是经过设计的工作集。更值得警惕的是 MemAvailable 持续下降、swap 读写持续发生、OOM 记录出现,或同一进程的 RSS 随时间不断增长且没有回落。

可按以下结果分支处理:

  • 只有 free 低,但 available 稳定、没有持续换页,响应正常:先核对告警是否只按 free 设置。可以调整监控判断方式,以可用内存、换页活动和服务延迟综合告警;不需要为了“让 free 变大”清理页缓存。
  • PHP 子进程数量在流量高峰同步增加,且总 RSS 挤压其他服务:检查请求并发、慢请求和 PHP-FPM 进程策略。先做容量估算,再小步调整最大进程数,避免一次改大造成更多并发占用。
  • 单个或少数进程 RSS 持续增长,流量下降后仍不回落:记录进程 PID、RSS、请求和日志变化,排查插件、扩展、长时间运行任务或异常查询。需要复现或采样时,优先在测试环境执行;不要为定位问题直接在线上终止高占用进程。
  • 主机有余量但容器报 OOM:核对容器限额、同容器内进程和工作负载峰值。只有确认节点有可用容量后,才考虑调整限制。
  • 内存和换页指标正常,网站仍明显变慢:继续检查 CPU、磁盘 I/O、数据库等待、锁和 PHP 请求耗时。此时把问题直接归因于 DDR5 容量,证据不足。

对于百万级访问,日累计访问量不能直接换算为同时需要多少内存。更有用的是峰值每秒请求、动态页面比例、PHP 请求耗时、缓存命中率和数据库查询量。大量静态页面命中缓存,与大量未缓存的动态请求,对 PHP-FPM 和数据库的压力并不相同。容量评估应使用峰值时段的并发和每个进程的实际内存,而不是仅根据日访问量推算。

五、什么情况下才进一步检查 DDR5、NUMA 和内存带宽

“DDR5 瓶颈”可能指内存容量不足,也可能指数据访问效率受限,两者需要不同证据。若 MemAvailable 充足、没有持续换页和 OOM,而请求仍变慢,先排除 CPU、磁盘、数据库锁和代码路径问题;只有在负载表现出较高内存访问压力时,再进一步检查 NUMA 和带宽。

先确认 CPU 拓扑和内存节点:

lscpu
numactl --hardware
numastat

numactl 未安装时,不要据此判断没有 NUMA;可先用 lscpu 和 /sys/devices/system/node/ 下的节点信息核对。numastat 中若本地与远端内存访问分布异常,可能提示进程跨节点访问较多,但它本身不能证明内存带宽已经饱和。还要结合应用延迟、CPU 利用率、进程放置和采样工具判断。

内存频率或通道配置应以当前系统实际识别情况为准,不能只依据产品名称或内存代际推断性能。dmidecode 可读取固件提供的内存设备信息,但显示值可能受固件和虚拟化环境影响,也不等同于应用实际获得的带宽。测量带宽需要适合的基准工具和可重复的测试条件,应避开生产高峰;不应在繁忙线上直接运行高负载压力测试。

如果怀疑 NUMA 亲和性或进程绑核,先记录当前进程配置和基线,在测试环境或低峰期逐项试验。绑定不当可能把进程限制在单个节点,导致可用内存和 CPU 分布失衡;未经验证,不要直接修改启动参数或强制绑定节点。回滚时恢复原来的服务启动参数,并在重新加载或重启后确认进程分布已恢复。

以具体容量作参考,A5数据的香港AMD 4584PX服务器配置包含 64GB DDR5-5600。内存容量用于评估 PHP、数据库及系统缓存能否同时容纳在物理内存中,DDR5-5600 则是内存规格信息;这两项都不能单独证明某个 WordPress 站点可以承载特定并发。实际结果还取决于进程配置、页面缓存、查询负载和应用本身的内存使用情况。

五、什么情况下才进一步检查 DDR5、NUMA 和内存带宽配图

六、按影响范围修复,并保留回滚办法

确认根因后,按低风险到高风险处理:

  1. 修正告警口径。 如果只有 free 低、可用内存稳定且没有换页,可调整监控为关注 MemAvailable、持续换页、OOM 和业务响应时间。修改前保存原阈值和告警规则;误报增多时恢复原设置并逐项调整。
  2. 处理异常请求和不合理并发。 通过访问日志、PHP-FPM 状态和慢日志定位高耗时路径。先在应用或缓存层验证针对性调整,再观察数据库请求和 PHP 排队是否改善,避免一次性扩大工作进程。
  3. 合理分配服务内存。 为 PHP-FPM、数据库、缓存服务和系统保留明确余量。修改前备份配置,确认配置语法和对应服务名称;先在低峰期变更一项,检查配置后再按服务要求 reload 或 restart。若出现启动失败、延迟上升或错误增多,恢复备份并执行对应的服务恢复操作。
  4. 处理容器限额或进程异常增长。 修改容器限制前检查节点总容量与同机负载;若属于单进程持续增长,则优先定位代码、插件或扩展,而不是持续提高限额。
  5. 评估扩容或拆分负载。 只有在优化后峰值仍持续出现低可用内存、换页或 OOM,且进程内存使用符合预期时,才说明当前物理容量可能不足。扩容前按实测峰值估算各服务内存和余量,避免只按照日访问量选择规格。

修改 pm.max_children 或数据库缓存等参数时,建议记录变更前后的数值、时间、服务状态和监控曲线。不要在未确认影响范围时批量重启 PHP、数据库和缓存服务;重启可能中断请求,也可能在缓存重建后引发短时回源压力。需要重启时,应先确认业务窗口、连接情况和恢复方式。

七、用同一组指标验证修复

修复后应在与故障相近的访问负载下复测,至少观察内存、换页、进程数量、OOM、请求延迟和错误率。若流量条件不同,应注明差异,不能把低峰期恢复正常当成高峰容量问题已经解决。

验证项预期变化仍异常时的排查方向
MemAvailable高峰期间不再持续快速下降检查 PHP、数据库和容器总占用
vmstat 的 si/so不再持续有换入换出活动检查物理内存容量和异常进程
内核日志不再出现新的 OOM 记录对照被终止进程和容器事件
PHP-FPM 进程数与 RSS在预期范围内波动,流量回落后有所恢复检查并发上限、慢请求和单进程增长
页面延迟、5xx 和队列与基线相比稳定或改善继续排查 CPU、I/O、数据库和应用瓶颈

可在修复后连续记录一段覆盖业务高峰的趋势,并与变更前同时间段比较。若 OOM 消失但响应时间仍高,说明内存问题可能已缓解,网站仍存在其他瓶颈;若可用内存改善但高峰时仍持续换页,则应重新核算各服务的并发预算,而不是只调整告警阈值。

排查 DDR5 内存告警的关键,是先确认告警是否代表真实压力,再用换页和 OOM 记录定位系统状态,随后按进程、容器和服务拆分占用。只有这些指标基本正常而性能仍受限时,才进一步调查 NUMA 和内存带宽。按同一组指标复测并持续观察高峰曲线,才能判断修复是否真正解决了问题。

目录结构
全文