Redis-03键管理与过期

03 键管理与过期

🎯 学习要点

  • TTL 设置与查询
  • 安全扫描与匹配查找
  • 键空间通知与事件监听

📖 名词解释

  • TTL:键的剩余存活时间,单位秒或毫秒。
  • SCAN:游标扫描命令,分批遍历键空间,避免阻塞。
  • KEYS:一次性全量匹配命令,易阻塞,生产需禁用或谨慎使用。
  • 键空间通知:Redis 通过发布消息告知键的事件(过期、删除)。
  • PERSIST:移除键的过期时间,使之持久存在(直到删除)。

🧭 学习方案

  • set+expire+ttl 组合练习设置与查询过期时间,理解不同返回值。
  • 使用 SCAN 按前缀扫描,对比 KEYS 的风险,形成统一扫描工具方法。
  • 开启键空间通知并监听过期事件,在控制台打印观察触发时机。
  • 设计合理的键生命周期与回收策略,避免长久不清理导致内存膨胀。

🗺️ 应用场景说明

  • 支付待确认:下单后设置一个过期键,到时未支付即关闭订单。
  • 清理脏数据:用 SCAN 按业务前缀批量找出旧版本键并删除。
  • 定时提醒:利用过期事件监听,到期后发通知或补偿处理。

⚠️ 注意事项

  • 避免使用 KEYS 在生产环境
  • 使用 SCAN 分批遍历防止阻塞
  • 谨慎操作大 Key 与热 Key

⏳ TTL 设置与查询

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.data.redis.core.RedisTemplate;
import java.time.Duration;

@Service
public class TtlOps {
    @Autowired
    RedisTemplate<String, String> tpl;

    public void setTtl(String key) {
        tpl.opsForValue().set(key, "v", Duration.ofMinutes(5));
    }

    public Long ttl(String key) {
        return tpl.getExpire(key);
    }
}

通俗说明

  • TTL 就是“有效期标签”,到点自动失效,避免长期占用内存。
  • 查询 TTL 返回 -2 代表键不存在,-1 代表没有设置过期,其它是剩余秒数。
  • 热点键建议在基础 TTL 上加一点随机时间,避免同一时刻同时失效(雪崩)。
详细解释
  • 业务上应定义不同数据的生命周期,重要数据用较长 TTL,临时数据用短 TTL。
  • persist 可移除过期时间;批量设置 TTL 建议统一封装工具方法。
  • 雪崩风险来自集中失效,通过随机抖动与预热减少峰值。
速记口诀
  • 口诀:TTL 定生命周期,-1 无过期、-2 不存在

🔎 SCAN 遍历

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.connection.RedisConnection;
import java.util.ArrayList;
import java.util.List;

@Service
public class ScanKeys {
    @Autowired
    RedisTemplate<String, String> tpl;

    public List<String> scanPrefix(String prefix) {
        return tpl.execute((RedisConnection conn) -> {
            List<String> keys = new ArrayList<>();
            ScanOptions options = ScanOptions.scanOptions().match(prefix + ":*").count(100).build();
            var cursor = conn.scan(options);
            while (cursor.hasNext()) keys.add(new String(cursor.next()));
            return keys;
        });
    }
}

通俗说明

  • SCAN 是“分批找键”的方式,不会像 KEYS 那样阻塞全局。
  • match 前缀与 count 批次可调;扫描是近似遍历,注意游标使用。
详细解释
  • 扫描用游标推进,直到游标回到 0 才结束;count 是提示值非硬指标。
  • 匹配前缀需规范命名,避免扫描出无关键影响效率。
  • 不建议边扫描边删除同一键空间,最好先收集再批处理。

📣 键空间通知配置

notify-keyspace-events Ex

通俗说明

  • Ex 开启“过期事件”,让 Redis 在键过期时发消息通知。
  • 监听频道与库号有关,默认库 0 的频道为 __keyevent@0__:expired
详细解释
  • 事件类别由组合字母控制(如 K 键事件、E 过期、g 通用),按需开启。
  • 过期通知在键真正删除时触发,惰性删除可能延后。
  • 开启通知会有少量开销,应仅开启必要事件类别。

🔔 监听过期事件(Spring)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

@Configuration
public class KeyspaceEventsConfig {
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory factory) {
        RedisMessageListenerContainer c = new RedisMessageListenerContainer();
        c.setConnectionFactory(factory);
        c.addMessageListener(new MessageListenerAdapter((MessageListener) (pattern, channel, message) -> {}), new PatternTopic("__keyevent@0__:expired"));
        return c;
    }
    interface MessageListener {
        void onMessage(byte[] pattern, byte[] channel, byte[] message);
    }
}

通俗说明

  • 容器里注册监听器,订阅过期事件频道,收到消息后执行回调。
  • 适合做到期提醒/补偿清理,但事件触发依赖键实际删除时间。
详细解释
  • RedisMessageListenerContainer 维护订阅连接,回调逻辑需轻量与线程安全。
  • 处理函数里建议异步分发或投递到队列,避免阻塞监听线程。
  • 注意库号与频道匹配,跨库监听需分别订阅。

🔍 小结

  • TTL 查询返回值含义:-2 表示键不存在,-1 表示没有过期时间,其他为剩余秒数。
  • 删除 TTL 可用 persist;对热点键建议设置随机 TTL,缓解雪崩。
  • 线上环境使用 SCAN 分批遍历,避免 KEYS 导致阻塞。
  • 键空间通知需显式开启,过期事件在键被删除时触发。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值