Enforce serializable session state access for InProc? - asp.net

I have heard advice in the past to use SqlServer / StateServer early on in a project, so when you scale you don't fall into the trap of a developer using non-serializable objects InProc and it breaking when moving to SqlServer / StateServer later.
For the moment we have no need to use InProc of SqlServer session state, as we're just launching, but we'll probably need to scale reasonably quickly.
Does anyone have any reccomendations in enforcing serializable objects when using InProc? Perhaps creating a wrapper?

The important thing to remember that using SqlServer / StateServer is not just about scaling out (web farms). Even on one server you can run into problems when just using InProc sessions. Basically when using InProc any sessions that are "live" when the app pool recycles are lost. To put this in context, you may be running a purchase funnel and are storing something in the session that is critical to the process (why that may be bad practise is another conversation). Anyway, if that session information is corrupt / lost then the user won't be able to continue. So the app pool recycles and loses any currently live sessions - so any customers currently in your purchase funnel drop out and are potentially lost.
For that reason alone I'd always recommend running SqlServer sessions at a minimum (even locally). Better architecture generally negates any performance issues. If you do run into performance issues you could potentially look at 3rd party StateServer implementations that I'd should be faster.
If after reading the drawbacks of running InProc on a live server you're still happy to be doing that (they're your reasons, so that's fine) the only thing I could recommend is to change your dev server (or test) to run using SqlState and leave Live running InProc. That way you see any problems in the environment that isn't using InProc and can fix them in a none live environment. Then if you decide to switch Live over, you'll know that it won't need any extra dev effort and everything should be OK.

Related

Is InProc Session State unstable under load

In this question there's a comment with a few upvotes that states:
InProc session state is known to be highly unstable under load. If it's abused (happens all the time), then Session["foo"] = null will perform better than Session.Remove["foo"]. The garbage collector should clean up the mess of excessive session variables
This concerns me as all of my web apps make heavy use of session state (account info, baskets, payment details, user preferences etc.).
I can't seem to find any evidence to back up this claim, can someone debunk this or explain why this is correct. Am I wrong to be storing such info in session? I'm not looking for a pros and cons of InProc vs SQL, I'm aware of the differences.
All of my apps run on a single or dedicated webserver so I've never seen any benefit or point in moving to SQL for session state.
InProc Session State is stable and you don't have to worry about it. I don't know why he called it unstable but I guess he might have thought one of the following reasons while commenting:
If your application gets too much load; when you scale it, you have to use sticky session (for InProc SessionState) to redirect the requests to the same server for a client otherwise session object would not persist.
If an application has memory leaks or inconsistencies, heavy load will most probably trigger the application to reset and this will cause all the session data be lost so that current users' active pages might get errors since their session datas are lost.
Session object is locked out for the entire request (for that user only) to prevent multiple pages to write into the session so that if concurrent requests are made for example, they have to wait for each other to write data into Session. But it happens both in SQL and InProc SessionState.
I saw banking applications which work with InProc SessionState and there is nothing unstable about it.

ASP.NET SQL SessionState or Custom solution?

The ASP.NET SQL SessionState provider seems excessive for my requirements. SQL Server has to be 'configured' to support it and I have questions about how optimized it is (i.e. is there one db hit to fetch the whole session or one for every session item requested?).
I think I could implement a custom solution very easily that I would understand and easily redeploy to other projects. Is there something fundamental I haven't considered here and an obvious reason why the built in SessionState handler is the 'best' way to go?
Just to clarify, our applications run on single servers at the moment. My main motivation for doing this is to enable Session to persist across IIS restarts and therefore provide more reliability for users.
you could use StateServer mode.
StateServer mode stores session state in a process, referred to as the ASP.NET state service, that is separate from the ASP.NET worker process or IIS application pool.
Using this mode ensures that session state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm.
more info at http://msdn.microsoft.com/en-us/library/ms178586.aspx
It takes just minutes to setup SQL session state server (assuming you have SQL server already running). I can't imagine that you can write anything in less time than it would take to at least try out what already exists and is free and supported by MS.
A proven, built-in/off-the-shelf solution is always better place to start than custom. You may still end up with a custom solution, but don't pick it because you didn't bother to test what is already available to you.

