PHP缓存数据怎样做读写分离_PHP读写分离缓存法【读写】

2次阅读

php无内置读写分离缓存,实为开发者设计的两级缓存策略:APCu作本地读缓存、redis作中心写缓存,需同步清理多进程APCu并避免误用OPcache。

PHP缓存数据怎样做读写分离_PHP读写分离缓存法【读写】

PHP 本身没有内置的“读写分离缓存”机制,所谓“读写分离缓存”不是标准术语,而是开发者为缓解缓存雪崩、穿透或主存储压力,人为将 readwrite 操作路由到不同缓存层(比如本地内存 + 分布式 Redis)的一种策略。它不等于数据库读写分离,也不依赖 PHP 语言特性,关键在逻辑设计和缓存选型。

什么时候该考虑两级缓存架构(本地 + 远程)

单靠 Redis 或 memcached 在高并发读场景下容易成为网络瓶颈;而全用 apcuopcache 又无法跨进程共享,更新不一致。两级缓存本质是用本地缓存扛读、远程缓存保一致:

  • 适合读多写少、数据变更不频繁但对读响应要求极高的场景(如商品基础信息、配置项)
  • 不适合实时性极强的数据(如秒杀库存),因为本地缓存会延迟失效
  • 必须配合合理的失效策略(主动删除远端 + 清空本地,或设置短 TTL + 后台异步刷新)

apcu 作本地读缓存 + redis 作中心写缓存怎么配

典型组合:用 apcu 存高频只读副本,所有写操作先落 redis,再清除本机 apcu 对应 key;读时优先查 apcu,未命中再查 redis 并回填。

注意点:

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

  • apcu 是 per-process 的,FPM 下每个 worker 有独立内存空间,apcu_clear_cache() 只清当前进程,不能广播清理
  • 写操作后不能只删 redis key,必须同步触发本机 apcu_delete($key)(否则其他请求仍可能读到旧值)
  • 推荐用 apcu_entry() 带回调的方式读取,避免重复查 redis 和重复写 apcu
  • 示例片段:
function get_user_info($uid) {     $key = "user:{$uid}";     return apcu_entry($key, function() use ($key, $uid) {         // 回调里查 redis,失败则返回 null,apcu 不缓存         $data = redis()->get($key);         if ($data === false) {             $data = fetch_from_db($uid); // 回源             if ($data) {                 redis()->setex($key, 3600, json_encode($data));             }         }         return $data ? json_decode($data, true) : null;     }, 600); // apcu 缓存 10 分钟 }

为什么不要用 opcache 当缓存容器

opcache 是为加速 PHP 脚本编译而设的,不是通用键值缓存。它不支持按 key 删除、不提供 TTL、无法序列化复杂结构,且启用 opcache.file_cache_only=1 时甚至不支持运行时写入。

  • 误用 opcache_get_status()['cache_full'] 判断缓存容量?那是 opcode 缓存区满载状态,和业务数据无关
  • 试图用 opcache_compile_file() 缓存 JSON?会直接报错或静默失败
  • 真正需要的是 apcu(共享内存)或 memcached(分布式),不是 opcache

缓存失效时最容易漏掉的一步

多数人记得删 Redis,却忘了通知所有 PHP-FPM worker 清除本地 apcu。没有跨进程通信机制的话,只能靠“懒清除”——让下次读请求发现过期后自动回源更新,但这会造成短暂不一致。

  • 可行解法之一:用 Redis 的 PUB/SUB 通道广播失效事件,各 worker 订阅后执行 apcu_delete()
  • 更轻量做法:写操作后,在 Redis 写一个带时间戳的 version:user:123 key,读时先比对版本号再决定是否跳过 apcu
  • 绝对别用 sleep(1) 等几毫秒再删本地缓存——既不可靠又拖慢响应

真正的难点不在代码怎么写,而在判断哪些数据值得两级缓存、TTL 设多长、失效广播要不要加、以及能否接受几秒内的脏读。这些没法套模板,得看监控里的缓存命中率、Redis 延迟、APCU 内存占用三个指标来回调。

text=ZqhQzanResources