Cloud services do a great job relieving the burden of managing and maintaining various IT infrastructure elements. However, the responsibility still belongs to the developer to determine how to integrate these cloud services into an application. This blog series will focus on Microsoft Azure Services, providing guidance and examples on how to integrate services into your application, starting with Azure Cache for Redis.
What is Azure Cache for Redis?
Azure Cache for Redis is Microsoft’s cloud caching solution based on the software Redis. You are provided with an instance of a Redis cache that is hosted within Azure and can use it to improve the performance and scalability of your application. A common circumstance where a Redis cache improves performance is when the same data is accessed frequently. The cache provides a temporary location close to the application for data to be copied to, instead of relying on a larger database.
Implementing Azure Cache for Redis
This demonstration will utilize the cache-aside pattern within a .NET application and assumes you have the Redis cache created in Azure. We will be creating a singularly connected instance which various services in your application can utilize.
Before implementing this Redis cache example, it would be helpful to become at least slightly familiar with the Cache-Aside pattern. This Microsoft document provides a detailed explanation, as well as a similar implementation, of the Cache-Aside pattern that I will be explaining below. A quick reference for the general pattern is illustrated in the following image (also included in the Microsoft Document):
The only value you will need to obtain through the Azure Portal is the value for your Redis Cache’s primary connection string. This is in the “Access keys” blade of your Azure Cache for Redis resource.
In Visual Studio, the two NuGet packages that you will need are StackExchange.Redis and Newtonsoft.Json, for which the latest versions can be installed via the Package Manage Console with the following commands:
The StackExchange.Redis package will be used for establishing a connection to your cache and provides basic methods to interact with the cache. The Newtonsoft.Json package is used for serializing and deserializing data stored in and retrieved from the cache.
Time to dive into the code. To set up our singularly connected instance for the Redis Cache, we will create a class with an established connection to our cache and static methods for our services to utilize. This connection is established using an instance of a ConnectionMultiplexer, which will be shared via a static property representing that connected instance. This can be accomplished in the code below:
The connection itself is left public in case a separate caching service wants to utilize this Redis Cache connection without the specific implementation of this class’s accessor methods.
A good idea before creating the accessor methods would be to establish a consistent identifier for items cached through this class and consistent JsonSerializerSettings. If your cache is shared between different development environments, the identifier is where you want to specify the current environment. Since values will be stored in the cache as string keys, this identifier can be appended to the keys as they are stored. The key identifier and simple JsonSerializerSettings are shown below:
Setting ReferenceLoopHandling to Ignore can prevent errors in instances where classes reference themselves.
Now we are ready to create our accessor methods. We will be creating methods to get, delete, and update entities in the Redis Cache.
Our GetEntity method will be taking advantage of C# generics and delegates to create a flexible tool for accessing the Redis Cache. The idea behind this is to follow the Cache-Aside pattern described above. If the entity with the corresponding key is in the cache, we return that. Otherwise, we return it from the normal data store, and store it in the cache with an optional expiration time:
Some important details to note:
- The entityCacheKey, which is the keyAppendage used to differentiate between environments appended to the key used to retrieve the object from the data store, is used when communicating with the cache.
- The jsonSerializerSettings specified above is used when storing the entity in the cache.
The DeleteEntity method will simply take in a string for the key used to store an object in the cache, and delete it:
It is important to note that this will have no impact on the entity in the original data store.
The UpdateEntity method is important to be used when entities that are stored in the cache need to be updated in the original data store. This prevents the value in the cache from becoming stale, and old data being accessed when retrieved in the GetEntity method:
The important takeaway from this method is that the developer using this and the GetEntity method must be consistent with the value used for the key. This is the challenge introduced when using generics because specific object’s identifying properties cannot be accessed from within these Redis Cache functions and used as the key.
A simple console application can be created to demonstrate and test if the Redis Cache is up and running and working properly. The application below mocks a small data store, takes advantage of the Redis Cache we created to store and access entities:
This program outputs these results:
That’s it! We’ve implemented a fully functional Redis Cache that can be used to improve the performance and scalability of your application. Use the following link to view the full Git Repository for Implementing Azure Cache for Redis.