diff --git a/content/commands/info/index.md b/content/commands/info/index.md index 6b690858c..3590597ae 100644 --- a/content/commands/info/index.md +++ b/content/commands/info/index.md @@ -313,6 +313,7 @@ Here is the meaning of all fields in the **stats** section: * `sync_full`: The number of full resyncs with replicas * `sync_partial_ok`: The number of accepted partial resync requests * `sync_partial_err`: The number of denied partial resync requests +* `expired_hash_fields`: The number of hash fields expiration events * `expired_keys`: Total number of key expiration events * `expired_stale_perc`: The percentage of keys probably expired * `expired_time_cap_reached_count`: The count of times that active expiry cycles have stopped early @@ -492,7 +493,7 @@ The statistics are the number of keys, and the number of keys with an expiration For each database, the following line is added: -* `dbXXX`: `keys=XXX,expires=XXX` +* `dbXXX`: `keys=XXX,expires=XXX,avg_ttl=XXX,hashes_with_expiry_fields=XXX` The **debug** section contains experimental metrics, which might change or get removed in future versions. It won't be included when `INFO` or `INFO ALL` are called, and it is returned only when `INFO DEBUG` is used. diff --git a/content/develop/use/keyspace-notifications.md b/content/develop/use/keyspace-notifications.md index bbf696b48..e6f474fd0 100644 --- a/content/develop/use/keyspace-notifications.md +++ b/content/develop/use/keyspace-notifications.md @@ -96,56 +96,57 @@ You can use the string `KEA` to enable most types of events. ### Events generated by different commands Different commands generate different kind of events according to the following list. - -* [`DEL`]({{< relref "/commands/del" >}}) generates a `del` event for every deleted key. -* [`RENAME`]({{< relref "/commands/rename" >}}) generates two events, a `rename_from` event for the source key, and a `rename_to` event for the destination key. -* [`MOVE`]({{< relref "/commands/move" >}}) generates two events, a `move_from` event for the source key, and a `move_to` event for the destination key. +* [`APPEND`]({{< relref "/commands/append" >}}) generates an `append` event. * [`COPY`]({{< relref "/commands/copy" >}}) generates a `copy_to` event. -* [`MIGRATE`]({{< relref "/commands/migrate" >}}) generates a `del` event if the source key is removed. -* [`RESTORE`]({{< relref "/commands/restore" >}}) generates a `restore` event for the key. +* [`DEL`]({{< relref "/commands/del" >}}) generates a `del` event for every deleted key. * [`EXPIRE`]({{< relref "/commands/expire" >}}) and all its variants ([`PEXPIRE`]({{< relref "/commands/pexpire" >}}), [`EXPIREAT`]({{< relref "/commands/expireat" >}}), [`PEXPIREAT`]({{< relref "/commands/pexpireat" >}})) generate an `expire` event when called with a positive timeout (or a future timestamp). Note that when these commands are called with a negative timeout value or timestamp in the past, the key is deleted and only a `del` event is generated instead. -* [`SORT`]({{< relref "/commands/sort" >}}) generates a `sortstore` event when `STORE` is used to set a new key. If the resulting list is empty, and the `STORE` option is used, and there was already an existing key with that name, the result is that the key is deleted, so a `del` event is generated in this condition. -* [`SET`]({{< relref "/commands/set" >}}) and all its variants ([`SETEX`]({{< relref "/commands/setex" >}}), [`SETNX`]({{< relref "/commands/setnx" >}}),[`GETSET`]({{< relref "/commands/getset" >}})) generate `set` events. However [`SETEX`]({{< relref "/commands/setex" >}}) will also generate an `expire` events. -* [`MSET`]({{< relref "/commands/mset" >}}) generates a separate `set` event for every key. -* [`SETRANGE`]({{< relref "/commands/setrange" >}}) generates a `setrange` event. -* [`INCR`]({{< relref "/commands/incr" >}}), [`DECR`]({{< relref "/commands/decr" >}}), [`INCRBY`]({{< relref "/commands/incrby" >}}), [`DECRBY`]({{< relref "/commands/decrby" >}}) commands all generate `incrby` events. +* [`HDEL`]({{< relref "/commands/hdel" >}}) generates a single `hdel` event, and an additional `del` event if the resulting hash is empty and the key is removed. +* [`HEXPIRE`]({{< relref "/commands/hexpire" >}}) and all its variants ([`HEXPIREAT`]({{< relref "/commands/hpexpireat" >}}), [`HPEXPIRE`]({{< relref "/commands/hpexpire" >}}), [`HPEXPIREAT`]({{< relref "/commands/hpexpireat" >}})) generate `hexpire` events. +* [`HINCRBYFLOAT`]({{< relref "/commands/hincrbyfloat" >}}) generates an `hincrbyfloat` event. +* [`HINCRBY`]({{< relref "/commands/hincrby" >}}) generates an `hincrby` event. +* [`HPERSIST`]({{ < relref "/commands/hpersist" >}}) generates a `hpersist` event. +* [`HSET`]({{< relref "/commands/hset" >}}), [`HSETNX`]({{< relref "/commands/hsetnx" >}}) and [`HMSET`]({{< relref "/commands/hmset" >}}) all generate a single `hset` event. * [`INCRBYFLOAT`]({{< relref "/commands/incrbyfloat" >}}) generates an `incrbyfloat` events. -* [`APPEND`]({{< relref "/commands/append" >}}) generates an `append` event. -* [`LPUSH`]({{< relref "/commands/lpush" >}}) and [`LPUSHX`]({{< relref "/commands/lpushx" >}}) generates a single `lpush` event, even in the variadic case. -* [`RPUSH`]({{< relref "/commands/rpush" >}}) and [`RPUSHX`]({{< relref "/commands/rpushx" >}}) generates a single `rpush` event, even in the variadic case. -* [`RPOP`]({{< relref "/commands/rpop" >}}) generates an `rpop` event. Additionally a `del` event is generated if the key is removed because the last element from the list was popped. -* [`LPOP`]({{< relref "/commands/lpop" >}}) generates an `lpop` event. Additionally a `del` event is generated if the key is removed because the last element from the list was popped. +* [`INCR`]({{< relref "/commands/incr" >}}), [`DECR`]({{< relref "/commands/decr" >}}), [`INCRBY`]({{< relref "/commands/incrby" >}}), [`DECRBY`]({{< relref "/commands/decrby" >}}) commands all generate `incrby` events. * [`LINSERT`]({{< relref "/commands/linsert" >}}) generates an `linsert` event. -* [`LSET`]({{< relref "/commands/lset" >}}) generates an `lset` event. +* [`LMOVE`]({{< relref "/commands/lmove" >}}) and [`BLMOVE`]({{< relref "/commands/blmove" >}}) generate an `lpop`/`rpop` event (depending on the wherefrom argument) and an `lpush`/`rpush` event (depending on the whereto argument). In both cases the order is guaranteed (the `lpush`/`rpush` event will always be delivered after the `lpop`/`rpop` event). Additionally a `del` event will be generated if the resulting list is zero length and the key is removed. +* [`LPOP`]({{< relref "/commands/lpop" >}}) generates an `lpop` event. Additionally a `del` event is generated if the key is removed because the last element from the list was popped. +* [`LPUSH`]({{< relref "/commands/lpush" >}}) and [`LPUSHX`]({{< relref "/commands/lpushx" >}}) generates a single `lpush` event, even in the variadic case. * [`LREM`]({{< relref "/commands/lrem" >}}) generates an `lrem` event, and additionally a `del` event if the resulting list is empty and the key is removed. +* [`LSET`]({{< relref "/commands/lset" >}}) generates an `lset` event. * [`LTRIM`]({{< relref "/commands/ltrim" >}}) generates an `ltrim` event, and additionally a `del` event if the resulting list is empty and the key is removed. +* [`MIGRATE`]({{< relref "/commands/migrate" >}}) generates a `del` event if the source key is removed. +* [`MOVE`]({{< relref "/commands/move" >}}) generates two events, a `move_from` event for the source key, and a `move_to` event for the destination key. +* [`MSET`]({{< relref "/commands/mset" >}}) generates a separate `set` event for every key. +* [`PERSIST`]({{< relref "/commands/persist" >}}) generates a `persist` event if the expiry time associated with key has been successfully deleted. +* [`RENAME`]({{< relref "/commands/rename" >}}) generates two events, a `rename_from` event for the source key, and a `rename_to` event for the destination key. +* [`RESTORE`]({{< relref "/commands/restore" >}}) generates a `restore` event for the key. * [`RPOPLPUSH`]({{< relref "/commands/rpoplpush" >}}) and [`BRPOPLPUSH`]({{< relref "/commands/brpoplpush" >}}) generate an `rpop` event and an `lpush` event. In both cases the order is guaranteed (the `lpush` event will always be delivered after the `rpop` event). Additionally a `del` event will be generated if the resulting list is zero length and the key is removed. -* [`LMOVE`]({{< relref "/commands/lmove" >}}) and [`BLMOVE`]({{< relref "/commands/blmove" >}}) generate an `lpop`/`rpop` event (depending on the wherefrom argument) and an `lpush`/`rpush` event (depending on the whereto argument). In both cases the order is guaranteed (the `lpush`/`rpush` event will always be delivered after the `lpop`/`rpop` event). Additionally a `del` event will be generated if the resulting list is zero length and the key is removed. -* [`HSET`]({{< relref "/commands/hset" >}}), [`HSETNX`]({{< relref "/commands/hsetnx" >}}) and [`HMSET`]({{< relref "/commands/hmset" >}}) all generate a single `hset` event. -* [`HINCRBY`]({{< relref "/commands/hincrby" >}}) generates an `hincrby` event. -* [`HINCRBYFLOAT`]({{< relref "/commands/hincrbyfloat" >}}) generates an `hincrbyfloat` event. -* [`HDEL`]({{< relref "/commands/hdel" >}}) generates a single `hdel` event, and an additional `del` event if the resulting hash is empty and the key is removed. +* [`RPOP`]({{< relref "/commands/rpop" >}}) generates an `rpop` event. Additionally a `del` event is generated if the key is removed because the last element from the list was popped. +* [`RPUSH`]({{< relref "/commands/rpush" >}}) and [`RPUSHX`]({{< relref "/commands/rpushx" >}}) generates a single `rpush` event, even in the variadic case. * [`SADD`]({{< relref "/commands/sadd" >}}) generates a single `sadd` event, even in the variadic case. -* [`SREM`]({{< relref "/commands/srem" >}}) generates a single `srem` event, and an additional `del` event if the resulting set is empty and the key is removed. +* [`SETRANGE`]({{< relref "/commands/setrange" >}}) generates a `setrange` event. +* [`SET`]({{< relref "/commands/set" >}}) and all its variants ([`SETEX`]({{< relref "/commands/setex" >}}), [`SETNX`]({{< relref "/commands/setnx" >}}),[`GETSET`]({{< relref "/commands/getset" >}})) generate `set` events. However [`SETEX`]({{< relref "/commands/setex" >}}) will also generate an `expire` events. +* [`SINTERSTORE`]({{< relref "/commands/sinterstore" >}}), [`SUNIONSTORE`]({{< relref "/commands/sunionstore" >}}), [`SDIFFSTORE`]({{< relref "/commands/sdiffstore" >}}) generate `sinterstore`, `sunionstore`, `sdiffstore` events respectively. In the special case the resulting set is empty, and the key where the result is stored already exists, a `del` event is generated since the key is removed. * [`SMOVE`]({{< relref "/commands/smove" >}}) generates an `srem` event for the source key, and an `sadd` event for the destination key. +* [`SORT`]({{< relref "/commands/sort" >}}) generates a `sortstore` event when `STORE` is used to set a new key. If the resulting list is empty, and the `STORE` option is used, and there was already an existing key with that name, the result is that the key is deleted, so a `del` event is generated in this condition. * [`SPOP`]({{< relref "/commands/spop" >}}) generates an `spop` event, and an additional `del` event if the resulting set is empty and the key is removed. -* [`SINTERSTORE`]({{< relref "/commands/sinterstore" >}}), [`SUNIONSTORE`]({{< relref "/commands/sunionstore" >}}), [`SDIFFSTORE`]({{< relref "/commands/sdiffstore" >}}) generate `sinterstore`, `sunionstore`, `sdiffstore` events respectively. In the special case the resulting set is empty, and the key where the result is stored already exists, a `del` event is generated since the key is removed. -* `ZINCR` generates a `zincr` event. -* [`ZADD`]({{< relref "/commands/zadd" >}}) generates a single `zadd` event even when multiple elements are added. -* [`ZREM`]({{< relref "/commands/zrem" >}}) generates a single `zrem` event even when multiple elements are deleted. When the resulting sorted set is empty and the key is generated, an additional `del` event is generated. -* `ZREMBYSCORE` generates a single `zrembyscore` event. When the resulting sorted set is empty and the key is generated, an additional `del` event is generated. -* `ZREMBYRANK` generates a single `zrembyrank` event. When the resulting sorted set is empty and the key is generated, an additional `del` event is generated. -* [`ZDIFFSTORE`]({{< relref "/commands/zdiffstore" >}}), [`ZINTERSTORE`]({{< relref "/commands/zinterstore" >}}) and [`ZUNIONSTORE`]({{< relref "/commands/zunionstore" >}}) respectively generate `zdiffstore`, `zinterstore` and `zunionstore` events. In the special case the resulting sorted set is empty, and the key where the result is stored already exists, a `del` event is generated since the key is removed. +* [`SREM`]({{< relref "/commands/srem" >}}) generates a single `srem` event, and an additional `del` event if the resulting set is empty and the key is removed. * [`XADD`]({{< relref "/commands/xadd" >}}) generates an `xadd` event, possibly followed an `xtrim` event when used with the `MAXLEN` subcommand. * [`XDEL`]({{< relref "/commands/xdel" >}}) generates a single `xdel` event even when multiple entries are deleted. -* [`XGROUP CREATE`]({{< relref "/commands/xgroup-create" >}}) generates an `xgroup-create` event. * [`XGROUP CREATECONSUMER`]({{< relref "/commands/xgroup-createconsumer" >}}) generates an `xgroup-createconsumer` event. +* [`XGROUP CREATE`]({{< relref "/commands/xgroup-create" >}}) generates an `xgroup-create` event. * [`XGROUP DELCONSUMER`]({{< relref "/commands/xgroup-delconsumer" >}}) generates an `xgroup-delconsumer` event. * [`XGROUP DESTROY`]({{< relref "/commands/xgroup-destroy" >}}) generates an `xgroup-destroy` event. * [`XGROUP SETID`]({{< relref "/commands/xgroup-setid" >}}) generates an `xgroup-setid` event. * [`XSETID`]({{< relref "/commands/xsetid" >}}) generates an `xsetid` event. * [`XTRIM`]({{< relref "/commands/xtrim" >}}) generates an `xtrim` event. -* [`PERSIST`]({{< relref "/commands/persist" >}}) generates a `persist` event if the expiry time associated with key has been successfully deleted. +* [`ZADD`]({{< relref "/commands/zadd" >}}) generates a single `zadd` event even when multiple elements are added. +* [`ZDIFFSTORE`]({{< relref "/commands/zdiffstore" >}}), [`ZINTERSTORE`]({{< relref "/commands/zinterstore" >}}) and [`ZUNIONSTORE`]({{< relref "/commands/zunionstore" >}}) respectively generate `zdiffstore`, `zinterstore` and `zunionstore` events. In the special case the resulting sorted set is empty, and the key where the result is stored already exists, a `del` event is generated since the key is removed. +* [`ZINCR`]({{< relref "/commands/zincr" >}}) generates a `zincr` event. +* [`ZREMBYRANK`]({{< relref "/commands/zrembyrank" >}}) generates a single `zrembyrank` event. When the resulting sorted set is empty and the key is generated, an additional `del` event is generated. +* [`ZREMBYSCORE`]({{< relref "/commands/zrembyscore" >}}) generates a single `zrembyscore` event. When the resulting sorted set is empty and the key is generated, an additional `del` event is generated. +* [`ZREM`]({{< relref "/commands/zrem" >}}) generates a single `zrem` event even when multiple elements are deleted. When the resulting sorted set is empty and the key is generated, an additional `del` event is generated. * Every time a key with a time to live associated is removed from the data set because it expired, an `expired` event is generated. * Every time a key is evicted from the data set in order to free memory as a result of the `maxmemory` policy, an `evicted` event is generated. * Every time a new key is added to the data set, a `new` event is generated. @@ -178,7 +179,7 @@ The `expired` events are generated when a key is accessed and is found to be exp If no command targets the key constantly, and there are many keys with a TTL associated, there can be a significant delay between the time the key time to live drops to zero, and the time the `expired` event is generated. -Basically `expired` events **are generated when the Redis server deletes the key** and not when the time to live theoretically reaches the value of zero. +Expired (`expired`) events are generated when the Redis server deletes the key and not when the time to live theoretically reaches the value of zero. ### Events in a cluster