Redis Caching in the Google Cloud Platform

By February 3, 2017.NET, Cloud Platform

Caching is one of those solutions that is often added after you realize that there is a performance problem with your system. For example, fetching records from a database may be fast when you are developing locally as the only user. But, in production with hundreds or thousands of simultaneous requests taking place, that disk-based database will soon become a bottleneck. If the data is slowly changing, then there is really no need to hit the database itself after the first read: simply save the data to cache after fetching it, and read it out of cache instead on subsequent requests.

Redis is a popular open-source highly-scalable shared in-memory data store. You can think of it as a database of key/value pairs, like a NoSQL database, but it can also serve as a message queue and pub/sub server. And, while its normal operating mode is in-memory on one machine, there is also support for clustering and persistence to disk.

Redis is often implemented as part of a solution because it is:

  • Cross-Platform: Being open source, a Redis server can run on both Windows and Linux operating systems. Even if your solution is based on .NET running on Windows Servers, the Redis server itself can be hosted on a lower-cost Linux instance.
  • Cross-Server: Redis can run locally on the same machine as your application, but it is often installed as its own server in order to permit multiple machines to access it. In this way, the same data cache can be shared among servers.
  • Cross-Application: A client API within your application is used to access the Redis server. One application can place data into Redis for another application to consume (like a message queue).
  • Cross-Process: Even within the same application, Redis can be used as a means to decouple code that runs in different processes.

Installing Redis in the Google Cloud

Unlike features such as Cloud SQL (MySQL) or Cloud BigTable, Redis is not a first-class citizen in the Google Cloud Platform. So, you have to somehow install it as a Compute Engine instance.

One easy way to do this is to use the Cloud Launcher. Search for “redis”, and you will find both a Google-provided and a Bitnami-provided image:

Searching for "redis" will result in a Google-provided image and a Bitnami-provided image

The Google-curated image is configured as an advanced Redis cluster of 3 x n1-standard-4 instances with a 10GB boot disk running on Debian 8, and costs an estimated $400/month to run. The Bitnami-curated image is very simple out of the box, using a single f1-micro instance with a 10GB disk running on Debian 8, and costs an estimated $5/month.

For those who do not want to administer Redis themselves, another popular option is to use a subscription service to set up and manage Redis for you. Redis Labs, for example, provides Redis-as-a-service hosted on a number of popular cloud platforms (GCE included) for a reasonable price. It even includes a free tier that is sufficient for evaluation or even as the caching layer for small applications.

The Redis Labs free cache plan provides a single 30MB database for free

After creating a subscription, you must add the database(s) via the website:

Create a database to be used as your system's caching layer

Redis Labs will then take care of the rest, creating your image that you can immediately use from your application.

Once you are up and running, you can also access monitoring and statistics from the Redis Labs website.

Using Redis for Caching in your .NET Application

Search NuGet for “redis”, and you’ll find a lot of results. But, one in particular is the StackExchange.Redis client library with over 1.4 million downloads. This is a general-purpose Redis client that is built for performance, and supports all of the Redis Commands. If you have ever searched for help on StackOverflow, then you have been on the receiving end of StackExchange.Redis in action.

Let’s look at how to build our own simple Cache-Aside implementation using StackEchange.Redis. Cache-Aside is a design pattern that tries to read data from cache first. If the data is not there, then it will fetch the data from the database and save it to cache for subsequent reads.

Note: This sample is a complete Console application, but the interesting part of the Cache-Aside implementation is in the highlighted GetSpeakerById() method. To run this locally, be sure to install the StackExchange.Redis and Newtonsoft.Json NuGet packages, as well as substitute your own Redis server information.

Some things to note in this code:

  • The ConnectionMultiplexer is a long-lived object. Create it once and just keep it around for the life of your application.
  • The method names are slightly different than the actual Redis commands. For example, Redis’s GET is called StringGet in this library.
  • The library provides both synchronous and asynchronous versions of each command. For example: StringGet() and await StringGetAsync()
  • Since Redis stores values as strings, the object graph is serialized to and from JSON in this code using the Newtonsoft.Json library.

The example app above sets the cache timeout to 30 seconds when the object is written to cache. After 30 seconds, the object is considered stale and will be removed. We can observe that the cached object is being used by watching the timestamp. Whenever it changes for a given ID, then we know that a “database fetch” has occurred:

You will need to decide what expiration is appropriate for your own application and data. Also, if an object is updated, it is common to remove it from cache at the same time as committing the changes to the database so that a fresh read is used on the next request.

Specialized Libraries

While the StackExchange.Redis library is a complete Redis client, using it directly might require more coding than you were hoping for. Fortunately, Redis is a very popular platform, and a number of specialized libraries have been written that use it as their backend for caching, session storage, message queueing, and a host of other things. In a lot of cases, these libraries actually use the StackExchange.Redis client themselves.

Here is a sampling of libraries and frameworks that can use Redis:

Hangfire.io: An easy way to perform background processing in .NET and .NET Core applications. No Windows Service or separate process required.

CacheManager: CacheManager is an open source caching framework for .NET written in C# and is available via NuGet. It supports various cache providers and implements many advanced features

CachingFramework.Redis: Distributed caching based on StackExchange.Redis and Redis. Includes support for tagging and is cluster-compatible.

Harbour.RedisSessionStateStore: Redis based SessionStateStoreProvider written in C# using ServiceStack.Redis

EFCache.Redis: Extends EFCache by adding Redis support

TagCache.Redis: .NET Redis Cache with support for tagging

RedisSessionProvider: Provides a drop-in class library that makes ASP.NET’s System.Web Session object store its contents in a Redis server or servers.

ServiceStack: Thoughtfully architected, obscenely fast, thoroughly enjoyable web services for all. Note: Commercial product, developer licensing required

The following two tabs change content below.