This article is contributed. See the original author and article here.

Scenario:

Sometimes we need to know what happened to some Redis keys. We expected to read the keys from Redis service, but the keys disappeared.

Some times the keys were deleted or evicted, other times the TTL expired and we are not aware of that. 

In these cases to monitor operations in the keys, we can enable the Redis Keyspace Notifications as described here to receive a notification when something happen: https://redis.io/topics/notifications

There are a list of Redis events that can be monitored as described in Events generated by different commands section in the Redis.io documentation.

 

Keyspace notifications allow clients to subscribe to two channels in order to receive events affecting the Redis data set in some way. Examples of the events that are possible to receive are the following:

  • All the commands affecting a given key.
  • All the keys receiving an specific operation (Set, Delete, etc)
  • All the keys expiring in the database.

 

Keyspace notifications are implemented by sending two distinct types of events for every operation affecting the Redis data space:

  • Key-space notification: to monitor specific keys
  • Key-event notification: to monitor specific events

 

By default keyspace notifications are disabled because may have some impact on the Redis performance using some CPU power.

 

Actions:

To enable Keyspace notifications and receive the events, first we need to enable and configure the Redis notification Keyspace.

When using Azure Cache for Redis, Keyspace notifications can be enabled in Azure Portal, on Redis blade.

Setting the parameter to the empty string disables notifications. In order to enable the feature a non-empty string is used, composed of multiple characters, where every character has a special meaning according to the following table:

