zoukankan      html  css  js  c++  java
  • redis过期key监听事件

    redis常用语缓存操作,但是redis功能不仅仅于此。今天我们来看看redis的key失效事件

    redis安装

    • 为了方便安装。我们直接使用docker安装redis。这里不多赘述docker了。直接贴出代码自己搞成脚本执行就可以了

    docker拉取

    docker pull redis:3.2

    启动

    
    docker run -p 6379:6379 -v /opt/soft/docker/redis/redis.conf:/etc/redis/redis.conf -v /opt/soft/docker/redis/data:/data --name=myredis --restart=always -d redis:3.2 redis-server /etc/redis/redis.conf --requirepass "password" --appendonly yes
    
    
    • 为了安全我们还是设置下密码,将上述脚本password修改为自己的密码即可

    • 上面的/opt/soft/docker/redis/data这个我们只需要创建空文件夹就行了,这个我们是为了将redis日志映射出来方便定位问题。

    • redis.conf文件去官网上下载就行了。docker安装的redis默认没有配置文件。或者直接复制我这里的。

    
    # Redis配置文件样例
    
    # Note on units: when memory size is needed, it is possible to specifiy
    # it in the usual form of 1k 5GB 4M and so forth:
    #
    # 1k => 1000 bytes
    # 1kb => 1024 bytes
    # 1m => 1000000 bytes
    # 1mb => 1024*1024 bytes
    # 1g => 1000000000 bytes
    # 1gb => 1024*1024*1024 bytes
    #
    # units are case insensitive so 1GB 1Gb 1gB are all the same.
    
    # Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
    # 启用守护进程后,Redis会把pid写到一个pidfile中,在/var/run/redis.pid
    daemonize no
    
    # 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
    pidfile /var/run/redis.pid
    
    # 指定Redis监听端口,默认端口为6379
    # 如果指定0端口,表示Redis不监听TCP连接
    port 6379
    
    # 绑定的主机地址
    # 你可以绑定单一接口,如果没有绑定,所有接口都会监听到来的连接
    # bind 127.0.0.1
    
    # Specify the path for the unix socket that will be used to listen for
    # incoming connections. There is no default, so Redis will not listen
    # on a unix socket when not specified.
    #
    # unixsocket /tmp/redis.sock
    # unixsocketperm 755
    
    # 当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
    timeout 0
    
    # 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
    # debug (很多信息, 对开发/测试比较有用)
    # verbose (many rarely useful info, but not a mess like the debug level)
    # notice (moderately verbose, what you want in production probably)
    # warning (only very important / critical messages are logged)
    loglevel verbose
    
    # 日志记录方式,默认为标准输出,如果配置为redis为守护进程方式运行,而这里又配置为标准输出,则日志将会发送给/dev/null
    logfile stdout
    
    # To enable logging to the system logger, just set 'syslog-enabled' to yes,
    # and optionally update the other syslog parameters to suit your needs.
    # syslog-enabled no
    
    # Specify the syslog identity.
    # syslog-ident redis
    
    # Specify the syslog facility.  Must be USER or between LOCAL0-LOCAL7.
    # syslog-facility local0
    
    # 设置数据库的数量,默认数据库为0,可以使用select <dbid>命令在连接上指定数据库id
    # dbid是从0到‘databases’-1的数目
    databases 16
    
    ################################ SNAPSHOTTING  #################################
    # 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
    # Save the DB on disk:
    #
    #   save <seconds> <changes>
    #
    #   Will save the DB if both the given number of seconds and the given
    #   number of write operations against the DB occurred.
    #
    #   满足以下条件将会同步数据:
    #   900秒(15分钟)内有1个更改
    #   300秒(5分钟)内有10个更改
    #   60秒内有10000个更改
    #   Note: 可以把所有“save”行注释掉,这样就取消同步操作了
    
    save 900 1
    save 300 10
    save 60 10000
    
    # 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
    rdbcompression yes
    
    # 指定本地数据库文件名,默认值为dump.rdb
    dbfilename dump.rdb
    
    # 工作目录.
    # 指定本地数据库存放目录,文件名由上一个dbfilename配置项指定
    # 
    # Also the Append Only File will be created inside this directory.
    # 
    # 注意,这里只能指定一个目录,不能指定文件名
    dir ./
    
    notify-keyspace-events Ex
    
    ################################# REPLICATION #################################
    
    

    redis 配置

    • 这里的配置我在上面已经配置了。在官网下载的是默认的配置。上面我加了一个配置notify-keyspace-events Ex 。关于Ex下表中有解释
    属性 说明
    K 键空间通知,所有通知keyspace@ 为前缀,追对key
    E 键事件通知,所有通知已keyspace@为前缀,追对event
    g DEL、EXPIRE、RENAME等类型无关的通用命令通知
    $ 字符串命令通知
    l 列表命令通知
    s 集合命令通知
    h 哈希命令通知
    z zset命令通知
    x 过期事件通知,每当key过期就会触发
    e 驱逐事件,每当有键因为maxmemory策略被清楚是触发
    A g$lshzxe总称

    命令监听

    • 完成上述配置后,我们打开redis客户端
    
    docker exec -it myredis redis-cli
    
    
    • myredis是上面安装redis容器的别名。这个读者可以自己设置
    • 因为设置了密码,连接后我们需要进行密码验证
    
    auth password
    
    
    • 然后注册监听器

    PSUBSCRIBE __keyevent@*__:expired

    • 其中expired就是我们注册类型 , @ 后面的* 表示DB。这里我们监听所有数据库的key过期事件。

    问题

    • 比如我们想监听DB0的key删除事件。我们可以这么注册PSUBSCRIBE __keyevent@0__:del

    • 127.0.0.1:6379后面没有数字说明使用的是默认的db0。

    • 切换到DB1中查看hello没有查到。且6379后面有了数据库索引值。这个时候在DB1新增hello并进行删除。看看另外一个监听DB0的监听器会不会有响应

    • 很明显,我们没有任何的通知。现在我们在DB0 中进行删除hello。看看监听器的效果
    • 这个时候在DB0 中执行删除也没有监控到信息。这里不知道为什么。还望指点

    程序监听

    • springboot程序添加依赖
    
    <!-- redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    
    
    
    @Configuration
    public class RedisConfig {
        @Bean
        public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) {
            RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
            redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
            return redisMessageListenerContainer;
        }
    }
    
    
    • 这里只是为了演示过期事件的监听。所以这里的redisConfig没有加入太多的配置。
    
    
    spring:
      redis:
        host: 39.102.60.114
        port: 6379
        database: 0
        password: password
        timeout: 1000s
    
    

    具体监听类

    
    
    @Slf4j
    @Component
    public class RedisKeyExpireListener extends KeyExpirationEventMessageListener {
    
        public RedisKeyExpireListener(RedisMessageListenerContainer listenerContainer) {
            super(listenerContainer);
        }
    
        @Override
        public void onMessage(Message message, byte[] pattern) {
            log.info("接受到消息:{},{}",message,new String(pattern));
        }
    }
    
    

    效果

    总结

    • key过期事件的监听实际使用的不是很多。因为redis大部分都是缓存作用。缓存本来就会可有可无的。所以监听意义不大。但是也可以在不少场景下使用。
    • 订单30分钟未付款自动取消场景
    • 系统定时提醒功能
  • 相关阅读:
    改变网页字体的大小
    dom小练习
    各种交换机接口及连接方法介绍【详细图文】
    网线从路由器接出来, 再接一个路由器怎么设置?
    路由器后面再接一个路由器怎么设置(二级路由)
    设置无线路由器
    交换机与集线器的区别
    Java的位运算符具体解释实例——与(&amp;)、非(~)、或(|)、异或(^)
    无法识别的属性“targetFramework”。请注意属性名称区分大写和小写。错误解决的方法
    简单工厂模式
  • 原文地址:https://www.cnblogs.com/zhangxinhua/p/14509563.html
Copyright © 2011-2022 走看看