Redis Keyspace Notifications on C#

Bora Kaşmer
5 min readDec 4, 2023

--

Hi,

Today, we will talk about how can we avoid repeated jobs with microservice in some periods. I will explain the requirements with a real business story. We have a phone number pool for every client. We will register some of them with expiration time. We have to remove the register flag from the Database when a phone number becomes free. So in this article, we try to avoid updating the DB for every 1-minute interval by checking expire dates on the microservice.

In this article, we will use Redis for managing phone number expiration. Redis has a “Keyspace Notifications” key feature. Its ability to trigger notifications based on key events happening in its keyspace allows for real-time updates for different types of events. Like Set, Expire, Update, and Delete events.

First in first we have to update Redis Config:

In Redis by default keyspace event notifications are disabled and we have to enable it with the below command:

notify-keyspace-events Kxge$

You can run Redis in two different ways. 1-) As a service(Windows Service) or .exe file(redis-server.exe). So you have two types of redis.config files. If you running Redis as a Windows service you have to edit the “redis.windows-service.conf” file. If you running as a .exe file, you have to edit the “redis.windows.conf” file.

I know “Kxge$” looks wired but each letter in the Kxge$ argument represents a different type of Redis event that should be published to the subscriber.

  • K: “SET,GET” commands
  • X: Expired Keys
  • G: Set “EXPIRE“ command
  • E: When Update keys.
  • $: Keyspace events for string commands received.

As seen below, we can fire notify to Redis for other many different events.

If Redis up and runing with above config, we will create C# Console App.

We will use “StackExchange.Redis” library for Redis operations.

1-) We will use StackExchange.Redis library and we will create the Redis ConfigOptions class(EndPoint and Password) as below. We will set Endpoint and Password. “6379” is the default Redis port. If you use SSL on cloud, Redis Port is usually “6380”.

using StackExchange.Redis;

Console.WriteLine("Redis Expire Service Start!");

var configurationOptions = new ConfigurationOptions
{
EndPoints =
{
"localhost:6379",
},
Password = "Your Passsword"
};

2-) We will create ConnectionMultiplexer by using the configurationOptions class. It is used for obtaining a subscriber or publisher connection to the specified server.

var connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(configurationOptions);
var subscriber = connectionMultiplexer.GetSubscriber();

3-) This is the most important part. We will subscribe to Redis Keyspace Notification. We will get every notification message when occurs some events on the Redis database. We will listen to the “__keyspace@0__:*” channel, which Redis will send notification messages to this channel when specific events occur on Reddis DB=0.

The switch statement then handles each type of keyspace event. In this case, we will check when the key is set and expire. At the end of the key timeout, we will check the expiration of the key and write message to the console.

await subscriber.SubscribeAsync("__keyspace@0__:*", (channel, type) =>
{
var key = GetKey(channel);

switch (type)
{
case "set":
Console.WriteLine($"Set: {key} =>{DateTime.Now}");
break;
case "expire":
//Console.WriteLine($"Expire: {key}");
break;
case "expired":
Console.WriteLine($"Expired: {key} =>{DateTime.Now}");
break;
}
});

Console.ReadLine();

4-) GetKey(): We will get the message which was published by Redis when the keyspace event occurred. We will parse channel and get the type. In this case we will get only “set, expire, and expired” types.

static string GetKey(string channel)
{
var index = channel.IndexOf(':');

if (index >= 0 && index < channel.Length - 1)
{
return channel[(index + 1)..];
}

return channel;
}

Let’s Test It

We will use Redis Desktop Manager for setting keys with expiration time. And Monitoring the results.

We will set a Discount Coupon for 5 seconds to the Redis. When we set the “coupon” keyword, we will get a “Set” Notification. After 5 seconds we will get an Expired Coupon notification on Console App. This is awesome. Because, when we get this notification we can disable this coupon from the Database by setting the “IsDeleted” column as “true”. No need to check the DB at certain time intervals anymore.

Conclusion:

Redis Keyspace Notification has both advantages and disadvantages. Unfortunately, the notification message sent to you from Redis may not always reach you. We call it “lack of durability”. This may cause you to have incorrect or incomplete data. But you can run your manual job at once in a day for missing or corrupted data. Of course, it is not correct to use Redis Keyspace Notification in critical data. But it is very usable when we need to make real-time Reports.

The biggest benefit of Redis Keyspace Notification is to get rid of the unnecessary DB operations, and system usage by going to the DB at certain time intervals, opening connections, and making queries.

See you until the next article.

“If you have read so far, first of all, thank you for your patience and support. I welcome all of you to my blog for more!”

Codes: https://gist.github.com/borakasmer/fbef04da0fee734f5665e447a9520e2a

Source:

--

--

Bora Kaşmer

I have been coding since 1993. I am computer and civil engineer. Microsoft MVP. Software Architect(Cyber Security). https://www.linkedin.com/in/borakasmer/