Redis Keyspace通知需显式配置notify-keyspace-events Ex并确保Pub/Sub权限;Pub/Sub事件易丢失,推荐改用Redis Stream;Serverless函数需代理订阅;触发扩容前须校验过期事件真实性与命名规律;扩容后必须通过version key驱动客户端刷新路由。

Redis Keyspace通知必须显式开启且配置正确
Redis默认关闭Keyspace通知,不手动启用就收不到任何过期事件。关键配置项是notify-keyspace-events,至少要包含Ex(E表示键事件,x表示过期事件)。只设Ex还不够——如果用Pub/Sub监听,还需确保Redis实例允许PUBLISH权限(云服务如阿里云Redis可能默认禁用)。
实操建议:
- 在
redis.conf中添加:notify-keyspace-events Ex,然后CONFIG REWRITE或重启生效 - 若用AWS ElastiCache或腾讯云CKV,需进控制台确认“键空间通知”开关已打开,部分版本需提交工单开通
- 验证是否生效:用
redis-cli --csv psubscribe '__keyevent@0__:expired'后执行SET test 1 EX 1,看是否收到消息;收不到就一定是配置或权限问题
Pub/Sub消费端必须处理断连与消息丢失
Redis Pub/Sub是“发即忘”模型,没有ACK机制。客户端断连期间发布的expired事件会直接丢弃,无法回溯。这意味着不能把扩容逻辑直接塞进一个长连接的psubscribe脚本里——它挂了,事件就没了。
实操建议:
- 用
redis-py时,不要依赖单个pubsub.listen()循环;改用带重连+心跳的封装,例如结合tenacity做指数退避重连 - 更稳妥的做法是:用Redis Stream(>=5.0)替代Pub/Sub,写入
XADD expired-events * key test ttl 1000,再用XREADGROUP消费,支持ACK和消息重放 - Serverless函数(如AWS Lambda)本身无状态、生命周期短,不能直接订阅;必须由常驻服务(如Fargate容器或云函数触发器代理)接收事件,再调用目标函数
Serverless函数触发扩容前必须校验负载真实性
单个key过期不代表真实负载激增——可能是定时任务清理缓存、测试数据误设TTL,甚至攻击者批量SETEX制造假过期风暴。直接按事件数量扩容,容易引发雪崩式扩缩容。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
实操建议:
- 在触发函数里加滑动窗口计数:用Redis
INCR+EXPIRE统计过去60秒内过期事件数,超过阈值(如500次/分钟)才继续 - 检查过期key命名规律:
if key.startswith('cache:user:'):才认为是业务缓存压力;匹配tmp:或test:前缀则忽略 - 避免硬编码扩容动作:把扩容逻辑抽象成可配置的
scale_policy.json,存于对象存储(如S3),函数启动时拉取,便于灰度和回滚
自动扩容结果必须反向同步到Redis配置闭环
扩容完成(如新增1个Redis分片)后,如果不更新客户端路由规则或集群拓扑,新流量仍打不到新节点,整个链路就断在最后一环。而Redis Cluster本身不提供“动态重分片后自动广播新槽位”的能力。
实操建议:
- 扩容脚本执行成功后,立刻写入一个
SET cluster:topology_version "v20240521-1"并设永不过期,供所有客户端启动时比对 - 客户端SDK(如
redis-py-cluster)需监听该key变化,触发reload_slots_cache();若用自研路由,得实现类似WATCH cluster:topology_version+GET轮询 - 云厂商方案注意兼容性:阿里云Tair的
proxy模式支持热加载,但直连Redis Standalone实例集群必须重启客户端,这点极易被忽略
实际落地时,最常卡在Pub/Sub丢事件和扩容后路由不同步这两点。前者靠Stream兜底,后者靠version key驱动客户端刷新——不补上这层闭环,监听再准也没用。


















