背景

最近需要涉及一个定时通知的业务,之前的办法是采用定时任务,每秒查询一次。后来了解到Redis的键空间通知机制,其中的过期通知,和业务非常贴合。

键空间通知

下面是Redis中文文档的介绍

键空间通知使得客户端可以通过订阅频道或模式, 来接收那些以某种方式改动了 Redis 数据集的事件。事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发, 因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下, 直接使用键空间通知功能。

事件类型

对于每个修改数据库的操作,键空间通知都会发送两种不同类型的事件。

比如说,对 0 号数据库的键 mykey 执行 DEL 命令时, 系统将分发两条消息, 相当于执行以下两个 PUBLISH 命令:

PUBLISH keyspace@0:mykey del

PUBLISH keyevent@0:del mykey

订阅第一个频道 keyspace@0:mykey 可以接收 0 号数据库中所有修改键 mykey 的事件, 而订阅第二个频道 keyevent@0:del 则可以接收 0 号数据库中所有执行 del 命令的键。

以 keyspace 为前缀的频道被称为键空间通知(key-space notification), 而以 keyevent 为前缀的频道则被称为键事件通知(key-event notification)。

当 del mykey 命令执行时:

键空间频道的订阅者将接收到被执行的事件的名字,在这个例子中,就是 del 。

键事件频道的订阅者将接收到被执行事件的键的名字,在这个例子中,就是 mykey 。

配置

另外开启Redis的键空间通知,需要修改配置文件。查看默认的配置你会发现“notify-keyspace-events”字段,且为空,表示不开启。总共有以下这几种设置:

字符 发送的通知

K 键空间通知,所有通知以 keyspace@ 为前缀

E 键事件通知,所有通知以 keyevent@ 为前缀

g DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知

$ 字符串命令的通知

l 列表命令的通知

s 集合命令的通知

h 哈希命令的通知

z 有序集合命令的通知

x 过期事件:每当有过期键被删除时发送

e 驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送

A 参数 g$lshzxe 的别名

其中必选K或E,比如开启过期通知,“Ex”或者"Kx",两者的区别在于事件名不同,不过我们可以采用模糊订阅的方式,如果开启所有事件则是“AKE”

订阅

订阅的表达式:

  1. __key空间/事件@数据库id__:对象
  2. 比如:
  3. __keyspace@0__:mykey 订阅数据库0 mykey的相关事件
  4. __keyevent@0__:del 订阅数据库0中的 del事件
  5. 两者的区别在于,一个是符合key就通知,一个是符合事件就通知。
  6. 对于key在哪个数据库,我们很难知道,那么可以使用"*"匹配所有:
  7. __key*__:*

PHP实现

在PHP里可以使用PHPRedis扩展,注意事项取消连接超时

  1. $redis = new Redis();
  2. $redis->connect("127.0.0.1");
  3. $redis->setOption(\Redis::OPT_READ_TIMEOUT,-1);
  4. $redis->psubscribe(['__key*__:*'], 'psCallback');
  5. function psCallback($redis, $pattern, $chan, $msg)
  6. {
  7. echo "Pattern: $pattern\n"; //订阅的模式
  8. echo "Channel: $chan\n"; //符合模式的频道
  9. echo "Payload: $msg\n\n"; //订阅的key
  10. }

后台运行

Linux下,可以使用nohup php file.php 在后台持续运行

