If you are storing ASP.NET session in webserver memory, then when a webserver dies, you lose all the sessions on that server. This results in poor customer experience, as they are logged out in the middle of some journey and have to log back in, losing their state, sometimes resulting in data loss. A common solution to avoid such problem is to store session outside the webserver. You can use a separate cluster of servers where you run some software that lets your application store session. Some popular technologies for storing session out-of-process are SQL Server, Memcached, Redis, NoSQL databases like Couchbase. Here, I present some performance test results for an ASP.NET MVC 3 website using SQL Server vs Redis vs Couchbase.
Test Setup
Configuration of the servers are as follows:
- Web Server: 2 x Windows 2008 R2 Enterprise x64 Virtual Machine running IIS 7.5, each with 4 x vCPU, 2100 MHz, AMD Opteron Processor 6172
- Load Balancer: HAProxy on one Linux VM.
- Load generator: 2 Linux VM running JMeter
- Test Plan: Perform a Login and then use the session cookie generated to visit Home Page. Ensure home page shows the logged in user’s name.
SQL Server ASPState DB as Session Store
SQL Server 2008 R2 configuration is:
- CPU MAX SPEED: 2100 MHz
- CPU NUM: 4
- CPU VERSION: AMD Opteron(TM) Processor 6172
- RAM: 8 GB
Now the juicy stuff: I am able to produce 567 requests / sec, while the response time median is 48 ms. Those who think SQL Server is slow, not for in-memory stuff, think again.
When I restarted website on one webserver, it resulted in a small fraction of error and a spike in response time:
Redis
Redis runs on two Linux VM. Each running 3 instances. They are Master-Slave clustered. 3 Master, 3 Slave. Configuration of each Linux VM is:
- CPU: Intel(R) Xeon(R) CPU E5540 @ 2.53GHz
- 4 vCPU
- 8 GB RAM
Redis gives 707 requests/sec. The response time median is also improved 38 ms. This is about 150 Req/sec more than the SQL Server result.
Notice the periodic jump in response time? I have seen this happen consistently with Redis setup. This must be when Redis decides to take a snapshot of its memory, and dump it to the disk.
Restarting one webserver results in a small fraction of error. However, I have experienced a total outage on the website when a Redis master node was killed, when I was using the Microsoft’s Redis Session State provider implementation. But when I used Alex Simonov’s Redis ASP.NET Provider, which uses StackExchange Redis client library, it was able to immediately failover to other surviving nodes, without causing an outage on the website.
Couchbase
Couchbase is running on 2 x Windows servers:
- CPU MAX SPEED: 2100 MHz
- CPU NUM: 4
- CPU VERSION: AMD Opteron(tm) Processor 6172
- RAM: 8 GB
Couchbase offers two types of storage, a Memcached-based fully in-memory storage, and a disk-based storage, where data is first written in the memory queue, and then flushed to disk when the queue is full. I have used Memcached in-memory store for the session store.
Load test result looked bad:
This is slower than SQL Server! However, looking at the code, I see the Session State provider implementation is not as optimal as SQL Server or Redis Session State implementation. Those hit the server once per page hit. But the Couchbase implementation hits 4 times per page hit. It is possible when Couchbase releases a better implementation, it might outperform SQL Server and Redis.
Couchbase dashboard confirms the 4x hit observation. For 400 hits to the webservers per second, it results in more than 1.5K hits to Couchbase.
Conclusion
If you want to stay pure Microsoft stack, go for SQL Server-based session. You should setup database mirroring and put the mirrored database on ASP.NET connection string so that when primary SQL Server node goes down, the secondary comes up and the application is able to detect it right away. If you have no issues mixing Linux in the stack, then Redis is an awesome technology. You can also use Microsoft’s compilation of Redis that runs on Windows.