ASP.NET Data Cache - preserve contents after app domain restart - asp.net

I am using ASP.NET's data caching API. For example:
HttpRuntime.Cache.Insert(my_data, my_key);
Is there any way to configure cache so its contents are preserved when the App Domain recycles?
I load many object into cache, but there is a substantial delay re-loading these every time the app domain restarts. Assume for this question that I can't prevent the appdomain restart due to a server configuration.

Is there any way to configure cache so
its contents are preserved when the
App Domain recycles?
No. The Cache object holds references in RAM. Period.
Alternatives:
Out-of-process Session state (although that's per-user)
Distributed cache
Use SQL Server as a cache (where it keeps data in memory, rather than on disk)
Write the objects to disk at the web tier
I generally prefer #3 myself, although there are scenarios where the others are appropriate.

Recycling the appdomain dumps the cache. If you want to get around this you'd need to use a distributed cache. Here's an example.

For your most expensive data you can cache the objects with a distributed cache such as Memcached or velocity. Depending on the size of the object and the length of runtime you could also serialize it to disk or to your database provided that the access speed to these resources is less than the time to create the object.
Now since the in-proc cache is super fast compared to any other solution since it just holds a reference to the memory object you will want to use it where possible. You can keep a copy of your cached object on disk until it is lost and then re-create it from that and place it in memory. Where this is tricky is when you have to expire the data so only use the cache/disk/sql combo where you won't need to expire/invalidate the data otherwise you will need to ensure that you clear both. This will also get around not being able to implement distributed caching on a shared server for example.

Related

How to load diskStore cache into memory in ehcache

I use ehcache in spring mvc. after server reset cache data save in diskStore. but after server starting not be use cache data. so I want to load diskstore content into memory.How do it? in this stackquestion Load EhCache diskstore content into memory use BootstrapCacheLoaderFactory but not appear for me.
The BootstrapCacheLoader concept is a performance optimization for Ehcache.
It allows synchronous or asynchronous prefetch of entries, in different conditions.
In order to prefetch disk entries into memory, use the DiskStoreBootstrapCacheLoader. It will iterate over the keys known by the cache and load them up to the point the memory is filled as per the cache configuration.
But given that you mention your cache is not being used after restart, you probably have another issue that this technique will not help resolve.

When to use HttpApplicationState rather than Web.Caching.Cache?

When i need to cache something in my application, i used to choose Web.Caching.Cache. But i ran into some legacy code that using HttpApplicationState instead.
Since Web.Caching.Cache is more powerful and flexible (seems MUCH more), is there a situation that better to use HttpApplicationState??
I will be very appreciate if you can show me some examples :-)
Both HttpApplicationState and Web.Caching.Cache can be used to store information that can be globally accessible throughout an ASP.Net application. However, they have very different uses.
HttpApplicationState is used to store application data that typically does not change. It is typically populated in Application_Start in Global.asax, when the application is starting. I personally have not used it much, but I believe it is typically used to store small pieces of application configuration that are global to all users of an application and which either do not change or change very infrequently. Something put into Application state will remain there indefinitely, until the app recycles. But when it recycles and restarts again, Application_Start will execute again and re-populate it.
It is important to note that HttpApplicationState is a singleton and is not thread safe. So when you make changes to it, you must lock and unlock the Application object via calls to Application.Lock() and Application.UnLock(). Read more
There are actually three different ways you can cache ASP.Net content: Page level, partial page, and data. I am going to talk about data caching, since I think that is most relevant to your question. The ASP.Net cache is used to store large quantities of application data that would be expensive to retrieve from a data store for every request. The key differences between HttpApplicationState and Cache are 1) Cache data is designed to expire and be purged from memory by a variety of triggers or conditions (time, other cache dependencies, etc), whereas HttpApplicationState will be there forever until the app recycles, and 2) Cache data can be purged from memory if a server is experiencing severe memory pressure, and you thus can never count on it being there and must always test to see if it is present, whereas HttpApplicationState will always be there.
Caching is used to store data closer to the application that does not need to be pulled from a database on every request. Caching is designed to store very large quantities of data, and an intelligent caching architecture can have an enormous positive impact on performance.

Is Caching in C# the right approach for me?