K     Keyspace events, published with __keyspace@<db>__ prefix.
E     Keyevent events, published with __keyevent@<db>__ prefix.
g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
$     String commands
l     List commands
s     Set commands
h     Hash commands
z     Sorted set commands
t     Stream commands
x     Expired events (events generated every time a key expires)
e     Evicted events (events generated when a key is evicted for maxmemory)
m     Key miss events (events generated when a key that doesn't exist is accessed)
A     Alias for "g$lshztxe", so that the "AKE" string means all the events except "m".

At least K or E should be present in the string, otherwise no event will be delivered regardless of the rest of the string.

For instance to enable just Key-space events for lists, the configuration parameter must be set to Kl, and so forth.

The string KEA can be used to enable every possible event.

 

 

1. Enable and configure the Redis Keyspace notifications

 

– Using Azure Portal

As CONFIG command is not supported in Azure Cache for Redis, as described in this documentation, Redis commands not supported in Azure Cache for Redis, we will enable and configure the Redis notifications using Azure Portal. As example we will configure ‘AKE’ to receive all notifications. As described in the table above, we may want to configure only some type of notifications.

To Enable Redis notifications using Azure Portal, we need:

– In Azure Portal, on Redis blade, click on “Advanced Settings” at the left.

– In Notify-Keyspace-Events box, write “AKE”

– Save the changes

 

Capture.PNG

 

With that, we enabled Redis Keyspace for all notifications. Removing all the text leaving a empty box and saving, will disable the Redis Keyspace notifications.

 

2. Subscribing Keyspace notifications

As described above, two types of events can be subscribed using PSUBSCRIBE command, in this format:

 psubscribe __keyspace@<database>__:<mykey>
 psubscribe __keyevent@<database>__:<operation>

 

– using Azure portal console:

In this case we will use the psubscribe command using Redis Console available in Azure Portal to subscribe both types of events in any database, for all events and all keys:

  psubscribe '__key*__:*'

 

– using Redis-cli console:

The same as above using redis-cli console command line:

  redis-cli --csv psubscribe '__key*__:*'

 

– using .NET (Stackexchange.Redis) application:

Using Stackexchange.Redis  client library to subscribe notifications, we may need to develop some app and use this Class. To subscribe just call NotificationsExample method passing the connection as ConnectionMultiplexer object, in the method parameter:

 

 

class RedisKeyspaceNotifications
    {
        /// <summary>
        /// NOTE: For this sample to work, you need to go to the Azure Portal and configure keyspace notifications with "Kxge$" to
        ///       1) turn on expiration notifications (x), 
        ///       2) general command notices (g) and 
        ///       3) Evicted events (e).
        ///       4) STRING operations ($).
        ///       or AKE for all events, all notifications
        /// IMPORTANT
        ///       1) MAKE SURE YOU UNDERSTAND THE PERFORMANCE IMPACT OF TURNING ON KEYSPACE NOTIFICATIONS BEFORE PROCEEDING
        ///          See http://redis.io/topics/notifications for more details
        ///       2) THIS DOES NOT WORK CORRECTLY ON CLUSTERED REDIS INSTANCES
        ///          See https://github.com/StackExchange/StackExchange.Redis/issues/789 for details
        public static void NotificationsExample(ConnectionMultiplexer connection)
        {
            var subscriber = connection.GetSubscriber();
            string db = "*"; // default db is 0 - Redis DB do you want notifications

            // ----------------------------------------------------------------------
            // subscribing the channel keyspace
            // ----------------------------------------------------------------------
            // keyspace
            string notificationChannel = "__keyspace@" + db + "__:*";             // all events - The Key-space channel receives as message the name of the event.
            //string notificationChannel = "__keyspace@" + db + "__:key25";         // only key25 events

            // keyevent
            //string notificationChannel = "__keyevent@" + db + "__:set";           // all set
            //string notificationChannel = "__keyevent@" + db + "__:del";           // all del
            //string notificationChannel = "__keyevent@" + db + "__:rename_to";     // all rename to
            //string notificationChannel = "__keyevent@" + db + "__:rename_from";   // all rename from
            //string notificationChannel = "__keyevent@" + db + "__:expired";       // all expired
            //string notificationChannel = "__keyevent@" + db + "__:evicted";       // all evicted
            // ----------------------------------------------------------------------
            // ----------------------------------------------------------------------


            Console.WriteLine("Subscribed to notifications...: " + notificationChannel);


            //--------------------------------------------------
            // we only have to do this once, then your callback will be invoked.
            //--------------------------------------------------
            subscriber.Subscribe(notificationChannel, (channel, notificationType) =>
            {
                var msg = GetKey(channel);
                switch (notificationType) // use "Kxge" keyspace notification options to enable all of the below...
                {   
                    // looking for some events
                    case "expire": // requires the "Kg" keyspace notification options to be enabled
                        Console.WriteLine("Expiration Set for Key: " + msg);
                        break;
                    case "expired": // requires the "Kx" keyspace notification options to be enabled
                        Console.WriteLine("Key EXPIRED: " + msg);
                        break;
                    case "rename_from": // requires the "Kg" keyspace notification option to be enabled
                        Console.WriteLine("Key RENAME(From): " + msg);
                        break;
                    case "rename_to": // requires the "Kg" keyspace notification option to be enabled
                        Console.WriteLine("Key RENAME(To): " + msg);
                        break;
                    case "del": // requires the "Kg" keyspace notification option to be enabled
                        Console.WriteLine("KEY DELETED: " + msg);
                        break;
                    case "evicted": // requires the "Ke" keyspace notification option to be enabled
                        Console.WriteLine("KEY EVICTED: " + msg);
                        break;
                    case "set": // requires the "K$" keyspace notification option to be enabled for STRING operations
                        Console.WriteLine("KEY SET: " + msg);
                        break;

                    // other events may be added following https://redis.io/topics/notifications - events section

                    // looking for other events
                    default:
                        Console.WriteLine("KEY " + notificationType + ": " + msg);
                        break;
                }
            });
            

        private static string GetKey(string channel)
        {
            var index = channel.IndexOf(':');
            if (index >= 0 && index < channel.Length - 1)
                return channel.Substring(index + 1);

            //we didn't find the delimeter, so just return the whole thing
            return channel;
        }
    }

 

From: JonCole RedisKeyspaceNotifications Example 

 

3. Receiving notifications

The notifications will be received in the same console application used to subscribe the Keyspace notifications.

To test and run some command to fire some events, we need to open a different console application (or running our dev/test/prod application).

 

Below we used Redis Console available in Azure Portal.
In Azure Redis console 1 we can see:

  • in blue, the result of subscribing both types of events in any database, for all events and all keys, using the command above.

After setting ‘key1’ with value ‘value1’ (using Azure Redis console 2), we can see the notifications in console 1:

  • in pink – the keyspace notification for key ‘key1’
  • in red – the keyevent notification for command ‘set’

Capture.PNG

Because we subscribed both types of events (keyspace and keyevent), we received two notifications.

 

The command ran in Azure Redis console 2 was setting ‘key1’ with value ‘value1’:

Capture.PNG

 

Conclusion:

There are a few other methods to monitor Redis instances. Specially using Azure Cache for Redis, we have Azure Monitor, Metrics, Alerts and Diagnostics features to Monitor Redis instances.
Redis Keyspace Notifications allow us to monitor some specific key or some specific operations apart of all other notifications.

 

Related documentation:

Azure Monitor for Azure Cache for Redis (preview)

Azure Redis Metrics with Azure Monitor

Azure Alerts for Azure Redis
Activity Logs for Azure Redis
Diagnostic Settings

 

 

I hope this can be useful !!!

 

 

Brought to you by Dr. Ware, Microsoft Office 365 Silver Partner, Charleston SC.