ASP.NET Session State Performance Benchmarks

I have found a lot of great information comparing InProc, StateServer, and SQLServer for ASP.NET state management, but I can't seem find any performance benchmark comparisons. It is clear that InProc is faster than StateServer which in turn is faster than SQLServer, but it isn't clear how much faster. I realize that it's going to vary greatly by application and environment, but having a relative idea of how they compare would be valuable.
Do you know of any benchmarks that have been performed that you could share? or have any personal experience with this? Thank you!
I have personal experience but no benchmarks or actual recorded metrics to share. We initially created an Asp.Net site which stored a larger than usual user object in session using the InProc method. We found that the size of the object and the nature of our error handling libraries caused 2 undesired behaviors. The first was a recycling of the application pool at random intervals during processes. Because the w3wp.exe process would recycle itself midstream, it would essentially dump the session and the object would be lost. This caused other code to kick in and repair the session, and it increased the latency of our transactions. We also found (although it was not a terrible problem and I only discovered while attempting to debug the memory loss I just described) that the size of the object in session along with some of the objects being loaded in libraries for the page itself would cause the w3wp.exe to page itself in and out repeatedly. For smaller requests that only involved either the session object or these library objects but not both, there was no odd paging behavior on the process.
In moving from InProc to StateServer, we discovered an immediate return on the recycling. The pool actually ended up recycling less, and even when it did our session objects stayed in separate memory. We also noticed that this created a universal "library only" condition as described above with respect to paging and we did not experience it again (though admittedly I stopped checking after 1 month of uptime). We did pick up a very small latency in accessing certain framework libraries at the time, but when we upgraded from 2.0 to 3.5, these access anomalies disappeared entirely. We're hoping for similar behavior when we upgrade from 3.5 to 4.0 soon.
A test site using SQLServer as a state controller was attempted, and the only latency we found was the initial session creation/storage. Subsequent calls to update/access the session in SQL provided no real difference from the StateServer option. I don't have any metrics, but there was nothing on any of the systems that indicated a difference in behavior. Timestamps had comparable differences in all aspects. A benefit we did gain, though it was of rare usage potential, was that we were able to couple our user database directly with the session state server and compare timestamps, statuses, and other specialized session variables directly. We had no real need for this feature, and the StateServer option was already in full swing on our production servers, so a determination to leave it as it was.
In the end, it wasn't speed so much as memory usage that persuaded us to dump InProc for StateServer. The benefits of access speed definitely did not outweigh the need to have the data in memory in the first place.
There's a good benchmarks the DevOps Guys.
http://www.slideshare.net/devopsguys/best-performing-aspnet-session-state-providers comparing
ASP.Net In-Proc
ASP.Net Session State Server
ASP.Net Sql Server
CouchBase
MongoDb
RavenDb
Redis (this one, TheCloudlessSky, not this one AngiesList)
AppHarbor also recommends memcached, but doesn't have a benchmark.
http://support.appharbor.com/kb/tips-and-tricks/using-memcached-backed-sessionprovider
and provides a Session Provider https://github.com/friism/Memcached-Providers

Session mode in ASP.Net?

Which session mode in the following ,should i implement for my ASP.Net website?
1)InProc .
2)State Server.
3)SQL Server.
4)Custom.
It depends entirely on your circumstances and the type of website you wish to operate.
I suspect your expected volumes of traffic and the hardware it is running on is also a large factor.
Can you give us more information.
Performance considerations
InProc - Fastest, but the more session data, the more memory is consumed on the web server, and that can affect performance.
StateServer - When storing data of basic types (e.g. string, integer, etc), in one test environment it's 15% slower than InProc. However, the cost of serialization/deserialization can affect performance if you're storing lots
of objects. You have to do performance testing for your own scenario.
SQLServer - When storing data of basic types (e.g. string, integer, etc), in one test environment it's 25% slower than InProc. Same warning about serialization as in StateServer.
Robustness
InProc - Session state will be lost if the worker process (aspnet_wp.exe) recycles, or if the appdomain restarts. It's because session state is stored in the memory space of an appdomain. For details, see KB324772.
StateServer - Solve the session state loss problem in InProc mode. Allows a webfarm to store session on a central server. Single point of failure at the State Server.
SQLServer - Similar to StateServer. Moreover, session state data can survive a SQL server restart, and you can also take advantage of SQL server failover cluster, after you've followed instructions in KB 311029.
The above is an extract from an article by Peter A. Bromberg available here
There's no one clear answer. It depends on how your app works, how many servers you have, what your tolerance for failure is etc. I would read up on the differences and then make an informed choice.
Providing you make everything that you are storing in the session serializable from the beginning, it is usually fairly easy to switch from one mode to another, unless you are using things like the Session_End event, which only fires when using in proc mode.
The default is InProc, and that works fine for most small and moderate size web sites. You just use it, you don't have to implement anything at all.
If you have any special curcomstances, like load balanced servers or extreme amounts of users, you would need some of the other methods.