I've tried to read up on Caching in ASP.NET and still have a few questions.
When using a Sql Cache Dependency ... I know that you can specify which tables will be monitored but if a change happens to any one of those tables does it reset the entire cache? I understand that I don't want to cache tables that will have frequent changes but we could end up with a good handful of cached tables and even if each table only gets a few updates a day, that could turn into 50ish resets of the cache daily (8 hour window).
I would be creating and maintaining this cache via a GAC DLL. A large number of different applications would be accessing that GAC at any one time. Does each application maintain its own copy of the cache or is it just stored in one global location (or possibly per app pool)?
Is there a physical location on the server where I can see how much space the Cache is currently consuming? This would be extremely pertinent if each application maintains its own Cache as that could end up taking large amounts of disk space.
Is there some way to physically force the cache to rebuild itself? I could see my boss assuming that the cache was at fault for a particular issue and I'd need to be able to rule that out at the rootest level. No "changing a record and saying that SHOULD rebuild the cache" but rather "doing [Action X] and KNOWING that whatever was in the cache is now gone"
Thanks in advance for your answers and time.
SqlCacheDependency only monitors tables in the old-style SQL 2000 approach, which relies on triggers and polling. The SQL 2005+ method monitors changes at the row level, and uses Service Broker. At the level of the Cache object, changes will invalidate just the Cache entries associated with the given SqlCacheDependency (not the entire cache).
Each application has a separate copy of the Cache. If you have many apps sharing the same data, you might consider creating a separate "caching server," and have your apps get their data from there, using WCF -- basically add another tier to your app.
You can look at a couple of cache-related performance counters, but if your concern is disk space, then there's nothing to worry about, since the ASP.NET cache is stored entirely in RAM. In addition, if RAM gets too full, one feature of the cache is that it will let go of old/infrequently referenced objects to make room for new objects.
The easiest way to force the cache to be dropped is to simply recycle your application or AppPool (which happens once a day or so by default anyway). If you want something more targeted, you would need to write some code to forcibly remove certain items from the cache, either using Cache.Remove() or using linked dependencies.
from top of my head:
Only that table's content will be invalidated.
Each web application has it's own cache.
Cache is stored in memory. and see this question How to determine total size of ASP.Net cache? regarding cache size
http://bit.ly/vsqNDl this may help

Caching user data in asp.net application

What's the best way to cache web site user data in asp.net 4.0?
I have a table of user settings that track all kinds of user or session specific stuff like the state of UI elements (open/closed), preferences, whether some dialog has been dismissed, and so on. Since these don't change very often (for each user, anyway) but are looked up frequently it seems sensible to cache them. What's the best way? These are the options I've identified...
Store them in HttpContext.Current.Session directly (e.g. Session["setting_name"])
Store them in HttpContext.Current.Cache
Use a global static dictionary, e.g. static ConcurrentDictionary<string,string> where the key is a unique userID + setting name value
Store a dictionary object for each session in Session or Cache
What's the most sensible way to do this? How does Session differ from Cache from a practical standpoint? Would it ever make sense to store a dictionary as a single session/cache object versus just adding lots of values directly? I would think lookups might be faster, but updates would be slower since I'd have to re-store the entire dictionary when it changed.
What problems or benefits might there be to using a global static cache? Seems like this would be the fastest, but I'd have to manage the size. I could just flush it periodically if it hits a certain size, or keep a cross reference queue and remove things oldest first when it gets to a certain size. Does this make any sense or is it just trying too hard?
Session may end up being stored out-of-process or in a database, which can make retrieving it expensive. You would likely be using a session database if your application is to be hosted in a server farm, as opposed to a single server. A server farm provides improved scalability and reliability, and it's often a common deployment scenario. Have you thought about that?
Also, when you use Session not in-process, it ends up getting serialized to be sent out-of-process or to a database, and deserialized when retrieved, and you are effectively doing what you describe above:
... updates would be slower since I'd have
to re-store the entire dictionary when
it changed. ...
.. since, even if you use individual session keys, the entire Session object for a user is serialized and deserialized together (all at once).
Whereas, Cache would be in memory on a particular server in the farm, and therefore much more efficient than going out of process or to the database. However, something in cache on one server might not be in cache on another. So if a user's subsequent request is directed to another server in the farm, the cache on that server might not yet hold any of the user's items.
Nevertheless, I'd suggest you use Cache if you're caching for performance reasons.
p.s. Yes, you're trying too hard. Don't reinvent the wheel unless you really need to. :-)
might be better to put your information into memcached for scalability

What's the problem with Sessions in ASP .Net

