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分鐘未付款自動取消場景
  • 系統定時提醒功能
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章