AWS Developer Tools Blog

ElastiCache as an ASP.NET Session Store

Are you hosting an ASP.NET application on AWS? Do you want the benefits of Elastic Load Balancing (ELB) and Auto Scaling, but feel limited by a dependency on ASP.NET session state? Rather than rely on sticky sessions, you can use an out-of-process session state provider to share session state between multiple web servers. In this post, I will show you how to configure ElastiCache and the RedisSessionStateProvider from Microsoft to eliminate the dependency on sticky sessions.

Background

An ASP.NET session state provider maintains a user’s session between requests to an ASP.NET application. For example, you might store the contents of a shopping cart in session state. The default provider stores the user’s session in memory on the web server that received the request.

Using the default provider, your ELB must send every request from a specific user to the same web server. This is known as sticky sessions and greatly limits your elasticity. First, the ELB cannot distribute traffic evenly, often sending a disproportionate amount of traffic to one server. Second, Auto Scaling cannot terminate web servers without losing some user’s session state.

By moving the session state to a central location, all the web servers can share a single copy of session state. This allows the ELB to send requests to any web server, better distributing load across all the web servers. In addition, Auto Scaling can terminate individual web servers without losing session state information.

There are numerous providers available that allow multiple web servers to share session state. One option is use the DynamoDB Session State Provider that ships with the AWS SDK for .NET. This post introduces another option, storing session state in an ElastiCache cluster.

ElastiCache is a web service that makes it easy to deploy, operate, and scale an in-memory cache in the cloud. ElastiCache supports both Memcached and Redis cache clusters. While either technology can store ASP.NET session state, Microsoft offers a provider for Redis, and I will focus on Redis here.

Launch an Elasticache for Redis Cluster

Let us begin by launching a new Elasticache for Redis cluster in the default VPC using PowerShell. Note that you can use the ElastiCache console if you prefer.

First, get a reference to the default VPC and create a new security group for the cluster. The security group must allow inbound requests to Redis, which uses TCP port 6379.

$VPC = Get-EC2Vpc -Filter @{name='isDefault'; value='true'}
$Group = New-EC2SecurityGroup -GroupName 'ElastiCacheRedis' -Description 'Allows TCP Port 6379'
Grant-EC2SecurityGroupIngress -GroupId $Group -IpPermission  @{ IpProtocol="tcp"; FromPort="6379"; ToPort="6379"; IpRanges=$VPC.CidrBlock }

Second, launch a new Redis cluster. In the example below, I launch a single node cluster named “aspnet” running on a t2.micro. Make sure you specify the security group you created above.

New-ECCacheCluster -CacheClusterId 'aspnet' -Engine 'redis' -CacheNodeType 'cache.t2.micro' -NumCacheNode 1 -SecurityGroupId $Group

Finally, get the endpoint address of the instance you just created. Note that you must wait a few minutes for the cluster to launch before the address is available.

(Get-ECCacheCluster -CacheClusterId 'aspnet' -ShowCacheNodeInfo $true).CacheNodes[0].Endpoint.Address

The endpoint address is a fully qualified domain name that ends in cache.amazon.com and resolves to a private IP address in the VPC. For example, ElastiCache assigned my cluster the address below.

aspnet.k30h8n.0001.use1.cache.amazonaws.com

Configuring the Redis Session State Provider

With the Redis cluster running, you are ready to add the RedisSessionStateProvider to your ASP.NET application. Open your project in Visual Studio. First, right click on the project in Solution Explorer and select Manage NuGet Packages. Then, search for “RedisSessionStateProvider” and click the Install button as show below.

Manage NuGet Packages

NuGet will add a custom session state provider to your project’s web.config file. Open the web.config file and locate the Microsoft.Web.Redis.RedisSessionStateProvider shown below.

<sessionState mode="Custom" customProvider="MySessionStateStore">
  <providers>
    <add name="MySessionStateStore" type="Microsoft.Web.Redis.RedisSessionStateProvider" host="127.0.0.1" accessKey="" ssl="false" />
  </providers>
</sessionState>

Now replace the host attribute with the endpoint address you received from Get-ECCacheCluster. For example, my configuration looks like this.

<sessionState mode="Custom" customProvider="MySessionStateStore">
  <providers>
    <add name="MySessionStateStore" type="Microsoft.Web.Redis.RedisSessionStateProvider" host="aspnet.k30h8n.0001.use1.cache.amazonaws.com" accessKey="" ssl="false" />
  </providers>
</sessionState>

You are now ready to deploy and test your application. Wasn’t that easy?

Summary

You can use ElastiCache to share ASP.NET session information with multiple web servers and eliminate the dependency on ELB stick sessions. ElastiCache is simple to use and integrates with ASP.NET using the RedisSessionStateProvider available as a NuGet package. For more information about ElastiCache, see the ElastiCache documentation.