加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Redis的键空间通知详解

发布时间:2020-12-16 04:43:38 所属栏目:安全 来源:网络整理
导读:《Redis的键空间通知详解》要点: 本文介绍了Redis的键空间通知详解,希望对您有用。如果有疑问,可以联系我们。 重要: 键空间通知(Keyspace Notification)是一个从Redis 2.8.0版本开始可用的功能. 一、功能概述 键空间通知使得客户端能够订阅Pub/Sub(发布/

《Redis的键空间通知详解》要点:
本文介绍了Redis的键空间通知详解,希望对您有用。如果有疑问,可以联系我们。

重要: 键空间通知(Keyspace Notification)是一个从Redis 2.8.0版本开始可用的功能.

一、功能概述

键空间通知使得客户端能够订阅Pub/Sub(发布/订阅)频道,这样客户端便能接收到以某种方式影响Redis数据集的事件.

可能接收到的事件示例,如下所示:

  • 所有影响到一个给定键的命令.

  • 所有接收到一个LPUSH命令的键.

  • 所有数据库-0中的键全都过期.

Redis会使用标准的Pub/Sub层来传递事件,因此,实现了Pub/Sub功能的客户端能够直接使用这个功能,而不用进行任何修改.

因为Redis的Pub/Sub功能当前是“触发后不管(Fire and Forget)”的,所以如果你的应用程序对事件有着可靠通知的要求,那么它就不能使用Redis的键空间通知功能.也便是说,如果你的Pub/Sub客户端断开连接,然后再重新连接,那么在客户端断开连接的期间内传递的所有事件都会丢失.

Redis将来会改善事件传递的可靠性,但是很有可能会以一种更加常规的方式来办理这个问题,有可能会提高Pub/Sub功能自身的可靠性,也有可能会通过Lua脚本拦截Pub/Sub消息,然后再执行某些操作(例如,将事件存入一个列表之中).

二、事件类型

每次执行会影响到Redis数据空间的操作时,键空间通知就会发送两个不同类型的事件.以DEL操作为例,当删除数据库-0中的一个名为mykey的键时,将会触发Redis传递两条消息,完全等价于下面两条PUBLISH命令:

PUBLISH __keyspace@0__:mykey del

PUBLISH __keyevent@0__:del mykey

很容易看出,如何让一个频道能够监听mykey键相关的所有事件,以及如何让另一个频道能够获取del操作所影响的所有的键的有关信息.

第一种类型的事件,频道名称的前缀为keyspace,这种事件被称为键空间通知;而第二种类型的事件,频道名称的前缀为keyevent,这种事件被称为键事件通知.

在上面的示例中,Redis会针对mykey键产生一个del事件.期间发生的事情,如下所示:

  • 键空间频道会接收到一条消息,它的内容是事件名称.

  • 键事件频道会接收到一条消息,它的内容是键的名称.

为了使Redis只传递我们感兴趣的事件子集,因此只可以使用一种类型的通知.

三、配置办法

在默认情况下,键空间的事件通知功能是禁用的,因为这个功能会消耗一些CPU性能,虽然几乎感觉不到性能消耗.有两种办法可以启用通知功能:修改redis.conf文件的notify-keyspace-events参数,或者使用CONFIG SET命令.

将上述参数设置为空字符串,就能禁用通知功能.如果想要启用这个功能,那么就要将上述参数设置为一个空字符串,这个字符串由多个字符组成,其中的每个字符都具有特殊含义,如下表所示:

字符含义
K键空间(Keyspace)事件,通过__keyspace@<db>__前缀的频道发布.
E键事件(Keyevent)事件,通过__keyevent@<db>__前缀的频道发布.
g通用的命令(不特定类型),例如:DEL、EXPIRE、RENAME,等等.
$字符串(String)相关的命令.
l列表(List)相关的命令.
s集合(Set)相关的命令.
h哈希(Hash)相关的命令.
z有序集合相关的命令.
x过期事件(每当一个键过期时,便会产生这种事件).
e内存回收事件(当达到最大内存,然后回收某个键的内存时,便会产生这种事件).
Ag$lshzxe的别名.因此,“AKE”字符串可以表示所有的事件.

配置字符串至少应当包括KE字符.否则,即使这个字符串包括其他任何字符,Redis也不会传递任何事件.

例如,若只想针对列表(List)启用键空间事件,则配置参数必需设置为Kl,以此类推.

KEA字符串可用于启用每种可能的事件.

四、不同命令产生的事件

不同的命令会产生不同类型的事件,如以下列表所示:

  • DEL

    这个命令会为每个被删除的键产生一个del事件.

  • RENAME

    这个命令会产生两个事件,一个为原始键产生的rename_from事件,以及一个为目标键产生的rename_to事件.

  • EXPIRE

    当为某个键设置过期时间时,这个命令便会产生一个expire事件;或者,每当为某个待删除的键设置一个过期结果时,这个命令便会产生一个expired事件(请参考EXPIRE命令的相关文档).

  • SORT

    当使用STORE选项来设置一个新键时,这个命令便会产生一个sortstore事件.如果结果列表为空,并且使用了STORE选项,并且已经存在一个同名的键,那么Redis便会删除这个已有的键,在这种情况下,这个命令还会产生一个del事件.

  • SET

    这个命令,以及它的所有变种(SETEXSETNXGETSET)命令,都会产生set事件.除此之外,SETEX命令还会产生一个expire事件.

  • MSET

    这个命令会为每个键单独产生一个set事件.

  • SETRANGE

    这个命令会产生一个setrange事件.

  • INCRDECRINCRBYDECRBY

    这些命令都会产生incrby事件.

  • INCRBYFLOAT

    这个命令会产生一个incrbyfloat事件.

  • APPEND

    这个命令会产生一个append事件.

  • LPUSHLPUSHX

    这些命令都会产生一个lpush事件,即使有多个输入元素时,也是如此.

  • RPUSHRPUSHX

    这些命令都会产生一个rpush事件,也是如此.

  • RPOP

    这个命令会产生一个rpop事件.另外,如果从列表中弹出最后一个元素,那么这个列表对应的键就会被删除,此时还会产生一个del事件.

  • LPOP

    这个命令会产生一个lpop事件.另外,此时还会产生一个del事件.

  • LINSERT

    这个命令会产生一个linsert事件.

  • LSET

    这个命令会产生一个lset事件.

  • LREM

    这个命令会产生一个lrem事件.另外,如果运行这个命令之后,列表变为空表,那么便会删除这个列表对应的键,此时还会产生一个del事件.

  • LTRIM

    这个命令会产生一个ltrim事件.另外,此时还会产生一个del事件.

  • RPOPLPUSHBRPOPLPUSH

    这两个命令都会产生一个rpop事件和lpush事件.这两个事件的产生顺序都是固定不变的,先产生rpop事件,然后再产生lpush事件.另外,如果运行这两个命令之后,此时还会产生一个del事件.

  • HSETHSETNXHMSET

    这些命令都会产生一个hset事件.

  • HINCRBY

    这个命令会产生一个hincrby事件.

  • HINCRBYFLOAT

    这个命令会产生一个hincrbyfloat事件.

  • HDEL

    这个命令会产生一个hdel事件.如果运行这个命令之后,哈希变为空,那么便会删除这个哈希对应的键,此时还会产生一个del事件.

  • SADD

    这个命令会产生一个sadd事件,也是如此.

  • SREM

    这个命令会产生一个srem事件.如果运行这个命令之后,集合变为空,那么便会删除这个集合对应的键,此时还会产生一个del事件.

  • SMOVE

    这个命令会为原始键产生一个srem事件,然后为目标键产生一个sadd事件.

  • SPOP

    这个命令会产生一个spop事件.如果运行这个命令之后,此时还会产生一个del事件.

  • SINTERSTORESUNIONSTORESDIFFSTORE

    这些命令会分别产生sinterstoresunionostoresdiffstore事件.在特殊情况下,如果运行这些命令得到的集合为空,并且用于存储结果的键已经存在,那么这个键将会被删除,然后还会产生一个del事件.

  • ZINCRBY

    这个命令会产生一个zincr事件.

  • ZADD

    这个命令会产生一个zadd事件,也是如此.

  • ZREM

    这个命令会产生一个zrem事件,即使必要删除多个元素时,也是如此.如果运行这个命令之后,有序集合变为空,那么便会删除这个有序集合对应的键,此时还会产生一个del事件.

  • ZREMRANGEBYSCORE

    这个命令会产生一个zrembyscore事件.如果运行这个命令之后,此时还会产生一个del事件.

  • ZREMRANGEBYRANK

    这个命令会产生一个zrembyrank事件.如果运行这个命令之后,此时还会产生一个del事件.

  • ZINTERSTOREZUNIONSTORE

    这两个命令会分别产生zinterstorezunionstore事件.在特殊情况下,如果运行这些命令得到的有序集合为空,然后还会产生一个del事件.

  • 每当一个键因为过期而被删除时,便会产生一个expired事件.

  • 每当一个键因为maxmemory策略而被删除,以便于回收内存时,便会产生一个evicted事件.

重要: 所有的命令只有当目标键真的被修改时,才会产生事件.例如,当使用SREM命令删除一个集合中并不存在的元素时,实际上没有改变这个键的对应值,所以也就不会产生任何事件.

如果还在怀疑一个给定命令的事件是如何产生的,那么最简单的办法便是自己验证一下.在Shell终端中运行以下命令:

redis-cli config set notify-keyspace-events KEA

redis-cli --csv psubscribe '__key*__:*'

此时,Redis客户端便进入频道监听状态,如下图所示:

Redis的键空间通知详解

此时,在另一个Shell终端中使用redis-cli命令向Redis服务器发送命令:

redis-cli set foo hello

然后,便能在前一个Shell终端中观察到以下输出信息:

Redis的键空间通知详解

五、过期事件的产生时机

Redis会通过以下两种方式使得具有生存时间的键过期:

  • 当使用某个命令拜访这个键,然后发现这个键已经过期.

  • 通过一个后台系统在后台渐进地查找已经过期的键,这样还能够收集从未被拜访过的键.

当通过上述两种方式之一拜访某个键,并且发现这个键已经过期时,Redis就会产生expired事件.结论便是,Redis服务器并不能保证每当键的生存时间降低至0的时候就能立刻产生expired事件.

如果总是没有任何命令拜访这个已经过期的键,并且带有生存时间(TTL:Time To Live)的键非常多的话,那么就很有可能感觉到键的生存时间降低至0和产生expired事件之间具有明显的延时.

基本上,只有当Redis服务器删除已经过期的键时才会产生expired事件,而不是当键的生存时间在理论上降低至0的时候.

六、键空间通知示例

接下来,会通过实际操作,简单讲解Redis键空间通知的使用办法.

1. 安装Redis

依照《在CentOS上安装Redis缓存系统》安装Redis服务器.

2. 启用键空间通知功能

在Shell终端(此处取名为终端-1)中运行以下命令,进入Redis客户端的命令行:

redis-cli

然后在终端-1的Redis客户端的命令行中运行以下命令,启用键空间通知功能的所有通知:

config set notify-keyspace-events KEA

3. 订阅键空间通知和键事件通知

打开一个新的Shell终端(此处取名为终端-2),在其中运行以下命令,进入telnet命令行:

telnet localhost 6379

在终端-2的telnet命令行中,运行以下命令:

psubscribe __key*__:*

上述命令会订阅键空间通知键事件通知,当对某个键执行修改命令时,终端-2便会同时收到上述两种通知.

4. 设置键的值

在终端-1的Redis客户端的命令行中运行以下命令,设置一个键的值:

set mykey hello

5. 观察结果

此时,便能在终端-2观察到两条通知消息,如下图所示:

Redis的键空间通知详解

上图的上半部分就是键空间通知,下半部分就是键事件通知.

《Redis的键空间通知详解》是否对您有启发,欢迎查看更多与《Redis的键空间通知详解》相关教程,学精学透。编程之家PHP学院为您提供精彩教程。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读