页面缓存和对象缓存都叫「缓存」,但处在 WordPress 请求链路的不同位置:一个保存最终生成的 HTML,另一个保存数据库查询结果。分不清这两者,就容易出现「装了 Redis 为什么首页还是慢」或者「页面缓存开了后台还是卡」的困惑。
这篇先讲清区别,再走一遍 1Panel 下的实际配置。
WordPress 与静态站的根本差异
WordPress 是典型的动态内容管理系统,页面在访客请求时才生成:
- 浏览器请求页面
- PHP 脚本开始执行,向 MySQL 发出多个查询,取内容、配置、评论
- PHP 把数据和主题模板结合,实时渲染出完整 HTML
- 把这份 HTML 返回给浏览器
关键点在于:页面的构建发生在请求时。每一次没有缓存的访问,都要重新消耗 PHP 和数据库资源。
Hugo、Astro 这类静态站点生成器完全不同:它们在部署前就把每个页面渲染成 .html 文件,访客请求时服务器只是把文件读出来返回。
所以静态站不需要「页面缓存」这个概念——它本来就没有动态渲染这一步。而 WordPress 想接近这种响应速度,只能靠缓存把生成结果存下来。
页面缓存(Page Cache)
代表插件:WP Super Cache、W3 Total Cache、WP Rocket。
- 缓存内容:完整的、最终渲染好的 HTML
- 工作原理:首个访客访问时 WordPress 正常执行,插件捕获这份 HTML 并存成静态文件
- 加速逻辑:后续访客直接拿到这个文件,完全绕过 PHP 执行和数据库查询
- 核心目标:把动态请求的开销降到接近零,改善 TTFB
对纯内容站、匿名访问为主的站点,页面缓存收益最大——它直接消除了 PHP 这一段。
对象缓存(Object Cache)
代表方案:Redis 或 Memcached,配合 Redis Object Cache 插件。
- 缓存内容:重复、频繁的数据库查询结果,也就是「对象」——站点配置、主题与插件设置、导航菜单、瞬态数据
- 工作原理:把这些结果放在内存数据库里,下次需要时优先从内存取
- 加速逻辑:减少对 MySQL 的重复查询,内存读写远快于磁盘
- 核心目标:加快 WordPress 生成页面这个过程本身
对象缓存覆盖所有请求,包括后台操作和登录用户——这些恰恰是页面缓存管不到的场景。
两种缓存如何配合
| 对比维度 | 页面缓存 | 对象缓存 |
|---|---|---|
| 缓存内容 | 完整 HTML(成品) | 数据库查询结果(原料) |
| 缓存位置 | 服务器硬盘 | Redis 内存 |
| 服务对象 | Web 服务器,直接给访客 | WordPress 程序自身 |
| 核心职责 | 加速前端响应 | 加速后端数据处理 |
只用页面缓存:匿名访客很快,但一旦缓存失效(管理员登录、用户提交评论),渲染速度依然受限于数据库,后台会明显卡顿。
只用对象缓存:后台和动态功能流畅,但每个匿名请求仍要执行 PHP 来拼页面,效率远不如直接发一个静态文件。
两者解决的是不同环节的问题,不互相替代。
在 1Panel 下启用 Redis
安装 Redis 服务与 PHP 扩展
- 在 1Panel 应用商店安装
Redis - 打开当前 WordPress 使用的 PHP 运行环境
- 在 PHP 扩展里启用
redis - 保存后等待运行环境重建完成
这一步的目标只有两个:服务器里真的有 Redis 在跑,当前 PHP 环境真的能调用 Redis 扩展。少任何一个,插件都会报「Redis 不可访问」或「扩展不存在」。
安装 WordPress 插件
后台安装并启用 Redis Object Cache。装好后先别急着点各种优化按钮,先把连接参数写清楚,否则「可访问 / 不可访问」的状态会反复横跳。
在 wp-config.php 写入连接参数
建议显式写清楚,而不是完全依赖插件自动探测:
define('WP_CACHE_KEY_SALT', 'example.com');
define('WP_REDIS_SELECTIVE_FLUSH', true);
define('WP_REDIS_HOST', 'redis');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_DATABASE', 0);
define('WP_REDIS_PASSWORD', '替换成你的 Redis 密码');WP_CACHE_KEY_SALT
给缓存键加前缀。一台服务器上多个 WordPress 共用一套 Redis 时,这个值几乎是必填项。建议直接用站点域名或一个稳定、唯一的标识。
WP_REDIS_SELECTIVE_FLUSH
设为 true 后,刷新缓存时只清理当前站点对应的键,而不是把整台机器共用 Redis 的缓存一把清空。多站环境必须开。
WP_REDIS_HOST 为什么写 redis
1Panel 的 Docker 网络里,应用之间通过容器名或服务名互相访问。只要 WordPress 运行环境和 Redis 在同一个可互通网络里,redis 这个主机名通常就能直接用。也可以在 1Panel 的「Redis 连接信息」里看实际地址,以面板显示的为准。
多站共用 Redis 的隔离
早期我在多站环境踩过一个坑:几个站点都在用 Redis,但没做缓存键隔离。结果是:
- 某个站点刷新缓存,把别的站点缓存一起清掉
- 站点之间的命中和污染变得不可控
不管是旧宝塔环境还是现在的 1Panel,只要多站共用 Redis,至少要做两件事:
WP_CACHE_KEY_SALT使用唯一前缀(推荐域名)WP_REDIS_SELECTIVE_FLUSH设为true
这两条做完,站点之间就是逻辑隔离的,各自的缓存互不干扰。
确认生效与排错
三个角度确认
插件状态页:Redis Object Cache 页面会直接显示是否已连接、是否已启用对象缓存。
Redis 侧活动:刷新几次首页和后台,如果 Redis 出现命中与读写,说明对象缓存已经在工作。
实际体感:数据库查询多的场景,后台和首页会明显更稳,小规格 VPS 上尤其明显。
插件提示「Redis 不可访问」
按这个顺序查:
- Redis 容器是否真的在运行
- PHP 的 redis 扩展是否已启用
WP_REDIS_PASSWORD是否与面板显示一致WP_REDIS_HOST是否与容器网络中的实际地址一致
如果四项都对还是连不上,去看 wp-content/object-cache.php 里最终生成的连接参数——重点确认主机地址有没有停留在旧值、密码有没有被正确带进去。
页面缓存的两个常见配置错误
搜索页没排除:?s= 后面的关键词无穷多,每个都生成一份缓存会产生大量碎片。搜索页应当排除。
带查询字符串的页面没排除:?x=y 这类参数同样会制造大量无意义缓存,建议统一排除,只缓存干净的 URL。
小结
- 页面缓存存 HTML,绕过 PHP;对象缓存存查询结果,加速 PHP 自身
- 两者覆盖不同场景,不能互相替代
- 多站共用 Redis 必须做键前缀隔离和选择性刷新
- 缓存不是银弹:先确认瓶颈在哪,再决定加哪一层
相关内容
一台 2 核 4G 的 VPS 承载 4 个 WordPress:从 PHP-FPM 的 ondemand 改造、MySQLTuner 诊断、MariaDB 参数收敛,到缓存分层、端口暴露检查和 swap 兜底。
一台 2C4G VPS 上用 1Panel(LEMP + Docker)跑多个 WordPress,优化后后台变慢并出现 EdgeOne 524。本文按时间线复盘:如何从“缓存/超时”误区切换到“容器环回 + Docker 出网被 iptables FORWARD 掐死”的根因定位,最终用 host-gateway + iptables 持久化完成修复,并给出可复制的检查清单。