In today's post, I'm going to talk about the different ways you can deal with session caching in a load-balanced environment.
Caching Issues With Umbraco in a Load Balanced Environment
If you work on an Umbraco website, stored on a single node, session caching is pretty simple, you store your site visitors session cache in local state server session, and everything works as expected. When you push a new release onto the live server, everyone will be kicked off until you update your code.
When companies hit a certain size, having downtime during code deployments is undesirable. If you run an e-commerce website that makes £1000,000 an hour, if you have to take your website down for an hour each time you release, you lose a lot of money, so strategies like load balancing and resource sharing become vital parts of the website's architecture. For the companies running Umbraco website in a load balanced environment, on multiple clusters, things get a little more interesting when it comes to persisting session cache. If you follow the single node strategy above and store your session cache locally on each node, when you release new code into a live enviroment, your site visitors can unnecessarily lose their sessions data.
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. A shopping basket object is stored into local session cache on Server A. At the same time the user is trying to buy things from your store, the development team needs to do a 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... in some cases, the user might give up and go somewhere else, losing you 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 business this loss of data is unacceptable.
If you've never come across the term continuous integration, then I strongly recommend reading up on it. The focus in continuous integration deployments is being able to deploy code whenever you want, quickly and with confidence so you won't break your website. Your continuous integration process should not only automate the back-end deployment tasks but, when new code is being promoted to live the site should also be resistant.
Out of the box, .NET will use a local session state provider to store your data. In a load balanced environment, you will need to configure your cluster to use a shared session store. Sharing your session storage between all of your nodes in the cluster. This will mean that no matter which node a site visitor navigates to, they won't lose their session data if you need to take a node down for whatever reason.
The default way to share session is to use SQL session state provider, however, nowadays alternative NoSQL solutions exist that will speed this process up, like Couchbase, Redis, MemCached, and RavenDb. Going into an in-depth analysis of which NoSql provider is best for your situation, is beyond this post. From my experience, I recommend using Redis and in this article, I'm assuming you've made the same conclusion, so 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, in your web.config you need to tell your application to use 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 web.config
Applying this snippet and installing the correct tables to your Umbraco database will fix your issue, however, by moving all the cache from the servers in-memory store and onto a different server, your performance will suffer. 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. Also, in the SQL approach as more and more site visitors access/update their session data, the slower your site will perform.
Redis is an alternative option to SQL caching. Redis is an open-source in-memory data structure store that also can be used as a database as well as caching. It supports simple and complex data-type catching all types of data structures such as strings, hashes, lists, sets, sorted sets with range queries, 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 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 also very likely want to be able to add other things into your Redis store to make the site faster. You can do this using a Redis provider, like StackExchange.Redis and be configured in the web.config appropriately.
PRO: Better object caching support built-in CON: Commercial product and required a license, Doesn’t support async, Not as popular with only half a million downloads
PRO: Free provider, Used on Stackoverflow, so proven, Open source, Async support, Most popular with over a million downloads CON: Less feature-rich for object caching
If you need to set-up Umbraco in a load-balanced environment, then 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 and outsourcing the store to a third-party 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.