Allowing Session in a Web Farm? Is StateServer Good Enough?

First of all to give you a bit of background on the current environment. We have a number of ASP.NET applications, all of which use session for certain aspects. We are "Load Balanced" over multiple servers due to traffic levels, however, our load balancing is set to use "Sticky Sessions" as currently all web applications are set to use "InProc" for session state.
We are looking at being able to remove the "Sticky Sessions" configuration on our load balancer, as due to our traffic loads servers can and do get overloaded. We want to go with a more balanced approach, but must be able to use session.
I know that SqlServer for session state will work, but for reasons beyond our control, we cannot use SqlServer to store our state. In researching it seems that StateServer is our best bet. We have an additional server, with loads of memory sitting around. This server could be our StateServer for the entire Web Cluster. We just want to know the following things.
1.) Besides any potential serialization issues with the switch from InProc to StateServer, are there any major known issues with losing session objects or generating errors with the above listed environment?
2.) Aside from the single point of failure, and slighly slower performance are there any other gotchas that we need to be aware of with using StateServer.
3.) Are there any metrics that show the performance differences between the three types of state storage?
Here is a decent FAQ on asp.net state: http://www.eggheadcafe.com/articles/20021016.asp
From that Article, here is some information on StateServer:
In a web farm, make sure you have the same MachineKey in all your web servers. See KB 313091 on how to do it.
Also, make sure your objects are serializable. See KB 312112 for details.
For session state to be maintained across different web servers in the web farm, the Application Path of the website (For example \LM\W3SVC\2) in the IIS Metabase should be identical in all the web servers in the web farm. See KB 325056 for details
I have only used sql and in-proc. But these 3 that apply when using sql server apply as well:
Avoid storing too much information in the session, as it affects both in serialization and data transmitted over the network.
Make sure you don't have anything that depends on the Session_onEnd. This is just not available for out of process sessions.
Turn off session on pages that doesn't uses it. This don't make a difference for in-process session, but for out of process it will save you a lot.
Make sure your server etag ids are synchronized across the web farm otherwise caching at client browsers will be upset.
Have you reviewed your code in detail to make sure everything can be serialized out of process and across a LAN efficiently?
Are you solving the main performance problem within your system? I ask because the database is the typical source of contention.
My main motivation for moving away from sticky sessions was operational flexibility i.e. cycle down a problematic server or to deploy a software upgrade. So having implemented a central session state service make sure you take full advantage from an operational stand point.
In my experience we've found out that native state server or even using SQL Server for sessions is a very scary scenario as both have issues (mainly performance). By the way, we are also using sticky sessions.
I think you can explore other products for this to achive the absolute best. A free option would be Velocity but it is still not released.
And another comprehensive but proven product will be (Very expensive actually) NCache. THis will even help in your serilizations with less cost, If you use their API's it will be even better results.
Take a look and see which looks best for you.
About SQL Server, you server will die very soon if you have enough number of hits coming in (I belive you have some hits already which yielded you to do Web Farm or you do it just for the sake of redundancy)
Bottom line: We are evaluating Velocity because NCAchce is really expensive. However advantages are huge.
We are using StateServer for a very small web farm with only two nodes for a few hundred users.
I'm not responsible for its operation but I remember only two issues in two years where the service had to be restarted because it crashed.
I would like to another one more point to the accepted answer:
Make sure the version of framework dlls is the same.
In my case the System.Web dll versions were different as a few windows updates were skipped on one of the servers of the farm.

Resources