Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Implementing Cloud Ready On-Premise Cache Solution With Redis on Windows

5.00/5 (1 vote)
23 Apr 2016CPOL3 min read 26.7K  
This articles describes how to write a caching solution using Redis on .NET platform.

Introduction

Often times, while developing applications, caching plays an important role in improving the performance of the application and playing an important role in implanting some key features.

This article will explain how Redis on Windows can be used to address this problem in a clean way using Microsoft Visual Studio and C# language. StackExchange Redis is one of the best available .NET Redis clients and we will use the same for this article.

The code can be used directly for Redis Cache on Azure Cloud as well.

Steps to Solution

Here are the steps needed to include Redis cache in your solution:

  1. Install Redis for Windows using any of the releases available on this MSOpenTech page. This solution has been tested with releases 2.8.2104, 2.8.2400 and 3.0.501.
  2. Once installed, a Redis service should be available in the Services console of your Windows machine. Ensure that this service is running.
  3. Create a new .NET solution using Microsoft Visual Studio.
  4. Add StackExchange.Redis client and two other nuGet packages to the solution using either the package manager or the following command:
    PM> Install-Package StackExchange.Redis
    PM> Install-Package StackExchange.Redis.Extensions.Core
    PM> Install-Package StackExchange.Redis.Extensions.Newtonsoft

    This would have added a reference to StackExchange.Redis library in your project.

    NOTE: Use StackExchange.Redis.StrongName in case your solution needs to be Strong Named.

  5. Add Redis connection string to your App.Config (Web.Config in case of a web application). Here is how a simple connection string will look like:
    XML
    <connectionStrings>
      <clear />
      <add name="RedisCacheConnection" connectionString="localhost:6379,ssl=false" />
    </connectionStrings>
    
  6. Add the following key to the Config file to explicitly select specific Redis database. There are 16 databases/segments (0 to 15) by default in a single Redis instance.
    XML
    <appSettings>
      <add key="RedisDatabaseNumber" value="1" />
      <add key="RedisCacheExpiration" value="20" />
    </appSettings>
    
  7. Add reference to System.Configuration library.
  8. Create a new class that will connect to Redis client similar to the following class:
    C#
    using StackExchange.Redis.Extensions.Core;
    using StackExchange.Redis.Extensions.Newtonsoft;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    
    namespace RedisDemo
    {
        public class RedisClient<T>
        {
            /// <summary>
            /// Connection string to the redis cache instance
            /// </summary>
            protected string cacheConnectionString;
    
            /// <summary>
            /// Cache object expiration time
            /// </summary>
            protected int cacheObjectExpiration;
    
            /// <summary>
            /// Redis DB instance to be used
            /// </summary>
            protected short redisDb;
    
            /// <summary>
            /// Default constructor
            /// </summary>
            public RedisClient()
            {
                cacheConnectionString = ConfigurationManager.ConnectionStrings
                                        ["RedisCacheConnection"].ConnectionString;
                redisDb = Convert.ToInt16(ConfigurationManager.AppSettings["RedisDatabaseNumber"]);
                cacheObjectExpiration = Convert.ToInt32
                        (ConfigurationManager.AppSettings["RedisCacheExpiration"]);
            }
    
            /// <summary>
            /// Initializes and returns Redis cache client
            /// </summary>
            /// <returns>Redis Cache client</returns>
            protected StackExchangeRedisCacheClient GetCacheClient()
            {
                var serializer = new NewtonsoftSerializer();
                var cacheClient = new StackExchangeRedisCacheClient
                                     (serializer, cacheConnectionString, redisDb);
                return cacheClient;
            }
    
            /// <summary>
            /// Flushes the cache
            /// </summary>
            public void FlushCache()
            {
                using (var cacheClient = this.GetCacheClient())
                {
                    cacheClient.FlushDb();
                }
            }
    
            /// <summary>
            /// Add the item to the cache
            /// </summary>
            /// <param name="key"></param>
            /// <param name="cacheObject"></param>
            public void AddToCache(string key, T cacheObject)
            {
                using (var cacheClient = GetCacheClient())
                {
                    if (cacheClient.Exists(key))
                    {
                        cacheClient.Replace
                           (key, cacheObject, new TimeSpan(0, cacheObjectExpiration, 0));
                    }
                    else
                    {
                        cacheClient.Add(key, cacheObject, new TimeSpan(0, cacheObjectExpiration, 0));
                    }
                }
            }
    
            /// <summary>
            /// Retrieve an item from cache based on the key
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public T GetCachedItem(string key)
            {
                using (var cacheClient = this.GetCacheClient())
                {
                    var cachedObject = cacheClient.Get<T>(key);
                    return cachedObject;
                }
            }
    
            /// <summary>
            /// Get all the items cached
            /// </summary>
            /// <returns></returns>
            public IEnumerable<T> GetAllCachedItems()
            {
                using (var cacheClient = GetCacheClient())
                {
                    var keys = cacheClient.SearchKeys("*");
                    var dictCollection = cacheClient.GetAll<T>(keys);
                    return dictCollection.Values.ToList();
                }
            }
        }
    }
  9. The cache client class is ready for use. You can now instantiate it and use it to store and retrieve data from the cache.

Additional Tips and Tricks

Here are a few additional tips and tricks that you can use while using Redis on Windows.

Managing Disk Space

Redis on Windows uses up a lot of disk space to persist some of its data. Although version 2.8.2400 has made some fixes to resolve this, here is how you can configure Redis to not consume any disk space:

  1. Stop Redis service.
  2. Delete all the files at the location “C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Redis” which is the default Redis persistence location.
  3. Go to the Redis server configuration file. Default location of the file is "C:\Program Files\Redis\redis.windows.conf".
  4. Uncomment this line in the file: save ""
  5. Comment these lines:
    • save 900 1
    • save 300 10
    • save 60 10000
  6. Go to this line: # persistence-available [(yes)|no]
  7. Add this line just below this: persistence-available [no]
  8. Save the file and restart the Redis service.

Redis Databases/Partitions

Each Redis instance comes with 16 databases or partitions by default. You can store similar or different objects in each partition. These partitions can be used to separate different type of objects that your application might need to cache.

Manage Session Using Redis

In case you have to spin out multiple web servers to scale out your web application, managing sessions gets a little tricky. There are various options like using sticky session, State Server and SQL server.

Similarly, you can use Redis cache to store sessions. A session state provider is available that utilizes Redis cache. Here is the link to a blog that describes how to use the same.

Manage Redis Through Command Line

Here is a glossary of commands that can be used to manage Redis through command line. Redis-Cli.exe present at Redis install location can be used to connect to the Redis Server instance.

Summary

We have looked at a simple, straight-forward and a crude method for using Redis in an intranet environment that can be ported over cloud and use the Azure Redis service as is.

History

  • Initial draft created

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)