One of the engineers watching my Data Center 3.0 webinar asked me why we need session stickiness in load balancing, what its impact is on load balancer performance, and whether we could get rid of it. Here’s the whole story from the networking perspective.
Update 2017-03-22: Added link to PROXY protocol which can be used to pass original client IP address to a web server even when SSL connection is terminated on the web server.
What Is (Network) Load Balancing?
Load balancing is one of the dirty tricks we have to use because TCP doesn’t have a session layer (yes, I had to start there). It allows a farm of servers to appear to the outside world as a single IP address.
There are numerous ways to make this trick work; the most common one involves network address translation (even in IPv6 world)
Whenever a client tries to open a new session with the shared (aka outside or virtual) IP address, the load balancer decides which server to use to serve the client, opens a TCP session to the selected server, and creates a NAT translation entry translating TCP session to virtual IP address into a TCP session to server’s real IP address.
In this scenario the return traffic MUST pass through the load balancer – the load balancer is the only point in the network that knows how to translate the “inside” TCP session into the “outside” TCP session.
You can use routing to push the return traffic through the load balancer (load balancer is the default gateway for the server farm) or source NAT where the source IP address of the original client is replaced with the load balancer’s IP address, ensuring the return traffic always goes through the load balancer.
Source NAT hides client’s real IP address from the servers, making it impossible to use geolocation or IP address-based actions (like user banning). A load balancer could insert the client’s real IP address into the X-forwarded-for HTTP header, which obviously doesn’t work if you want to use TLS (aka SSL) all the way to the web servers. (thanks to Lukas Tribus for pointing that out).
Want to know more about load balancing mechanisms, from application-level to anycast and network appliance approaches? You’ll find them all in the Data Center 3.0 webinar.
What Are HTTP Sessions?
HTTP (in all its versions) has a fundamental problem: it’s stateless. Every single request sent by the client is totally independent and not linked to the previous requests, making it impossible to implement web site logins, shopping carts…
Well, since all the features I mentioned in the previous paragraph work, there must be another trick involved: HTTP sessions implemented with specially-crafted URLs or session cookies:
- Whenever a new client visits a web site, the web server creates a session for the new client, and sends the session identifier (usually in an HTTP cookie) to the client;
- As the web server processes client requests, it stores per-client state (username, preferences, shopping cart contents…) in session variables. These session variables are automatically saved by the web server and restored when the client makes the next request based on client’s session cookie.
What Are Sticky Sessions?
Using the default configuration many scripting languages (including PHP) save session data in temporary files residing on the web server. The client session state is thus tied to a single web server, and all subsequent client requests must be sent to the same server – the HTTP sessions must be sticky.
The load balancer could implement session stickiness using additional session cookies generated by the load balancer or by caching the mapping between client IP addresses and web servers.
In the old days of short-lived HTTP sessions, the state generated by session stickiness was a major nightmare – the number of clients that had to be cached was an order of magnitude (or more) larger than the number of active HTTP sessions.
With persistent HTTP connections the difference between the number of active TCP sessions and the number of clients probably becomes negligible (or at least smaller). Would appreciate real-life data points; please write a comment.
Want to know what persistent HTTP connections are? I explained them in the free TCP, HTTP and SPDY webinar.
Do We Need Sticky Sessions?
Short answer: NO!
Every web server scripting environment I looked at has a mechanism to store client session data in data store shared among all servers, making session stickiness totally unnecessary. Using a shared data store any web server can retrieve the client session data on demand, so there’s no need for load balancer to track client-to-server mappings.
Added 2017-03-28: Some readers understood the shared data store to mean transactional database like MySQL. You should use a solution that meets your consistency requirements – in most cases memcached is more than good enough.
The only reason the scripting languages (PHP, Python…) store session data on the local web server (most often in the local file system) is because the local file system is always available and thus requires no configuration – the installation will work even when the web server admin can’t read.
To make matters worse: it takes one or two lines of web server configuration to enable the shared data store, but because “it cannot be done” in many cases the networking team buys yet another expensive load balancer giving CIO another reason to complains about the costs of data center networking.
Even More Load Balancing
I described how you can use load balancing to implement active/active data centers in Designing Active/Active Data Centers webinar, and Ethan Banks described his hands-on experience in autumn 2016 session of the Building Next-Generation Data Center webinar (you get access to recordings of autumn 2016 session as soon as you register).