游乐游手机版
首页/数据库/文章详情

Redis淘汰机制结合Pub/Sub实现LRU本地缓存同步方案

时间:2026-08-20 20:08
Redis 的 LRU 淘汰机制不会触发 Pub Sub 事件,只有键过期事件(需配置 notify-keyspace-events Ex)才能被监听;如果要实现缓存同步失效,应依赖 TTL + keyspace notification,而不是依赖 LRU 淘汰策略。Redis 本身并没有真正意义

Redis 的 LRU 淘汰机制不会触发 Pub/Sub 事件,只有键过期事件(需配置 notify-keyspace-events Ex)才能被监听;如果要实现缓存同步失效,应依赖 TTL + keyspace notification,而不是依赖 LRU 淘汰策略。

如何利用Redis淘汰机制实现简单的LRU本地缓存同步_通过Pub/Sub监听

Redis 本身并没有真正意义上的“本地缓存同步”能力。它的 LRU 淘汰策略只在单个 Redis 实例内部生效,无法把淘汰结果跨进程、跨服务传播出去。如果想依靠 maxmemory-policy allkeys-lru 来触发 Pub/Sub,通知其他节点“这个 key 刚刚被淘汰了”,实际上是不可行的,因为 Redis 不会为内存淘汰事件发布消息。

Redis 的 LRU 淘汰不会触发任何 Pub/Sub 事件

这是一个非常常见的误区。很多人以为只要开启了 allkeys-lru,当 key 被移除时就能通过订阅机制收到通知。但事实并非如此。像 DEL、EXPIRE、EVICT 这类底层行为里,Redis 默认不会针对淘汰动作对外广播。只有在 key 明确进入过期流程,且启用了 keyspace notifications 的情况下,Redis 才会向 __keyevent@__:expired 频道发送消息。需要注意的是,淘汰(eviction)和过期(expiration)并不是一回事,两者的实现机制彼此独立。

  • EXPIRE / SET ... EX → 可能触发 expired 事件(前提是配置了 notify-keyspace-events Ex)
  • LRU 淘汰 → 全程静默,没有 channel、没有日志、也没有回调通知
  • 即便使用 redis-cli --stat 看到 evicted_keys 持续增长,也无法得知究竟是哪个 key 被淘汰

想同步“被 LRU 踢掉的 key”,得自己埋点拦截

如果你确实需要让其他服务感知“某个 key 已经从当前 Redis 缓存中消失”,就不能依赖自动淘汰,而应该绕开 LRU 机制,改用显式可控的失效方式:

  • 不要依赖自动淘汰,改为使用带 TTL 的 SET key value EX 300 主动设置过期时间
  • 提前开启 keyspace notifications:执行 CONFIG SET notify-keyspace-events Ex(也可以写入 redis.conf)
  • 订阅 __keyevent@0__:expired 频道(注意 db 编号必须一致)
  • 收到消息后,解析 payload(即 key 名),再通过自定义 channel(如 cache-evict-broadcast)使用 PUBLISH 转发给其他节点

示例监听逻辑(Python):

import redis
conn = redis.Redis()
pubsub = conn.pubsub()
pubsub.subscribe('__keyevent@0__:expired')

for msg in pubsub.listen():
if msg['type'] == 'message':
key = msg['data'].decode()
# 这里不是淘汰,是过期;但语义上可当作“缓存失效”处理
conn.publish('cache-invalidation', key)

Pub/Sub 同步缓存失效,别碰 LRU,盯紧 TTL + keyspace events

真正可落地的方案不是“同步淘汰”,而是“同步缓存失效”:

  • 所有写操作统一采用 SET key value EX N 或 PEXPIRE,避免把 maxmemory 当成业务级淘汰方案
  • 确保所有 Redis 实例都开启 notify-keyspace-events,至少包含 Ex
  • 每个业务服务启动后订阅 cache-invalidation 频道,收到 key 后及时清理本地缓存或二级缓存
  • 尽量不要直接使用 DEL 删除,因为它不会触发 expired 事件,也无法用于失效通知;更稳妥的方式是通过 EXPIRE key 1 强制过期兜底

在这种架构下,LRU 相关参数(maxmemory-policy、maxmemory-samples)只适合作为 Redis 内存保护策略存在,不应参与缓存同步业务逻辑。它的职责是“内存兜底”,而不是“同步通知源”。

真正需要重点关注的是 TTL 的精度以及 Pub/Sub 的可靠性:过期事件可能会有几百毫秒延迟,而 Pub/Sub 本身也不保证消息一定送达。如果业务对缓存一致性要求较高,就不能只依赖这一层,还应结合数据库 binlog、延迟双删或业务侧补偿机制一起使用。

来源:https://www.php.cn/faq/3019694.html
上一篇phpMyAdmin排查Laravel 12数据库迁移失败方法 下一篇WPF现状与未来发展策略解析:今生与前景探讨
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Redis是什么:核心特性、架构与应用场景解析
数据库 · 2026-09-01

Redis是什么:核心特性、架构与应用场景解析

Redis是一款基于内存的键值型NoSQL数据库,以超高读写速度和丰富的数据结构著称。本文系统梳理Redis的核心特性、架构组成、性能优势及典型应用场景,并通过与Memcached、MySQL、MongoDB的对比,帮助开发者快速判断Redis是否适合当前业务需求。

Windows 安装 MongoDB 完整图文教程
数据库 · 2026-09-01

Windows 安装 MongoDB 完整图文教程

本文详细介绍在 Windows 系统上安装 MongoDB 的完整流程。从官网下载 MSI 安装包开始,逐步演示自定义安装路径、配置 Windows 服务、跳过 MongoDB Compass 等关键选项,并提供通过系统服务列表验证安装是否成功的方法,帮助开发者快速搭建本地 MongoDB 环境。

Linux 安装 MongoDB 完整指南:依赖配置、环境变量与服务启动
数据库 · 2026-09-01

Linux 安装 MongoDB 完整指南:依赖配置、环境变量与服务启动

本文详解在 Linux 系统下安装 MongoDB 的完整流程,涵盖依赖包安装、二进制包下载解压、环境变量配置、数据与日志目录创建及服务启动验证。通过标准化命令与路径说明,帮助开发者快速完成部署并确认服务状态。

MacOS安装MongoDB完整教程
数据库 · 2026-09-01

MacOS安装MongoDB完整教程

本文介绍在MacOS系统下安装MongoDB的完整流程,涵盖下载、解压、目录配置、环境变量设置及服务启动。通过明确的命令与参数说明,帮助开发者快速完成环境搭建并验证安装结果。

Ubuntu系统安装与配置Redis完整指南
数据库 · 2026-09-01

Ubuntu系统安装与配置Redis完整指南

本文详解在Ubuntu系统中安装Redis的两种主流方式:apt在线安装与源码编译安装。涵盖版本选择逻辑、服务启停与状态检查、连接验证方法,以及在线练习工具与桌面GUI客户端的对比与使用建议,帮助开发者快速搭建并验证Redis运行环境。