PHP多级缓存怎样选存储引擎_PHP引擎选择缓存法【适配】

4次阅读

最稳的php多级缓存组合是redis作一级缓存、APCu作二级缓存:redis存高频可共享数据,APCu存本机独享只读配置,兼顾性能与一致性。

PHP多级缓存怎样选存储引擎_PHP引擎选择缓存法【适配】

Redis 作一级缓存、APCu 作二级缓存最常用

PHP 多级缓存不是得越多越好,而是要按访问频次、数据生命周期和一致性要求分层。生产环境最稳的组合是:Redis 存高频可共享的数据(如用户会话、热点商品),APCu 存本机独享的、只读且变化极慢的配置或模板元数据(如路由映射、语言包哈希)。这样既避免 Redis 网络开销拖慢本地高频读,又防止 APCu 进程隔离导致集群数据不一致。

常见错误是把所有东西都往 Redis 塞——结果 get_config() 每次都走 TCP,QPS 上不去;或者全用 APCu——多实例部署后缓存不同步,改个开关要等所有机器重启。

  • APCu 只在单进程内有效,不能跨 PHP-FPM worker 共享,更不能跨服务器
  • Redis 支持过期、原子操作、发布订阅,但引入网络延迟和连接池管理成本
  • 若用 memcached 替代 Redis,注意它不支持复杂数据结构incr/decr 行为也略有差异

文件缓存仅适合低并发调试场景

别被 file_get_contents() + serialize() 的简单迷惑。文件缓存在高并发下容易触发 inode 锁争用,flock() 不到位时还会出现脏读。CI/CD 流水线里临时用它存构建产物没问题,但线上 Web 请求中作为二级缓存,stat() 频繁调用会直接拉高系统负载。

如果你非要用文件缓存,请确保:

立即学习PHP免费学习笔记(深入)”;

  • 缓存目录挂载在 tmpfs(内存文件系统),避开磁盘 IO
  • 每个缓存项用独立文件,避免大文件锁整块区域
  • 加前缀隔离命名空间,比如 /tmp/cache/v2/user_123.json,别用 md5(serialize($data)) 当文件名——太难 debug

OPcache 不是缓存引擎,别把它当二级缓存用

OPcache 是 PHP 字节码缓存,只加速 .php 文件解析,对 json_decode() 结果、new stdClass() 对象file_get_contents() 读出来的字符串完全无效。很多人误以为开启 opcache.enable=1 就“有缓存了”,结果数据库查询结果还在裸奔。

它的作用边界非常明确:

  • 缓存编译后的 opcode,减少重复 parse 和 compile
  • 不缓存运行时数据,也不参与任何应用层缓存逻辑
  • APCu 可共存,但两者数据完全不互通——apcu_store('key', $val) 不会影响 OPcache 的命中率

选型要看部署拓扑,不是看 benchmark 数值

单机 docker 环境跑 Redis + APCu 没问题;但 kubernetes 下如果每个 Pod 自带 Redis 实例,就变成资源浪费+状态分散。这时候该换成 Redis Cluster 或托管服务(如 AWS ElastiCache),而本机缓存仍用 APCu

另一个常被忽略的点:PHP 版本兼容性。PHP 8.0+ 的 APCu 默认关闭 apc.enable_cli=1,命令行脚本里 apcu_fetch() 会静默失败;Redis 扩展在 PHP 7.4 和 8.2 中的 connect() 超时参数名也从 ['timeout' => 2] 变成 ['tcp://127.0.0.1:6379?timeout=2']

缓存层级越深,失效路径越难追踪。与其堆三级缓存,不如先确认 Redis 是否用了连接池、APCu 是否开了 apc.shm_size 足够大、关键数据有没有加 version 前缀防雪崩——这些细节比引擎名字重要得多。

text=ZqhQzanResources