What level is ObjectCache at - asp.net-mvc-3

If I add an object to the ObjectCache - at what level is this stored at? Would this be accessible by all users of the application or only a specific instance?
I've read articles that claim it is at application level but when I enumerate the cache, all I can see are the objects that instance of the application created.

As far as I know it depends on the application pool (since it stays on top of the ASP.NET stack).
This means that if you have multiple instances of the same cache on the same machine, each using a different app pool, you'll have different caches. The same if you have multiple machines.
If you want a single cache on multiple machines use a distributed cache like Windows Server Appfabric.

Related

Setting Up Ncache (Distributed?/Shared)

I have two servers, where I will be deploying the same application. Basically these two servers will handle work from a common Web API, the work that handed out will be transformed and go through some logic and loaded into DB. I want to cache the data the get loaded/update or deleted in the database, so that when the same data is referenced i can get it from the Cache (Kind of explained the cache mechanism). Now I am using Ncache and it working perfectly fine within one application. I am trying have kind of a shared cache, so that both my application can have access to. How do i go about doing it?
NCache is a distributed cache so you can continue to use that.
There is good general documentation available and very good getting started material that walks you through all the steps required.
In essence you install NCache on both the servers and then reference both servers in your client configuration (%NCHOME%\config\client.ncconf)
In cluster caches, a single logical cache instance is distributed over multiple server nodes and because the cache process is running outside the application address space, multiple applications can share and see the same exact cache data change in terms of addition, removal and update of the cache content.
Local out-proc caches are limited to one server node but as they are outside the application address space, they also support sharing of data between applications.
In fact, besides allowing multiple applications to share data, NCache supports a pub/sub infrastructure to allow for multiple applications to actually communicate with each other. This allows NCache to play a key part in setting up a fast and reliable microservices environment wherein all the participating services send messages to each other through the NCache platform.
See the link below where they have shared information about NCache topologies
http://www.alachisoft.com/resources/docs/ncache/admin-guide/cache-topologies.html
http://www.alachisoft.com/resources/videos/five-steps-getting-started.html

how to update local memory cache in all server instances

I have a web server cluster that contains many running web server instances. each instance cache some configurations in its local memory, the original configurations are stored in Database.
these configurations are used for every request, so the cache may necessary for performance reason.
I want to provide an admin page, in which, the administrator can change the configurations. how do I update all the cache in every server instance?
now I have two solutions for this:
set an expire time for the cache.
when administrator update the configuration, notify each instance via some pub/sub mechanism(e.g. use redis).
for solution 1, the drawback is the changes can not take effect immediately.
for solution 2, I'm wondering, if the pub/sub will have impact on the performance of the web server.
which one is better? or is there any common solution for this problem?
Another drawback of option 1 is that you'll periodically hit your database unnecessarily.
If you're already using Redis then option 2 is a good solution. I've used it successfully and can't imagine how there could be a performance impact just because you're using pubsub.
Another option is to create a cache invalidation URL on each website, e.g. /admin/cache-reset/, and have your administration tool call the cache-reset URL on each individual server. The drawback of this solution is that you need to maintain a list of servers. If you're not already using Redis it could just be the simple/practical/low-tech solution that you're looking for.

Windows Azure in-role caching vs shared cache

We have a website in Azure and we want to cache the content on the website. The app that will update the content will be outside Azure. We got this scenario working with Shared Cache. Shared caching however is considered a legacy feature and so we wanted to take a look at alternate solutions including using in-role caching. The cached content is very small should not exceed 1 MB and will be consumed by C# code.
We could use co-located cache within the web roles or dedicated cache using a worker role.
The questions we had using in-role cache are:
How can the co-located cache be updated from an external app?
If there was a way to update co-located cache from an external app,
cache notifications could be used to invalidated all co-located cache nodes, correct?
We use extra-small web role instances now - do we need to upgrade to
small/medium instances?
Is dedicated caching better for our scenario?
Thanks in advance.
After doing a bunch of research and guided by Simon's responses in the SO thread he already mentioned, here are my responses:
Q: How can the co-located cache be updated from an external app?
A: I would expose a public endpoint on your Webrole that would clear cache. And I would call that endpoint from your external apps (this endpoint can be a service, rest URL, etc). Alternatively, throw a message onto a queue and have your Webroles monitor that queue and clear the item from cache when they receive a message in the queue. Either way, you're implementing your own notification mechanism
Q: If there was a way to update co-located cache from an external app, cache notifications could be used to invalidated all co-located cache nodes, correct?
A: I don't believe so. The endpoints to co-located cache are strictly internal.
Q: We use extra-small web role instances now - do we need to upgrade to small/medium instances?
A: Yes. I believe colocated cache is supported at Small instance and higher. You will need to try this out to see how much ram you get vs. how much is left over and whether or not that is of any use to your main application
Q: Is dedicated caching better for our scenario?
A: Dedicated vs. colocated cache is really about the load. Do you
have enough load on your cache and on your app servers to justify
moving the cache out into a separate Role? Check out this article
for Microsoft's recommendation:
http://msdn.microsoft.com/en-us/library/windowsazure/hh914129.aspx

