keyspace通知是从redis2.8.0开始的;
通知是通过普通的pub/sub订阅发送的,所以通知并不完全可靠,客户端离线的时候的通知是收不到的;
事件有两种类型:以keyspace前缀的Key-space通知和以keyevent前缀的Key-event通知;(可以自己选择开始两种通知或者只开启其中一种)
事件通知可以通过redis.conf里的notify-keyspace-events配置或者通过CONFIG SET命令设置;
默认事件通知是禁用的,设置为空字符串可以禁用,因为事件通知也会消耗一部分cpu;
notify-keyspace-events配置的选项:(此时最新稳定版为6.2.6)
- K:Keyspace事件,以__keyspace@<db>__为前缀发布订阅消息;
- E:Keyevent事件,以__keyevent@<db>__为前缀发布订阅消息;
- g:通用命令(非特定类型),例如DEL、 EXPIRE、RENAME等类型无关命令的通知;
- $:字符串命令;
- l:List命令;
- s:Set命令;
- h:Hash命令;
- z:Sorted Set命令;
- x:过期事件;(每个key过期时通知的,过期key从内存清除时,并不一定是准确过期时间)
- e:驱逐事件;(由于释放内存驱逐key时通知)
- t:Stream命令;
- d:模块key类型事件;
- m:Key-miss事件;(当访问不存在的键时通知,不包含在A中)
- A:g$lshzxetd的别名,用“AKE”可表示所有事件通知(除了特殊的Key-miss事件)
注:至少要有K或者E才能使配置生效;Key-miss事件是redis6版本开始添加的;
不同的命令会产生一个或多个不同的通知:
- DEL:删除一个键的时候会产生一个del事件;
- RENAME:会产生两个事件,源键rename_from事件和目标键rename_to事件;
- MOVE:会产生两个事件,源键move_from事件和目标键move_to事件;
- COPY:产生copy_to事件;
- MIGRATE:如果源键被删除会生成del事件;
- RESTORE:为键生成restore事件;
- EXPIRE以及所有变体PEXPIRE, EXPIREAT, PEXPIREAT:键超时生成expire事件;(如果用命令设置负超时时间或者使用过去的时间设置则只生成del事件)
- SORT:当用STORE设置一个新键时生成sortstore事件;(如果使用了STROE项并返回空列表且该键已存在,则会删除该键并生成del事件)
- SET以及所有变体SETEX, SETNX,GETSET:生成set事件;(并且SETEX也会生成一个expire事件)
- MSET:为每个键生成一个set事件;
- SETRANGE:生成setrange事件;
- INCR, DECR, INCRBY, DECRBY:都生成incrby事件;
- INCRBYFLOAT:生成incrbyfloat事件;
- APPEND:生成append事件;
- LPUSH和LPUSHX:生成一个lpush事件,包括变参情况;
- RPUSH和RPUSHX:生成一个rpush事件,包括变参情况;
- RPOP:生成rpop事件,如果列表里最后一个值被pop由于键被删除则额外生成一个del事件;
- LPOP:生成lpop事件,如果列表里最后一个值被pop由于键被删除则额外生成一个del事件;
- LINSERT:生成linsert事件;
- LSET:生成lset事件;
- LREM:生成lrem事件,如果结果列表为空且键被删除则会额外生成一个del事件;
- LTRIM:生成ltrim事件,如果结果列表为空且键被删除则会额外生成一个del事件;
- RPOPLPUSH和BRPOPLPUSH:生成rpop事件和lpush事件,并且lpush一定在rpop事件之后,如果结果列表长度为0且键被删除则额外生成del事件;
- LMOVE和BLMOVE:生成一个lpop/rpop事件(取决于wherefrom参数)和一个lpush/rpush事件(取决于whereto参数),并且
lpush
/rpush一定在lpop
/rpop事件之后,
如果结果列表长度为0且键被删除则额外生成del事件; - HSET, HSETNX, HMSET:都生成一个hset事件;
- HINCRBY:生成hincrby事件;
- HINCRBYFLOAT:生成hincrbyfloat事件;
- HDEL:生成一个hdel事件,如果哈希值为空并且键被删除则额外生成一个del事件;
- SADD:生成一个sadd事件,包括变参情况;
- SREM:生成一个srem事件,如果结果集为空并且键被删除则额外生成一个del事件;
- SMOVE:生成两个事件,源键srem事件,目标键sadd事件;
- SPOP: 生成spop事件,如果结果集为空并且键被删除则额外生成一个del事件;
- SINTERSTORE, SUNIONSTORE, SDIFFSTORE:分别生成sinterstore, sunionstore, sdiffstore事件,特殊情况下结果集为空并且存储结果集的键已存在,则会删除该键并生成一个del事件;
- ZINCR:生成zincr事件;
- ZADD:生成一个zadd事件,即使添加了多个值;
- ZREM:生成一个zrem事件,即使删除了多个值,如果结果集为空且键已经生成,则生成额外del事件;
- ZREMBYSCORE:生成一个zrembyscore事件,如果结果集为空且键已经生成,则生成额外del事件;
- ZREMBYRANK:生成一个zrembyrank事件,如果结果集为空且键已经生成,则生成额外del事件;
- ZDIFFSTORE, ZINTERSTORE, ZUNIONSTORE:分别生成zdiffstore, zinterstore和zunionstore事件,特殊情况下当结果集为空并且用于存储结果的键已经存在则会删除键并生成del事件;
- XADD:生成xadd事件,跟MAXLEN参数一起使用后面可能还会有一个xtrim事件;
- XDEL:生成一个xdel事件,即使删除了多个元素;
- XGROUP CREATE:生成xgroup-create事件;
- XGROUP CREATECONSUMER:生成xgroup-createconsumer事件;
- XGROUP DELCONSUMER:生成xgroup-delconsumer事件;
- XGROUP DESTROY:生成xgroup-destroy事件;
- XGROUP SETID:生成xgroup-setid事件;
- XSETID:生成xsetid事件;
- XTRIM:生成xtrim事件;
- PERSIST:如果键的超时时间被移除则生成persist事件;
- 每次由于过期从数据库中删除关联生存时间的键时都会生成一个expired事件;
- 每当由于maxmemory策略释放内存从数据库中驱逐一个键时都会生成一个evicted事件;
注:必须真正修改了目标键才能有通知,例如del一个不存在的key不会产生通知、get一个key也不通知,keys也不通知;
关于过期事件,由于键过期通过两种方式发现:1.通过命令访问键发现键过期,2.通过后台系统逐步查询过期键;并且expired事件的通知是在redis删除过期键的时候通知的,所以并不是键的存活时间刚好到0时通知expired事件;
关于集群事件,由于集群节点只会生成关于自身的key事件,这与集群中普通的pub/sub有所不同,事件通知不会发送其他节点,事件通知是基于特定节点的,所以客户端需要请阅每个节点以接收集群所有key事件;
参考:Redis Keyspace Notifications – Redis