redis过期回调以及键空间通知的更多相关文章

  1. python中的Redis键空间通知(过期回调)

    介绍 Redis是一个内存数据结构存储库,用于缓存,高速数据摄取,处理消息队列,分布式锁定等等. 使用Redis优于其他内存存储的优点是Redis提供持久性和数据结构,如列表,集合,有序集和散列. 在 ...

  2. 利用Redis keyspace notification(键空间通知)实现过期提醒

    一.序言: 本文所说的定时任务或者说计划任务并不是很多人想象中的那样,比如说每天凌晨三点自动运行起来跑一个脚本.这种都已经烂大街了,随便一个 Crontab 就能搞定了. 这里所说的定时任务可以说是计 ...

  3. redis键空间通知(keyspace notification)

    一.需求 在redis中,设置好key和生存时间之后,希望key过期被删除时能够及时的发送一个通知告诉我key,以便我做后续的一些操作. 二.环境 系统:windows10 php:7.1 redis ...

  4. Redis键空间通知(keyspace notification),事件订阅

      Redis键空间通知(keyspace notification),事件订阅   应用场景:有效期优惠券.24小时内支付.下单有效事件等等. 功能概览 键空间通知使得客户端可以通过订阅频道或模式, ...

  5. redis中键空间通知

    通过redis的键空间通知,当redis删除过期key的时候,及时更新mongodb数据库中user的状态 var Redis = require('ioredis'); var redis = ne ...

  6. Redis 键空间通知

    [Redis 键空间通知] 键空间通知使得客户端可以通过订阅频道或模式, 来接收那些以某种方式改动了 Redis 数据集的事件. 以下是一些键空间通知发送的事件的例子: 所有修改键的命令. 所有接收到 ...

  7. Redis源码解析:09redis数据库实现(键值对操作、键超时功能、键空间通知)

    本章对Redis服务器的数据库实现进行介绍,说明Redis数据库相关操作的实现,包括数据库中键值对的添加.删除.查看.更新等操作的实现:客户端切换数据库的实现:键超时相关功能的实现.键空间事件通知等. ...

  8. redis 过期回调通知

    redis 过期回调通知 背景 在使用redis的过程中,有时我们会遇到这种情景,当key过期的时候,我们需要去重新做一些操作,比如重新生成value等.之前,一直用的是添加一个celery定时任务, ...

  9. KeySpaceNotification 键空间通知

    KeySpaceNotification 键空间通知 1.Redis键淘汰机制简介 在Redis中,内存的大小是有限的,所以为了防止内存饱和,需要实现某种键淘汰策略.主要有两种方法,一种是当Redis ...

随机推荐

  1. 【java】Java泛型

    一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 1 public class GenericTest { 2 3 public static void main(Stri ...

  2. Docker学习笔记 ---存储与管理

    存储管理 为了适应不同平台不同场景的存储需求,Docker提供了各种基于不同文件系统实现的存储驱动来管理实际的镜像文件 元数据管理 镜像在设计上将元数据和文件存储完全隔离.Docker管理元数据采用的 ...

  3. mysql_install_db 运行结果

    # /usr/local/mysql/scripts/mysql_install_db \ > --defaults-file=/etc/my.cnf \ > --basedir=/usr ...

  4. Java Nashorn--Part 1

    伴随 Java 8 的发布,Oracle 也一同发布了 Nashorn,它是在 Java 虚拟机上运行 Javascript 语言的一个引擎.Nashorn 的设计是为了替换最初的运行在 JVM 上的 ...

  5. Android数据库安全解决方案,使用SQLCipher

    源码:http://files.cnblogs.com/android100/SQLCipherTest.rar 我们都知道,Android系统内置了SQLite数据库,并且提供了一整套的API用于对 ...

  6. postman发送post数据到node.js中

    使用get请求我们很容易的来利用postman来发送数据,但是今天的express在使用postman进行post请求的时候,竟然解析的body是空对象.在网上找了一下果然有解决方法,如下: 因为是P ...

  7. WPF 项目升级错误

    今天将一个 WPF 项目从 .NET 4.0 升级至 .NET 4.6.1 时,出现一个错误: 错误        未知的生成错误"程序集"PresentationFramewor ...

  8. Linux学习笔记--SSH免password登录

    须要实现的效果: 有两台server:"192.168.201.236" 和 "192.168.201.237" 须要实现:在server"192.1 ...

  9. jmeter经验---java 追加写入代码一例

    最近最项目参数化的时候用到,场景是这样的,需要测试A和B两个接口,其中B接口传入的参数必须是传递给A接口过的,所以整理一个思路就是: 1. 正常调用A接口,但是将传递给A接口的参数保存到文本里,此处要 ...

  10. JSP中四种传递参数中文乱码问题

    查看来源:http://blog.csdn.net/hackerain/article/details/6776083