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分鍾未付款自動取消場景
  • 系統定時提醒功能


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM