Subkey notification for hash fields#14958
Conversation
🤖 Augment PR SummarySummary: This PR adds field-level (subkey) notifications for hash operations, extending Redis keyspace notifications to include the affected hash fields. Changes:
Technical Notes: Subkeys are published in a binary-safe 🤖 Was this summary useful? React with 👍 or 👎 |
|
description LGTM |
|
Hi @alonre24 Maybe you also care about module API, please have a look when you are available |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 9f3a362. Configure here.
|
Hi @fcostaoliveira i refactored some code based on new |
on it :) |
Benchmark results — commit
|
| Test | Baseline | PR | Change |
|---|---|---|---|
| load-50f-1000B | 26,389 ±0.5% | 26,131 | -1.0% |
| load-50f-100B | 63,684 ±0.4% | 63,759 | +0.1% |
| load-50f-10B-expiration | 20,909 ±1.2% | 21,241 | +1.6% |
| load-50f-1000B-expiration | 18,507 ±0.2% | 18,361 | -0.8% |
| load-50f-10B-long-exp | 20,893 ±1.1% | 21,215 | +1.5% |
| load-50f-10B-short-exp | 21,536 ±0.9% | 21,784 | +1.1% |
| hgetall-50f-100B | 165,531 ±2.1% | 164,507 | -0.6% |
| hexpire-5f | 140,457 ±0.5% | 140,972 | +0.4% |
| hexpire-50f | — | 30,347 | — |
| hpexpire-5f | 140,457 ±0.5% | 139,806 | -0.5% |
| hpexpire-50f | 29,705 ±0.3% | 30,174 | +1.6% |
| hexpireat-5f | 140,035 ±0.7% | 141,300 | +0.9% |
| hexpireat-50f | — | 30,288 | — |
| hpexpireat-5f | — | 144,188 | — |
| hpexpireat-50f | 31,038 ±0.7% | 30,544 | -1.6% |
All within noise. No performance impact on x86.
ARM (Neoverse-V2) — 2 small regressions (1dp, needs confirmation)
| Test | Baseline | PR | Change |
|---|---|---|---|
| hexpireat-50f | 33,252 ±0.2% | 32,113 | -3.4% |
| hpexpireat-50f | 33,536 ±0.2% | 32,390 | -3.4% |
All other ARM tests: No Change.
The two -3.4% regressions on ARM are single-datapoint — both on the 50-field expireat variants. Baseline has very low variance (0.2%), so this warrants a re-trigger to confirm.
Summary
The vector refactor has no measurable performance impact on hash data type commands on x86. ARM shows two borderline regressions (-3.4%) on the hexpireat/hpexpireat 50-field tests — recommending a re-trigger for 3dp confirmation.
|
thanks @filipecosta90 , the performance degradation caused by this PR is relatively small. cc @moticless |
|
@tezc , can you review please related changes of cluster ASM? Thanks. |
|
@moticless @ShooterIT I don't see any change that may affect ASM. Please point me if there are such parts and want me to take a look. |
@tezc , True. my mistake. just minor refactor of |
|
Daily CI: https://github.com/ShooterIT/redis/actions/runs/24544487006 Most of them are successful, and the failed cases have nothing to do with this PR. So merging |

Motivation
Redis's existing keyspace notification system operates at the key level only — when a hash field is modified via
HSET,HDEL, orHEXPIRE, the subscriber receives the key name and the event type, but not which fields were affected, therefore, these notifications has very little practical value.This PR introduces a subkey notification system that extends keyspace events to include field-level (subkey) details for hash operations, through both Pub/Sub channels and the Module API.
New Pub/Sub Notification Channels
Four new channels are added:
__subkeyspace@<db>__:<key><event>|<len>:<subkey>[,...]__subkeyevent@<db>__:<event><key_len>:<key>|<len>:<subkey>[,...]__subkeyspaceitem@<db>__:<key>\n<subkey><event>__subkeyspaceevent@<db>__:<event>|<key><len>:<subkey>[,...]Design rationale for 4 channels:
Subkeys are encoded in a length-prefixed format (
<len>:<subkey>) to support binary-safe field names containing delimiters.Safety guards:
|are skipped for__subkeyspaceand__subkeyspaceeventchannels (to avoid parsing ambiguity).\nare skipped for the__subkeyspaceitemchannel (newline is the key/subkey separator).subkeys != NULL && count > 0.Hash Command Integration
The following hash operations now emit subkey level notifications with the affected field names:
HSET/HMSEThsetHSETNXhsetHDELhdelHGETDELhdel/hexpiredHGETEXhexpire/hpersist/hdel/hexpiredHINCRBYhincrbyHINCRBYFLOAThincrbyfloatHEXPIRE/HPEXPIRE/HEXPIREAT/HPEXPIREAThexpireHPERSISThpersistHSETEXhset/hdel/hexpire/hexpiredhexpiredFor field expiration, expired fields are collected into a dynamic array and sent as a single batched notification after the expiration loop, rather than one notification per field.
Module API
Three new APIs and one new callback type:
Configuration
Subkey notifications are controlled via the existing
notify-keyspace-eventsconfiguration string with four new characters:notify-keyspace-events"STIV"S -> Subkeyspace events, published with
__subkeyspace@<db>__:<key>prefix.T -> Subkeyevent events, published with
__subkeyevent@<db>__:<event>prefix.I -> Subkeyspaceitem events, published per subkey with
__subkeyspaceitem@<db>__:<key>\n<subkey>prefix.V -> Subkeyspaceevent events, published with
__subkeyspaceevent@<db>__:<event>|<key>prefix.These flags are independent from the existing key-level flags (
K,E, etc.). Enabling subkey notifications does not implicitly enable or depend on keyspace/keyevent notifications, and vice versa.Known Limitations
subkey->ptr, and there is an assert, redis will crash if not.Note
Medium Risk
Touches core keyspace notification and module API surfaces and changes notification behavior/perf paths across many hash commands and expiry code, so regressions could affect Pub/Sub and modules. Guardrails and extensive new tests reduce but don’t eliminate risk.
Overview
Adds subkey-level keyspace notifications (hash field names) on top of existing key-level KSN, gated by four new
notify-keyspace-eventsclasses (S,T,I,V) and documented inredis.conf.Extends the notifications pipeline with
notifyKeyspaceEventWithSubkeys()/isSubkeyNotifyEnabled()and publishes new Pub/Sub channel variants (__subkeyspace@..,__subkeyevent@..,__subkeyspaceitem@..,__subkeyspaceevent@..) with length-prefixed subkey payloads and ambiguity guards; also short-circuits work when there are no Pub/Sub subscribers.Updates the module KSN dispatcher to accept optional subkeys, adds subscribe/unsubscribe + notify APIs for modules (
RM_*WithSubkeys), caches subscriber type masks for faster checks, and wires new notification flags intoserver.h/redismodule.hand config parsing.Integrates subkey emission across hash mutations and hash-field expiration paths (batching expired fields where possible) and adjusts tests to cover module callbacks, replication, and the new Pub/Sub channel formats; minor
vectorAPI tweaks support stack-backed field collection.Reviewed by Cursor Bugbot for commit f6613bc. Bugbot is set up for automated code reviews on this repo. Configure here.