In today's post, you will learn about the different ways you can deal with session data when using traditional server hosting with a website powered by Umbraco CMS in a load-balanced environment. Mouthful 😱 ! If you work on a Umbraco website, stored on a single node, session caching is pretty simple. You can store your site visitors session data in a local server session and everything will work as expected. The issue with this approach is that if you reboot the server, you lose session data. If you work on more than one server, a single session cache will not work. What should you do?
For the companies running a Umbraco website in a load-balanced environment, on multiple clusters, this issue of persisting session data is a problem that you will need to solve. If you follow the single node strategy above and store your session cache locally on each node your visitor will bump into wired issues. Let's say you have two servers in your load balanced set-up, Server A, and Server B. When your visitor visits your website, they hit the load balancer and get redirected to server A. At this stage, they add a product to their shopping basket. The shopping basket object is stored within the cache on Server A. While this is happening, the development team want to perform a code release and push some new changes live. The team decides to take Server A off the live cluster to push the new code onto it for testing.
When they take Server A offline, the site visitor trying to buy stuff from you loses everything in their shopping cart, as their session data is no longer available. When this happens, a user might give up and go somewhere else, losing your business... not ideal. If you have a basic brochureware website then site visitors losing their session cache might not be an issue. If, on the other hand, you have a website that has elements of e-commerce, or a sale funnel then for most businesses this loss of data is unacceptable.
Website releases can also cause issues on a single node architecture. Whenever you deploy code into production, an IISRESET will occur and all session data will be lost. When companies hit a certain size, having downtime during code deployments is undesirable. If you run an e-commerce website that makes £100,000 an hour, if you lose all your customer's shopping basket data whenever you deploy code, you will lose your company a lot of money. In these situations, strategies like load balancing and resource sharing become vital parts of the website's architecture.
This situation will not be acceptable for many companies. You will need to configure your architecture to use a shared storage solution for session data. Sharing your session storage between all of your nodes in the cluster will mean that no matter which node a site visitor navigates to, they will get access to the same sessions data. Perfect 💋
The default way to share sessions is to use SQL session state provider, however, nowadays alternative NoSQL solutions exist that will speed this process up. Solutions, like Couchbase, Redis, MemCached, and RavenDb. Going into an in-depth analysis of which NoSql provider is best for your situation, is beyond the scope of this post. From my experience, I recommend using Redis and in this article, I'm assuming you've made the same conclusion. This is why I'm only going to compare SQL Session caching, against Redis.
SQL Session State
SQL Session State is the caching solution that comes out of the box with any .NET website. To enable your Umbraco website to work in a load-balanced environment. You can do this within
web.config. Here, you need to tell your application to use a SQL based session store. I won't get into a step-by-step guide here, but you need to install some SQL files and add this snippet in your
Applying this snippet and installing the correct tables to your Umbraco database will enable shared caching, however, moving all the cache from memory to a SQL database will impact performance. This is why people who care about performance turn to alternative solutions. Querying a NoSQL table is quicker than SQL as NoSQL uses an in-memory approach.
Redis is an alternative option to using SQL as your sessions storage solution. Redis is an open-source in-memory data store that can be used to cache session data, HTML fragments and any other cache data you might need. Redis supports simple and complex object type caching. Redis can cache strings, hashes, lists, sets, sorted sets with range queries, and bitmaps. Redis also can be used as a messaging system used to push/retrieve notifications off a stack. Redis is a newer technology and was built based on the learnings from some of the other NoSQL providers, like Memcached.
With Redis you can either self-host, or you can use a Redis cloud provider. In a self-hosted environment, you simply install Redis on a shared server and point your Redis connection string to it. In a hosted environment you offload the infrastructure maintenance and let someone else deal with the hassle. If you use Azure, for example, you can use Azure Redis Cache.
After deciding on where to host your Redis store, you will need to add things to it. You can do this from ASP.NET in code, using a Redis provider, like StackExchange.Redis or ServiceStack.Redis. For a quick comparison, ServiceStack.Redis has better object caching support built-in. The downside is that it's a commercial product and requires a paid license, it also doesn’t support async. The more popular provider is one published by StackOverflow. StackExchange.Redis is a free tool. It's used on Stackoverflow, so proven as scale. StackExchange.Redis is open source, it also supports async requests.
If you need to set up Umbraco in a load-balanced environment with a shared cache, I would strongly recommend that you look at Redis for session caching. How you host your Redis store is up-to-you. Hosting internally takes more effort than using a cloud provider. The cloud will cost you more. Using Redis as your sessions store will not only guarantee that your users won't lose their session data (even if the Redis server is rebooted), your website will also be very performant as Redis caching is very quick. Setting up Redis is quick a painless. You can read my Episerver Redis instal guide to learn about the steps involved (here), as the steps are very similiar. Happy Coding 🤘