暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis注意

原创 手机用户7109 2025-10-06
75

1.监听过期key

在Java中,使用KeyExpirationEventMessageListener的实现类来监听redis中即将过期的key,并调用onMessage方法对过期key进行处理,示例:

@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
  /**
   * Creates new {@link MessageListener} for {@code __keyevent@*__:expired} messages.
   *
   * @param listenerContainer must not be {@literal null}.
   */
  public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
    super(listenerContainer);
  }
//接收到过期的key
  @Override
  public void onMessage(Message message, byte[] pattern) {
    String expiredKey = message.toString();//拿到key值
    System.out.println("收到过期key:"+expiredKey);
    super.onMessage(message, pattern);
  }
}

当然接收到KeyExpirationEvent的前提是redis-server配置文件里的notify-keyspace-events参数要打开,否则也是检测不到的,参数介绍参见文档

    https://geek-docs.com/redis/redis-ask-answer/124_redis_notifykeyspaceevents_in_redis.html


在 Redis 中,键空间是指所有键的集合。每当执行与键相关的操作时,例如设置、修改、删除键等,Redis 都会生成相应的事件。通过配置 notify-keyspace-events 选项,我们可以开启对键空间事件的监听,从而实现实时监控和处理键空间的操作。

notify-keyspace-events 可以设置为以下各项的组合: – K 键空间通知,所有通知事件都以keyspace@为前缀,并通过 PUBLISH 命令发送 – E 键事件通知,所有通知事件都以keyevent@为前缀,并通过 PUBLISH 命令发送 – g DEL、EXPIRE、RENAME等生成通知 – s SET、EXPIREAT等生成通知 – h HSET、HDEL等生成通知 – l LSET、LREM等生成通知 – z ZADD、ZREM等生成通知 – x 过期事件:当键被设置了过期时间时,会生成通知 – e 驱逐事件:当键因为空间被驱逐出去时,会生成通知 – A 任何事件都会生成通知# K Keyspace events, published with __keyspace@<db>__ prefix. # E Keyevent events, published with __keyevent@<db>__ prefix. # g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... # $ String commands # l List commands # s Set commands # h Hash commands # z Sorted set commands # x Expired events (events generated every time a key expires) # e Evicted events (events generated when a key is evicted for maxmemory) # n New key events (Note: not included in the 'A' class) # t Stream commands # d Module key type events # m Key-miss events (Note: It is not included in the 'A' class) # A Alias for g$lshzxetd, so that the "AKE" string means all the events # (Except key-miss events which are excluded from 'A' due to their # unique nature).
示例 notify-keyspace-events "AKE"


实际上这么做是有问题的,redis官方文档显示:

    当某个键被访问,并被上述机制之一检测出已过期时,便会生成过期事件。因此,Redis服务器无法保证在键的生存时间精确变为零时立即生成过期事件。

也就是说,只有key被访问时(同时这个key濒临过期的情况下)才会触发过期事件,redis自己主动清理是不会触发过期事件的,因此这种对过期键的处理方式是有问题的.

当redis里的数据量很大时,对过期Key的正确的处理方式是什么?

2.过期key解决方案分析:

    1.类似redis,提前将一些重要的key登记在缓存中,或者消息队列里,消费者每次向redis查询这些key的过期时间,并予以更新.

        但假设有些Key已经被弃置了,这里就会有问题.一个比较好的方式是把key值单独放到一个redis里,消息队列的log只是起到一个崩溃恢复和重建的作用.

    2.不过redis的问题是自己也会杀key,那其实不如使用elasticsearch来代替redis.

elasticsearch相当于一个分布式Map,redis就不是了.消息队列则是分布式日志,因此如果希望持久化的稳定的从Map里拿数据,还是应该用elasticsearch.

3.过期Key最终解决方案

            1.对于希望持久存在于redis里的key,可以用elasticsearch,存储这些key名

            2.开启若干个定时服务,定时从elasticsearch里获取这些key,并在redis里更新过期时间

            3.有些时候商品会下架,可能需要永远删除这个key,也就是不希望再更新这个key的过期时间了,就可以同步在elasticsearch里设置.这样定时任务就拿不到这个任务了.

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论