I was investigating one of the new offerings in windows azure. Specifically "Websites" and i'm not able to find anything about how it handles session data. Does anybody know? I moved the slider up to 2 instances and it all seems to "just work", but I would feel better about using it if I knew for sure it was sharing session data (or not?)
If you'd like to learn more about the architecture of Windows Azure Web Sites, I would suggest watching this session from TechEd 2012 Windows Azure Web Sites: Under the Hood
You have some options to solve this problem
sql solution
table storage solution
memcache solution
Sql is the classic solution. Sql handles all sessions with classic sql requests.
Table storage works wonders (in my experience). It's really easy to scale and really simple to implement (just a few lines of code on your webconfig).
Memcache solution is the best solution. Azure provides a cluster of "cache servers" to store session (or other serializable objects). It's really easy to scale and works really really fast. I am using this solution on my production environments with 0 problems and a really good performance results.
In order to implement Memcache, you just need to add those lines on your web.config:
<configuration>
<configSections>
<section name="dataCacheClients" type="Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core" allowLocation="true" allowDefinition="Everywhere"/>
<!-- more config sections here -->
</configSections>
<dataCacheClients>
<dataCacheClient name="default">
<hosts>
<host name="YOUR_NAME_HERE.cache.windows.net" cachePort="YOUR_PORT_HERE"/>
</hosts>
<securityProperties mode="Message">
<messageSecurity authorizationInfo="YOUR_KEY_HERE">
</messageSecurity>
</securityProperties>
</dataCacheClient>
</dataCacheClients>
<!-- more configurations here -->
Summary
If you don't care about the costs and you wish to archieve best performance possible, go for memcache solution. If you need to keep your costs really low, go for table storage.
Since the linked video above is quite out of date, I thought I would share what I was able to find regarding sessions on Azure.
Azure makes use of Application Request Routing.
ARR cleverly keeps track of connecting users by giving them a special cookie (known as an affinity cookie), which allows it to know, upon subsequent requests, to which server instance they were talking to. This way, we can be sure that once a client establishes a session with a specific server instance, it will keep talking to the same server as long as his session is active.
Reference:
https://azure.microsoft.com/en-us/blog/disabling-arrs-instance-affinity-in-windows-azure-web-sites/.
Are you targetting ASP.NET 4.5?
If you don't explicitly configure any providers with 4.5, it will default to using the ASP.NET Universal Providers which are now included in Machine.config. So it will be using a SQL Session State provider by default. I would expect it to use a local DB, though, so I'm not sure how it would be sharing the state.
You could test it by opening up some sessions, then taking the number of instances back down to one and see if some sessions lose state or not.
The load balancer could be using session affinity, in which case, you might not notice if it's not sharing session state.
How many web roles do you have? If you keep it to 1 you should be ok, but you can read the details here about how multiple web roles are going to create the same session state problems you'd encounter if you were running a web farm... When running a web farm an option is keeping session state in your db. So as you can imagine, if you needed to run multiple web roles then you could lean on sql Azure (though Table Storage is really cool, and likely a great fit for something like session state)
But to more directly answer your question, you can use multiple web roles to distribute processing load, and a web role is just a "front-end web application and content hosted inside of IIS". So again, if you're only using one web role then your app probably is working just fine. But just be aware that if you ever need to scale your web roles out, it will bork your Session persistence up.
Related
I'm writing a web application using ASP .NET MVC 3. I want to use the MemoryCache object but I'm worried about it causing issues with load balanced web servers. When I google for it looks like that problem is solved on the server ie using AppFabric. If a company has load balanced servers is it on them to make sure they have AppFabric or something similar running? or is there anything I can or should do as a developer for this?
First of all, for ASP.NET you should look at the ASP.NET Cache instead of MemoryCache. MemoryCache is a generic caching API that was introduced in .NET 4.0 to provide an equivalent of the ASP.NET Cache in non-web applications.
You're correct to say that AppFabric resolves the issue of multiple servers having their own instances of cached data, in that it provides a single logical cache accessible from all your web servers. Before you leap on it as the solution to your problem, there's a couple of things to consider:
It does not ship as part of Windows Server - it is, as you say, on
you to install it on your servers if you want to use it. When
AppFabric was released, there was a suggestion that it would ship as
part of the next release of Windows Server, but I haven't seen
anything about Windows Server 2012 that confirms that to be the case.
You need extra servers for it, or at least you're advised to have
them. Microsoft's recommendation for AppFabric is that you run it on
dedicated servers. Which means that whilst AppFabric itself is a free
download, you may be incurring additional Windows Server licence
costs. Speaking of which...
You might need Enterprise Edition licences. If you want to use the
High Availability features of AppFabric, you can only do this with
servers running Enterprise Edition, which is a more expensive licence
than Standard Edition.
You might not need it after all. Some of this will depend on your application and why you want to use a shared caching layer. If your concern is that caches on multiple servers could get out of sync with the database (or indeed each other), some judicious use of SqlCacheDependency objects might get you past the issue.
This CodeProject article Implementing Local MemoryCache Invalidation with Redis suggests an approach for handling the scenario you describe.
You didn't mention the flavor of load balancing that you are using: "sticky" or "stateless". By far the easiest solution is to use sticky sessions.
If you want to use local memory caches and stateless load balancing, you can end up with race conditions the cross-server invalidation messages arrive late. This can be particularly problematic if you use the Post-Redirect-Get pattern so common in ASP.Net MVC. This can be overcome by using cookies to supplement the cache invalidation broadcasts. I detail this in a blog post here.
I saw this post in StackOverflow that encouraged me to use Session State in my Azure application.
I followed this post and generated the tables, but my problem is I can't have an additional Database for that, I'd have additional costs too.
My question is: there's a way to make the Session State know that it should run in both tables, even if I don't have a specific connectionString pointing to the database ASPState?
If you need session state then I would recommend skipping the SQLAzure provider and using the AppFabricCacheSessionStoreProvider instead. It is now in production, in some of your links above it wasn't yet. I have found it pretty easy to use but there are additional costs. But if you use SQL Azure you could end up with additional costs pretty soon anyway as the database size grows.
Having said that, I am in the process of eliminating session use in my app on Azure. Make it much easier to add more server with no worries, unless your app has sessions deeply ingrained.
It seems some web architects aim to have a stateless web application. Does that mean basically not storing user sessions? Or is there more to it?
If it is just the user session storing, what is the benefit of not doing that?
Reduces memory usage. Imagine if google stored session information about every one of their users
Easier to support server farms. If you need session data and you have more than 1 server, you need a way to sync that session data across servers. Normally this is done using a database.
Reduce session expiration problems. Sometimes expiring sessions cause issues that are hard to find and test for. Sessionless applications don't suffer from these.
Url linkability. Some sites store the ID of what the user is looking at in the sessions. This makes it impossible for users to simply copy and paste the URL or send it to friends.
NOTE: session data is really cached data. This is what it should be used for. If you have an expensive query which is going to be reused, then save it into session. Just remember that you cannot assume it will be there when you try and get it later. Always check if it exists before retrieving.
From a developer's perspective, statelessness can help make an application more maintainable and easier to work with. If I know a website I'm working on is stateless, I need not worry about things being correctly initialized in the session before loading a particular page.
From a user's perspective, statelessness allows resources to be linkable. If a page is stateless, then when I link a friend to that page, I know that they'll see what I'm seeing.
From the scaling and performance perspective, see tsters answer.
We have four public websites running on the same database with different schema(Oracle). All of them are 'AAA' application and have "20,0000PV~500,000PV"daily. 90% data in websites are read-only and updated daily(By Batch). Less than 10% data, such as announcement, are updated manually. We are looking for the best practices to solve following concerns.
Improve website availability. Though we have a BCP database, it might need 1~2 hours to recover 4 websites in case database server is down.
Since most data are read-only, we are considering using in-memory db (hsqldb) or cache component(ehcache) to improve performance. As default, we are using ibatis and hibernate. Ehcache might not only be used on Level-2 cache, but also page cache.
We trends to build web services framework(restful) instead of java solution since mobile application might reuse them. Not very sure if it is a good idea to run website on web service on the same web application server. We have active-active HTTP and web servers.
On-line shopping is in the future plan.
Add database processes, make it at least 4 for serving each website.
Consider memcache
The same application server can run multiple applications. Not a problem it there is a good amount of RAM. However, if there is an overwhelm of users, you can always move particular applications to a different server. But, a better idea is to wait and see which service is worth that privilege.
Another web-application, too much of security and state management. Better put it in a new server.
We are having issues with IIS6 slowdowns when using more than 1.2GB of RAM in a single worker and would like to use more workers. However looks like ASP sessions are made by worker and when the browser accesses some page through another worker it losts the ASP session.
Do you have some tips on how to solve this problem?
We are considering to use some other way to manage session separately from IIS (not database, maybe memcache?). Do you recomend something?
Note.: The application is full of legacy code and we need to avoid big changes in code.
I've had a similar scenario with a legacy app in the past and ended up writing a simple component to serialize the ASP Session object to & from the database.
I have written a central session store for classic ASP in the past using Redis as a storage layer. The code is freely downloadable at https://gitlab.com/erik4/classic-asp-book-examples
It uses a redis ActiveX/COM component, available here.
Using a central session store using Redis will allow you to use as many worker processes as needed.
If you want a detailed explanation of the implemantation, there's an accompanying book, but the example code should work out of the box.