ASP.NET SQL Server Session State extremely slow - asp.net

I'm having problems with an ASP.NET application that I need to web-farm, however just logging into my application takes at about 15 seconds
I did a little experiment where I created a non-web farmed version of my application and then used INPROC session state instead, and the login time is immediate. In this test instance, I'm running SQL Express on the same machine.
I know session state on SQL server is slower, but there is no way it should be THIS slower. Any suggestions on how to track down the issue?
This is my session state:
<sessionState mode="SQLServer" timeout="60" sqlConnectionString="Data Source=localhost;Integrated Security=SSPI;" sqlCommandTimeout="30" cookieless="false" useHostingIdentity="False" regenerateExpiredSessionId="True" />
I've tried both using a username password as well as integrated security.

Relational databases are Atomic (ACID), so give pretty poor performance when everyone is hitting the same table (ASPStateTempSessions).
We had the same problem as used the SessionState mode instead, we started the ASPNet State Service on the load balancer and used that. Much better throughput.
<sessionState mode="StateServer" stateConnectionString="tcpip=localhost:42424" cookieless="false" timeout="60" />

Your question spans a wide area -
Code: What things you are pushing into the session matters a lot. If you are storing large blobs etc, serialization/deserialization happens every time session data is stored and read from the database. Can you parse the data being stored and try to find out average size? I have seen business applications storing 1mb to 2mb data on sql server with thousands of users connected but then underlying hardware was capable enough to support the throughput.
Infrastructure: How much RAM do you have on your machine? Can you try running sql trace on your aspstate database to see how many connections are coming in and how long it takes to execute the query? The problem may not be on the database end, it might be your application trying to do something when storing session information.
SQL Server session storage is not this slow, on my machine with 8gig ram and asp.net application running through visual studio (IIS Express) it takes merely a second to connect and launch the application.

The best thing you can do (if your application permits) is to completely avoid a session storage backend. If the session data fits in the HTTP headers themselves (which usally does) you can have it encoded and move back and forth with the requests themselves as cookies.
Plus most implementations of session state provider are "blocking" so you cannot have concurrent requests for the same session, turning into a huge bottleneck.
This article points to a JWT based drop-in session state provider:
http://www.drupalonwindows.com/en/content/aspnet-session-state-scaling-and-performance-issues

Related

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.

Where asp.net session is kept on iis server

i want to know where a session is stored when i set it in asp.net application. Does it consume RAM or hard disk space?
Actually, i save a datatable into a session variable. I save it into session because calculation of the datatable takes long time. In order not to calculate the datatable again, i get it from the session.
But i am curious about the time when the datatable will grow much larger than now. Will it stuck the ISS?
Thanks
Session state in ASP.NET is by default stored in process memory (which is RAM).
You can change this in web.config by altering the values of the configuration/system.web/sessionState element:
<configuration>
<system.web>
<sessionState mode="...">
</system.web>
</configuration>
The available options are:
InProc (default)
StateServer - will store in a seperate process which can be on a seperate computer
Off
SqlServer - will store state information in a sql server database
Custom - allows you to provide your own session store
Depending on how you configure the Session in your Web.Config, the Session can be stored In-Memory, Asp.NET State Server, Sql Server.
By default, the session is stored in-memory, which means the Ram. If the data-table gets large and there are a number of concurrent users, you may get an exception. Depends on how many users are accessing the system concurrently, what is the Ram on your system etc.
Session state can be stored in different places that you can choose. Here's a good explanation on MSDN
The default is in memory on the server where you web application runs, so if your session grows too large you will indeed have ram/paging problems.
But why session? Is the data in the datatable user-specific? Otherwise Cache would be more appropriate.
If you are using InProc session, then it will be stored in memory. So if you have enough memory it will be in memory. Once you hit your limit look forward to it paging out to disk.
You can also use out of process session storage like the SQL server. This is configurable in the web.config. Note that you will need to have a database configured for it. You can also check out MSDN to read up on the storage types.
Old link above, but still partially useful. Another quick look and I'm found a better link that goes more into detail.
The typical InProc session state is stored in memory of the web server.

Shrinking Session State in ASP.Net 4.0

