NodeBalancers - Sticky sessions or central session storage?

Hi,

For those out there who is using Linode NodeBalancers for their web servers (or any other LB solution), I have a question about sessions:

Do you use the load balancer's ability to do sticky sessions (if you do, which method - Cookie or table?) or do you store the user sessions on a centralized location, like memcached (which one do you use…) ?

PHP, for example, has an easy way of using memcached as the session storage. Just a couple of configuration parameters and you're good to go. I don't know about performance vs local disk files, though.

Thanks for your opinions and advice,

Bar.

10 Replies

I currently use a database-backed memcached approach, using Django's cached_db capability. As a belt-and-suspenders protection against replication lag, I force session-related database reads to use only the master. As long as all the app servers are on the same page (same set of memcache servers, same set of database servers, etc), life is good…

Thanks for the reply :)

Why you're not using sticky sessions?

Anyone doing what hoopycat is doing with PHP ? :)

@Bartzy:

I don't know about performance vs local disk files, though.

You can't have disk based sessions with more than one application server. If one stores the session and the next request from the same client hits another, this other has no session data.

So for loadbalanced apps, your options are (in order of speed/performance):

1. Cookie based session data

2. Sticky sessions

3. Memcached

4. DB

@Bartzy:

Why you're not using sticky sessions?

There's no need. No session data are stored on the app servers.

> Anyone doing what hoopycat is doing with PHP ? :)

Good luck!

@Azathoth:

So for loadbalanced apps, your options are (in order of speed/performance):

1. Cookie based session data

2. Sticky sessions

3. Memcached

4. DB

1 is, unfortunately, not ideal for significant amounts of data. The most you'd want to reasonably stuff into a cookie is a unique (and secure!) pointer to larger server-side storage. (Which is, not surprisingly, how sessions typically work.) Keep in mind that the cookie comes along on every HTTP request, and you probably want to avoid overflowing that into a second packet.

"Significant" is application-dependent, of course. I tend to pickle everything I can into the session because I'm lazy.

@hoopycat:

"Significant" is application-dependent, of course. I tend to pickle everything I can into the session because I'm lazy.

Everything you've said is true and of course the implementation depends on the application needs. In my experience I'm using either cookie based HMAC encrypted data (for simple stuff like auth tokens) or memcached. It is surprising how much data can fit into 4kb cookie limit, even if that's teh encrypted hex digest. I've implemented a webshop with total max of 10 items in the cart, auth data, delivery data etc… and filled maybe 2k.

Having extra packet(s) for request is imho insignificant compared to the overall resource consumption of the application, no? Even if you used memcached that's a few more TCP packets going through the stack on each request anyways (not including the session payload).

BTW: You say you pickle. I'm a Python user too, my fav framework is Pyramid. Did you consider simplejson instead?

@Azathoth:

Having extra packet(s) for request is imho insignificant compared to the overall resource consumption of the application, no? Even if you used memcached that's a few more TCP packets going through the stack on each request anyways (not including the session payload).

From looking at some packet captures, it isn't that big of a deal. It looks like spreading the request across two packets added about 0.32 ms, which is about 1% of the RTT in this case. For comparison, it took 2.49 ms for nginx to start sending the response after the end of the HTTP request was received. So, disregard that point.

But still… :-)

> BTW: You say you pickle. I'm a Python user too, my fav framework is Pyramid. Did you consider simplejson instead?

I used "pickle" as a generic term. In reality, I use Django, which "takes care" of that whole thing. I believe it encodes the data upon sheep entrails. (I make it sound like I do all this cool stuff, but I don't. It just works out of the box like that.)

@hoopycat:

From looking at some packet captures, it isn't that big of a deal. It looks like spreading the request across two packets added about 0.32 ms, which is about 1% of the RTT in this case. For comparison, it took 2.49 ms for nginx to start sending the response after the end of the HTTP request was received. So, disregard that point.

If the overhead is constant (depending on the number of packets, not the number of concurrent connections) then I can live with that. :)

So if I don't desparately need my sessions on a stable storage, using memcached is a fine idea (and for example, using each web server as a memcached node, with a replica of at least 2 ?) ?

Thanks!

Edit

–---

Why sticky sessions are faster than memcached?

I read somewhere that sticky sessions are eventually not a good solution, and you'll want to use some kind of memcached service, maybe backed by a RDBMS….

@Bartzy:

So if I don't desparately need my sessions on a stable storage, using memcached is a fine idea (and for example, using each web server as a memcached node, with a replica of at least 2 ?) ?

As long as each app server is using the same set of memcached servers, specified in the same order, and with the same hashing scheme.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct