The regular subscriber API should work fine - there is no assumption on use-cases, and this should work fine.
However, I do kinda agree that this is inbuilt functionality that could perhaps benefit from helper methods on the API, and perhaps a different delegate signature - to encapsulate the syntax of the keyapace notifications so that people don't need to duplicate it. For that: I suggest you log an issue so that it doesn't get forgotten.
Simple sample of how to subscribe to a keyspace event
First of all, it's important to check that Redis keyspace events are enabled. For example, events should be enabled on keys of type Set. This can be done using CONFIG SET command:
CONFIG SET notify-keyspace-events KEs
Once keyspace events are enabled, it's just about subscribing to the pub-sub channel:
using (ConnectionMultiplexer connection = ConnectionMultiplexer.Connect("localhost"))
{
IDatabase db = connection.GetDatabase();
ISubscriber subscriber = connection.GetSubscriber();
subscriber.Subscribe("__keyspace@0__:*", (channel, value) =>
{
if ((string)channel == "__keyspace@0__:users" && (string)value == "sadd")
{
// Do stuff if some item is added to a hypothethical "users" set in Redis
}
}
);
}
Learn more about keyspace events here.
Answer from Marc Gravell on Stack OverflowThe regular subscriber API should work fine - there is no assumption on use-cases, and this should work fine.
However, I do kinda agree that this is inbuilt functionality that could perhaps benefit from helper methods on the API, and perhaps a different delegate signature - to encapsulate the syntax of the keyapace notifications so that people don't need to duplicate it. For that: I suggest you log an issue so that it doesn't get forgotten.
Simple sample of how to subscribe to a keyspace event
First of all, it's important to check that Redis keyspace events are enabled. For example, events should be enabled on keys of type Set. This can be done using CONFIG SET command:
CONFIG SET notify-keyspace-events KEs
Once keyspace events are enabled, it's just about subscribing to the pub-sub channel:
using (ConnectionMultiplexer connection = ConnectionMultiplexer.Connect("localhost"))
{
IDatabase db = connection.GetDatabase();
ISubscriber subscriber = connection.GetSubscriber();
subscriber.Subscribe("__keyspace@0__:*", (channel, value) =>
{
if ((string)channel == "__keyspace@0__:users" && (string)value == "sadd")
{
// Do stuff if some item is added to a hypothethical "users" set in Redis
}
}
);
}
Learn more about keyspace events here.
Just to extend what the selected answer already describes:
using (ConnectionMultiplexer connection = ConnectionMultiplexer.Connect("localhost"))
{
IDatabase db = connection.GetDatabase();
ISubscriber subscriber = connection.GetSubscriber();
subscriber.Subscribe($"__keyspace@0__:{channel}", (channel, value) =>
{
// Do whatever channel specific handling you need to do here, in my case I used exact Key name that I wanted expiration event for.
}
);
}
Another important thing, I had to subscribe KEx (CONFIG SET notify-keyspace-events KEx ) to get channel based updates for expiration notifications.
caching - Redis keyspace notifications with StackExchange.Redis For Delete operation - Stack Overflow
channelPrefix disables Keyspace Notifications
stackexchange.redis - Redis Keyspace Notifications with flushdb - Stack Overflow
Cluster pub/sub: keyspace notification issues
Just as the other answer mentioned, there's no such notification.
After all, Keyspace Notification is a notification for events on a single key. Each notification is associated with a key. For keyspace event, the key name is part of the channel name. For keyevent event, the key name is the message.
PUBLISH __keyspace@0__:key_name comamnd
PUBLISH __keyevent@0__:command key_name
Each command that sending a notification must have a key as argument. e.g. del key, set key val. However, the flushdb command has no key as argument. The command doesn't affect a single key. Instead, it removes all keys in the database. So there's no such notification for it. Otherwise, what do you expect from the channel? All keys that have been removed? It's not a good idea.
However, you can simulate an event for flushdb
- set a special key, e.g.
flushdb-event:set flushdb-event 0 - subscribe on the corresponding channel:
subscribe __keyspace@0__:flushdb-event - set the special key before you call
flushdb:set flushdb-event 1
In this way, you can get the simulated flushdb notification.
According to Redis Documentation, there is no notification for Flushdb.
From Redis Keyspace Notifications
Keyspace notifications allow clients to subscribe to Pub/Sub channels in order to receive events affecting the Redis data set in some way.
Examples of events that can be received are:
All the commands affecting a given key.
All the keys receiving an LPUSH operation.
All the keys expiring in the database 0.
Events are delivered using the normal Pub/Sub layer of Redis, so clients implementing Pub/Sub are able to use this feature without modifications.
So, if you need just pub/sub, there is no need of extra configuration regarding Keyspace Notifications
key-space-notifications and pub/sub are 2 different concepts.
PUB/SUB: It's usual method publishing data to a channel and other clients can subscribe to the same channel by it's name. published messages are characterised into channels, without knowledge of what (if any) subscribers there may be.
This is enabled by default. messages are not persisted here, and once delivered/lost, messages cannot be retrieved.
key-space-notifications: This also a way of subscribing to Pub/Sub channels in order to receive events by the clients.
This we need to enable manually as this consumes little more CPU. Use below code to enable this
redisClient.configSet("notify-keyspace-events", "Ex");
we can subscribe to 2 different channels
- Key-space channel: receives the name of the event as message.
- Key-event channel: receives the name of the key as message.
example: To subscribe to key expired events, use the below code
export const subscribeForExpiry = () => {
//.: Subscribe to the "notify-keyspace-events"
// channel used for expired type events
client.configSet("notify-keyspace-events", "Ex");
const sub = client.duplicate();
sub.connect();
sub.subscribe(
`__keyevent@${process.env.REDIS_DATABASE_INDEX}__:expired`,
(key) => {
console.log("key=> ", key);
// do something with key, can't retrieve value here
}
);
};