I need more information on new feature in ASP.Net 4.0 Shrinking Session State.
My question is I am using session-state provider that stores data in a Microsoft SQL Server database. If I add compressionEnabled="true" key in web.config file as shown below and not do any code change, will application performance improve. How to check whether compression of sessions are happening and stored in SQL Server. Can any one share any sample code to implement and test this.
<sessionState
mode="SqlServer"
sqlConnectionString="data source=dbserver;Initial Catalog=aspnetstate"
allowCustomSqlDatabase="true"
compressionEnabled="true"
/>
Once you enable compression, session data will be GZip compressed when you use a state server or SQL server but will cost additional CPU cycles on your web server to perform the compression/decompression. This will result in smaller data being transmitted over the wire which will improve performance. Notice that while this reduces the actual session data it is still considered as bad practice to store big amounts of data into the session.

How to implement a Windows Service to manage Session state?

I'm working on an ASP.NET MVC web application that will be deployed across multiple load-balanced servers. With this setup, a user might have one request served by server A and the next request will be served by ServerB or ServerC.
We don't want to store Session Data in the database, as we're trying to minimise database hits where ever possible. As such, we need to have the HttpSession managed and stored on another server.
My understanding is that this is possible by using a Windows Service that will manage this for me, but I'm unfamiliar with how to implement this. Can somebody point me at some good documentation on how to do this? Or any pitfalls or other points to take into consideration? Thanks
You need to dedicate a machine that will host the Windows NT service and which must have .NET installed (well you could use one of the web servers as state server but IMHO this would be a very bad idea):
net start aspstate
And then instruct your application to use this server:
<system.web>
<sessionstate
mode="stateserver"
cookieless="false"
timeout="20"
server="127.0.0.1"
port="42424"
/>
</system.web>
where of course you would replace 127.0.0.1 with the IP address of the server hosting the NT service.
Note1: don't forget to decorate the objects you intend to store into session with the [Serializable] attribute.
Note2: this is a good solution in a load balanced environment but if you are looking for a real failover clustering you should use SQL server.
You may read more details about ASP.NET session state on MSDN.
As usual, Peter gives this issue good coverage...
http://www.eggheadcafe.com/articles/20021016.asp
Another alternative you may want to consider is Memcached Providers - it allows you to store session state in a memcached instance; optionally using SQL Server as a fallback. The best of both worlds, IMHO.

ASP.Net Persisting Data Across the Application

How Can I persist a User-Specific data for an ASP.Net application.
I tried Session Variable - Not good when the worker process recycles.
I need something that can be accessed GLOBALLY by any class of my application.
Advice most welcome.
I tried to utilize asp.net session State Server but I got some DLLs crashing because they are Unserializable.
Is there any other way to have a persistent variable across the application?
ASP.NET session state can be configured to persist to a database.
Here is a tutorial on how to set that up.
Store Data in a Database (such as SQL Server).
You should use Session. You can access session state globally in a class like this...
HttpContext.Current.Session
To avoid losing sessions by the worker process recycling, use StateServer mode.
You can change the Session State Server to not be in process which will make it far more stable and also seperate it from the worker process (You'll need to be able to start the Asp.NET State Service on the server if it's not already running)
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20"/>
Also if you need to share it across applications in the same domain you should be able to give them the same machine key
Theres nothing you can really do about the process recycling. If you use the Cache smartly to retain information in a more global sense but you still have the same worker process limitation.
I try and design my app in a n-tier setup with business entity objects. The factory methods for my objects use the cache kind of like a lazy instantation pattern. If its in the cahce, pull it. If not, put it into the cache for next time.
i.e
MyAppsNameSpace.MyBusinessLayerNameSpace.MyObject.GetObject(objectID)
now when this returns my object, it may be from the cache or may not, if the object is under high usage then it will be probably be cached.
This can be used throughout your entire app and because the caching mechanism is maintained centrally you dont really have to worry about it.
You could use the Profile Provider with a SQL database as your backing store.
See this MSDN Article
If you lose data when the worker process recycles then you should stop using the InProc persistance mode for the Session. Use StateServer or SQL Server. Ultimately you could build your own session persistance module if neither satisfies you.

Resources