Azure - what is the purpose of applicationName in Azure Caching?

Configuration the ASP.NET Output Cache Provider for Windows Azure Caching
I'm a bit confuse about applicationName attribute.
Does it mean I can use multiple applications share the same Azure cache (as long as I don't max out Transactions, Data Transfers and Connections)?
In other words, same cache key won't collide between different web applications as long as applicationName are different?
1 GB cache for $110.00 is a lot cheaper than 10 X 128 MB cache for $45.00.
Thank you for shedding the light!
If we consider the architectural design for out-of-box cache, so when you have multiple instances of same application running in cloud and using a out-of-box cache, to keep all of the instances in sync with regard to output cache.
When you have multiple applications 1) / Root 2) /production 3) /test you really don't want to mix output cache between two different applications because output cache could have full page and partial page cache distributed at cache endpoint based on application name (if configured) or AppID provided by the IIS system.
IF you are using multiple sites within the same ASP.NET Web Role application then you can use dataCacheClient to separate output cache based on different host headers for different sites withing the same application, that would be preferred solution.
Based on the MSDN link, the ApplicationName is used internally to generate the Cache Key. If application key is not provided it uses HttpRuntime.AppDomainAppId. Now the onus is on the development team to udpated IIS metabase so that HttpRuntime.AppDomainAppId in each instance resolves to same value.
In short ApplicationName name is used to provide an additional layer of segregation, If ApplicationName match in different apps, those apps would use the same cache.
The difference in usage of applicationName tag for session state and output caching is mentioned here:
http://msdn.microsoft.com/en-us/library/hh361708.aspx
In context to the question asked here, applicationName tag is handy to cache data between multiple instances of the same role.

What's the best place for a database-backed, memory-resident global cache in an ASP.NET web server?

I have to cache an object hierarchy in-memory for performance reasons, which reflects a simple database table with columns (ObjectID, ParentObjectID, Timestamp) and view CurrentObjectHierarchy. I query the CurrentObjectHierarchy and use a hash table to cache the current parents of each object for quickly looking up the parent object ID, given any object ID. Querying the database table and constructing the cache is a 77ms operation on average, and ideally this refresh occurs only when a method in my database API is called that would change the hierarchy (adding/removing/reparenting an object).
Where is the best place for such a cache, if it must be accessed by multiple ASP.NET web applications, possibly running in different application pools?
Originally, I was storing the cache in a static variable in a C# dll shared by the different web applications. The problem, of course, is that while static variables can be accessed across threads, they cannot be accessed across processes, which is a problem when multiple web-apps are involved (possibly running in separate application pools). As a result... synchronized, thread-safe modifications to the object hierarchy cache in one application are not reflected in other applications, even though they are using the same code-base.
So I need a more global location for this cache. I cannot use static variables (as I just explained), session state (which is basically a per-user store), and application state (needs to be accessible across applications).
Potential places I've been considering are:
Some kind of global object storage within IIS itself, accessible from any thread in any application in any application pool (if such a place exists. Does it?)
A separate, custom web service that manages an exclusive cache.
Right now, I think the BEST solution is SQL CLR integration, because:
I can keep my current design using static variables
It's a separate service that already exists, so I don't have to write a custom one
It will be running in a single process (SQL Server), so the existing lock-based synchronization will work fine
The cache would be setting as close as possible to the data structures it represents!
I would embed the hierarchy-traversing methods in the SQL CLR DLL, so that I could make a single SQL call where I would normally make a regular method call. This all depends on SQL Server running in a single process and the CLR being loaded into that process, which I think is the case. What do you think of this? Can you see anything obviously wrong with this idea that I may be missing? Is this not an awesome idea?
EDIT:
After looking more closely, it seems that different ASP.NET applications actually run in the same process, but are isolated by AppDomains. If I could find a way to share and synchronize data across AppDomains, that would be very very useful. I'm reading about .NET Remoting now.
Microsoft is working on a distributed caching framework: Velocity. However, the latest release is a CTP3 version, so it may not be production ready...

Resources