Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEV: update keyspace notifications page for new hash commands #238

Merged
merged 6 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion content/commands/info/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
67 changes: 34 additions & 33 deletions content/develop/use/keyspace-notifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
andy-stark-redis marked this conversation as resolved.
Show resolved Hide resolved
* [`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.
Expand Down Expand Up @@ -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

Expand Down
Loading