查看是否开启键空间监听

1
CONFIG GET notify-keyspace-events

设置键空间监听

只要设置了会立即生效,无需重启,在windows中,奇怪的是设置redis.conf不生效。

1
CONFIG SET notify-keyspace-events Ex

测试添加带有效期的键

1
SET testkey "hello" EX 5

监听键失效事件

1
psubscribe __keyevent@?__:expired

ThinkPHP6.0失效监听

以下操作不会占用大内存,因为监听事件取出的数据,处理完毕后会立即释放,一定要避免下面这种方式。

1
2
3
4
$data = [];  // 全局变量
$redis->psubscribe(..., function(...) use (&$data) {
$data[] = $msg; // 无限累积!
});

主要业务是取出集合中数据,拿到数据进行工单创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php

namespace app\common\command;

use think\console\Command;
use think\console\Input;
use think\console\Output

class WatchRedisExpired extends Command
{
protected function configure()
{
$this->setName('watch:redis_expired');
}

protected function execute(Input $input, Output $output)
{
// $output->info("===========BEGIN-2026===========");

$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
// 设置永不超时
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
set_time_limit(0);

while (true) {
try {
$redis->psubscribe(['__keyevent@0__:expired'], function ($redis, $pattern, $chan, $msg) {
echo "键过期事件: $chan -> $msg\n";
// 处理业务逻辑...
});
} catch (Exception $e) {
// 记录错误日志
error_log('Redis subscription error: ' . $e->getMessage());
// 等待一段时间后重连
sleep(5);
// 重新连接 Redis
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
}
}
}
}

失效键无法获取值解决方法

1.集合不设置有效期

2.在扫单时,只需判断集合是否存在

3.不存在则创建一个触发键,设置有效时间

4.当时间过期时,订阅监听之际,取出集合中所有数据

5.删除该集合

6.拿到数据,就开始读取tms运单数据、创建工单,并将扫单表标记与已同步

远程redis连接

redis-cli.exe -h 47.112.7.182 -p 6379

redis-cli -h 127.0.0.1 -p 6379 -a password

注意事项

  1. Redis 6.*版本以上,订阅有expire事件,也就是某个键在失效前可以在回调中取到,以下的版本只能使用expired。
  2. 在回调中,整个线程是封闭阻塞的,无论是读取哪个库号,都无法获取其他键的键值,必须在里面重新创建一个redis,但是还要解决连接中断的问题。