views:

2406

answers:

8

Session variables are normally keept in the web server RAM memory.

In a cluster, each request made by a client can be handled by a different cluster node. right?!

So, in this case...

  • What happens with session variables? Aren't they stored in the nodes RAM memory?
  • How the other nodes will handled my request correctly if it doesn't has my session variables, or at least all of it?
  • This issue is treated by the web server (Apache, IIS) or by the language runtime (PHP, ASP.NET, Ruby, JSP)?

EDIT: Is there some solution for Classic ASP?

A: 

In ASP.NET you can persist session data to an SQL Server database which is common to all web servers in the cluster.

Once configured (in the web.config for your site), the framework handles all of the persistance for you and you can access the session data as normal.

Chris Roberts
How about complex data stored in session variables, like objects references?
Daniel Silveira
Anything that can be serialised (including complec objects) can be stored, I believe.
Chris Roberts
+4  A: 

There are 3 ways to store session state in ASP.NET. The first is in process, where the variables are stored in memory. The second is to use a session state service by putting the following in your web.config file:

<sessionState
    mode="StateServer"
    stateConnectionString="tcpip=127.0.0.1:42424"
    sqlConnectionString="data source=127.0.0.1;user id=sa;password="
    cookieless="false"
    timeout="20" />

As you can see in the stateConnectionString attribute, the session state service can be located on a different computer.

The third option is to use a centralized SQL database. To do that, you put the following in your web.config:

<sessionState
    mode="SQLServer"
    stateConnectionString="tcpip=127.0.0.1:42424"
    sqlConnectionString=
     "data source=SERVERHAME;user id=sa;password="
    cookieless="false"
    timeout="20"
/>

More details on all of these options are written up here: http://www.ondotnet.com/pub/a/dotnet/2003/03/24/sessionstate.html

amdfan
Which solution is better? StateServer or SQLServer?Please, answer @ http://stackoverflow.com/questions/224039/
Daniel Silveira
+4  A: 

Get a Linux machine and set up http://www.danga.com/memcached . Its speed is unbeatable compared to other approaches. (for example, cookies, form hidden variables, databases)

yogman
What is this? Can you explain a little better?
Daniel Silveira
memcached lets you cache (note, not store -- it's not guaranteed to be persistent) data for a given key. So, you'd take the session key from the client request and lookup the session data from memcached. It's fast, so the one instance could be shared by all members of the cluster.
TimB
even better, set memcached on all webservers. the clients will use a hash of the key to distribute the load and use more available memory.
Javier
+2  A: 

As with all sorts of thing, "it depends".

There are different solutions and approaches.

As mentioned, there's the concept of a centralized store for session state (database, memcached, shared file system, etc.).

There are also cluster wide caching systems available that make local data available to all of the machines in the cluster. Conceptually it's similar to the centralized session state store, but this data isn't persistent. Rather it lives within the individual nodes and is replicated using some mechanism provided by your provider.

Another method is server pinning. When a client hits the cluster the first time, some mechanism (typically a load balancer fronting the cluster) pins the client to a specific server. In a typical client lifespan, that client will spend their entire time on a single machine.

For the failover mechanism, each machine of the cluster is paired with another machine, and so any session changes are shared with the paired machine. Should the clients pinned machine encounter an issue, the client will hit another machine. At this point, perhaps due to cookies, the new machine sees that it's not the original machine for the client, so it pings both the original machine, and the paired machine for the clients session data.

At that point the client may well be pinned to the new machine.

Different platforms do it in different ways, including having no session state at all.

Will Hartung
+4  A: 

To extend @yogman's answer.

Memcached is pure awesomeness! It's a high performance and distributed object cache.

And even though I mentioned distributed it's basically as simple as starting one instance on one of your spare/idle servers, you configure it as in ip, port and how much ram to use and you're done.

memcached -d -u www -m 2048 -l 10.0.0.8 -p 11211

(Runs memcached in daemon mode, as user www, 2048 MB (2 GB) of RAM on IP 10.0.0.8 with port 11211.)

From then on, you ask memcached for data and if the data is not yet cached you pull it from the original source and store it in memcached. I'm sure you are familiar with cache basics.

In a cluster environment you can link up your memcached's into a cluster and replicate the cache across your nodes. Memcached runs on Linux, Unix and Windows, start it anywhere you have spare RAM and start using your resources.

APIs for memcached should be generally available. I'm saying should because I only know of Perl, Java and PHP. But I am sure that e.g. in Python people have means to leverage it as well. There is a memcached wiki, in case you need pointers, or let me know in the comments if I was raving too much. ;)

Till
+2  A: 

With Hazelcast, you can either use Hazelcast distributed map to store and share sessions across the cluster or let Hazelcast Webapp Manager do everything for you. Please check out the docs for details. Hazelcast is a distributed/partitioned, super lite and easy, free data distribution solution for Java.

Regards,

-talip

http://www.hazelcast.com

A: 

As Will said, most load-balancing approaches will use some sort of stickiness in the way the distribute forthcoming requests from the same client, meaning, a unique client will hit the same server unless that actual server goes down.

That minimizes the need of distribution of session-data, meaning that only in the eventual failure of a server, a client would loose his session. Depending on your app, this is more or less critical. In most cases, this is not a big issue.

Even the simplest way of loadbalacing (round-rubin the DNS-lookups) will do some sort of stickiness since most browsers will cache the actual lookup and therefor keep going to the first record it received, AFAIK.

It's usually the runtime that is responsible for the sessiondata, in for exampla PHP it's possible to define your own session-handler, which can persist the data into a database for instance. By default PHP stores sessiondata on files, and it might be possible to share these files on a SAN or equivalent in order to share session-data. This was just a theory I had but never got around to test since we decided that loosing sessions wasn't critical and didn't want that single point of failure.

jishi
+1  A: 

To achieve load balancing for classic ASP, you may store the user specific values in the database and pass a reference unique id in the URL as follows.

Maintain a session table in the database which generates a unique id for each record. The first time you want to store session specific data, generate a record in your session table and store the session values in it. Obtain the unique id of the new session record and re-write all links in your web application to send the unique id as part of querystring.

In every subsequent page where you need the session data, query the session table with the unique id passed in the querystring.

Example:

Consider your website to have 4 pages: Login.asp, welcome.asp, taskList.asp, newtask.asp

When the user logs in using login.asp page, after validating the user, create a record in session table and store the required session specific values (lets say user's login date/time for this example). Obtain the new session record's unique id (lets say the unique id is abcd).

Append all links in your website with the unique id as below:

  • welcome.asp?sessionId=abcd
  • tasklist.asp?sessionId=abcd
  • newtask.asp?sessionId=abcd

Now, if in any of the above web pages you want to show the user's login date/time, you just have to query your session table with the sessionID parameter (abcd in this case) and display to the user.

Since the unique value identifying the session is a part of the URL, any of your web servers serving the user will be able to display the correct login date/time value.

Hope this helps.

Nahom Tijnam