I keep hearing that it's bad practise to store large object collections / anything in the session. Often during conversation it's quickly followed by: 'Just turn sessions off'
So what is the general problem with sessions? I use them a fair bit and since they 'real' session is stored behind a strongly typed container I don't really see the issue.
There is nothing wrong with session - you just need to be mindful of its limitations. To say "just turn off session" is throwing the baby out with the bathwater.
There is a huge difference between storing BIG objects and small objects in a session
The session will stay alive on a server untill it expiers, and that means those big objects pollute your available memory. If you do that with a server under load, or a server that runs many application pools, then this can cause trouble.
You dont need cookies to have a session, since ASP cal also encode that information in the urls. Also you can configure the session store to run out of process, or even to store the information inside a SQL Server (reducing the memory load on the server, and enabeling sessions across a farm)
So basically: Objects are ok - Big objects not
Here's my take -- sessions are not bad but sometimes they are overused. It can also be harder to understand a web application's flow when it relies on a lot of sessions so of course you should be careful not to get carried away.
However, you should feel free to use them anytime you need to store temporary data to be made accessible across multiple pages. In no other situation should they be used. But that situation is one for which sessions were specifically designed.
Now, if you're worried about memory consumption on the server, that's not necessarily a reason to avoid sessions. But it may be more of a reason to avoid the InProc session provider. In fact I'm not a fan of InProc sessions as they tend to expire prematurely after a certain number of recompiles in your application.
What I actually prefer and nearly always use are SQL Server sessions. They'll be slightly slower, but the benefits are numerous. They'll persist even if the server is rebooted and that makes them a very reliable choice. And of course since they're stored in the SQL file system instead of in memory, they won't make such a big hit on memory.
This article on MSDN talks about the various session providers and also explains how to configure SQL to handle your sessions. If you don't have SQL, just know that even the free SQL Server Express 2008 can be configured as your session provider.
I had thought that it largely depends on the traffic to your web site. If you are running something like amazon.com, trying to store the user's shopping cart in a session would take huge amounts of IIS allocated memory, bringing down your web server. For smaller web sites, session variables are fine to use in moderation.
Storing large objects in Session is bad, yes, but "large" is relative.
Basically, storing an object in session will keep it in memory until the session expires, so if you have a site with a high user count all storing mega-objects in their session, you'll kill your server pretty quickly.
With that being said, an argument could be made for the idea that if you have objects that are 5k+ in memory and have enough users to actually cap out a server then you can probably afford more hardware anyway.
There are also topics like server clustering and session integrity between boxes in the cluster. Some frameworks handle this, I don't know if .NET does or not.
There are two things to be careful of:
Memory consumption: if you store large data objects in session and you have many user you may well run out of memory or at the very least triggering many early recycling of your application
This is only a problem if you have multiple web servers (web farm): the session has to be stored externally (not in process) in a SQL server or a windows service so that it is accessible from different machines. This can be quite slow at times.
Session requires the user to have cookies turned on
If you're working in a web farm, you'll run into trouble.
I guess these reasons don't have anything to do with storing large objects in session, just in using sessions at all.
2 major issues come to mind...
1) Persistence of sessions across servers when you start scaling your website
2) Memory usage explosion from storing UI objects in session state
The more serious issue is the tendency to store objects in session. When you store something as innocuous as a Label from a page on your page, you get LOTS of unwanted object attributes as well. You probably just wanted the text of that label stored in your session, but along with it, you get references to the page itself...and all of a sudden, you have a massive usage of memory to store the page, its view state, and lots of unwanted attributes in memory on your server.
Check out this link about storing UI elements in session
You may want to check out this question as well.
This is an old thread although.
But I have an experience for a session problem. I would like to share it.
There is a simple flow.
One .aspx validate a client, and read a bill-html from a file (for this client), then save this html(about 2MB) in a session variable.
This .aspx will auto redirect to next .aspx, the next .aspx retrieves this html from session. Then show it to the client.
It works fine in most cases. But some clients encountered a problem: The bill he saw is not his bill, but others.
We used sniffers tools to intercept the network package.
And we saw a strange situation:
Our IIS has definitely sent the SessionID(eg: 1111111) to the client, But when the client redirects to next page and tries to access session. The SessionID(eg: 11112222) that this client brings is different.
We think that the browser of that client does not accept the SessionID.
And finally, we abandon the use of Session, and solved this problem.

Resources