views:

1134

answers:

9

Hi there,

Where is the best place to implement caching in a web based app?

  • At the presentation layer (hope not)?
  • At the Business Logic Layer?
  • At the data layer?

I'm going to use something like memcached or MS Velocity under the hood.

I'm just finding myself writing so much code to update the cache here and there in the business logic layer, so would it be better to create a fabric in between the data access layer at the Database Server to cache data?

I think these complications are down to the fact, most of the data we are caching is user specific and we are duplicating data in the cache. We struggling to find the best solution.

Thanks for your help! Ash.

+1  A: 

Cache: implemented at the data access layer, accessed by the Business logic layer.

this mean you must watch out carefully for the cache going stale.

Here Be Wolves
+3  A: 

Data Layer - all layers above this layer don't need to know where the data is sourced from. I would also only cache data thats not very volatile, or include some expiration policy.

ozczecho
+2  A: 

We implement it at the business logic layer between interactions with the presentation layer. If a request from the presentation layer comes in and it is cached we can then skip a whole lot of logic and data access.

I'd highly recommend MemCached over MS Velocity, Velocity was a pain to setup!

Lloyd
+1  A: 

Data layer. But it is confusing because we use ASP.NET caching. With its expiration and dependency capability, it's pretty handy. So our business layer has no idea the data layer might be caching but the data layer uses a presentation-layer technology for caching! :(

n8wrl
The problem with ASP.NET's cache is it's not distributed or shared across applications and appdomains, MemCached and Velocity allow this which is why we switched to it.
Lloyd
Very true. I played games with SqlCacheDependency with limited success. I'd like very much to go with MC or V.
n8wrl
+1  A: 

If you're caching business objects, and given the 3 tiers you describe you're using, the business layer is the obvious place.

A simple setup would be (for a single business object):

  1. MyCache is a static class
  2. One static method: MyCache.Retrieve(id), returns an object
  3. The class uses a static Dictionary for storage, and a static ReaderWriterLock

The Retrieve method then performs the following:

  1. Is the id in your cache (a Dictionary of id/object)?
  2. No
    • Grab the object from the database
    • AquireWriterLock from the ReaderWriterLock (why ReaderWriter? because you're not writing frequently but you are reading often)
    • Add the object to the cache
  3. Yes
    • Retrieve the object from the dictionary

That's my prefered solution, you can add timeouts, clearing and so on if you need. Or use memcached or the Microsoft Enterprise Library Caching Block but they're usually overkill.

Chris S
+1  A: 

I can't speak for ASP.NET specific stuff, but I've generally found that you can cache at each level. Your data tier will cache data responses, your presentation layer may find the need to cache generated presentation elements (e.g., user-specific style sheets), etc. In most cases, the data tier is the heaviest cache user and the other tiers will include an object cache if one is proven to be necessary.

The hardest part is getting cache invalidation working correctly. Stale caches are a major headache during deployment. Make sure to figure out how you are going to manage the lifetime of each cache object. LRU caches work well for caching static elements based on demand. Most data caches, however, will need an explicit life cycle whether it be based on an expiration timer or tied to some sort of a user session.

D.Shawley
+4  A: 

Caching is a performance optimization, so do it where the bottleneck is. You know where the bottleneck is by measuring it three times and then once more.

Beware of the relaxed consistency of your data when you cache, e.g. you don't want to cache all of your stock trading app.

Hans Malherbe
+4  A: 

Hi,

You should consider caching at EVERY layer.

The best place to cache is as near to the client request as possible (so you do as little work as possible to serve the response). In web apps, yes at the presentation layer, at the business layer and the data layer.

(Side note: If you are basically peppering your business logic code with caching logic here and there, you should really look into seperation of concerns to avoid your code becoming a big ball of mud :-) )

Steve
+13  A: 

Cache is an important part or a web app, but there is no magical solution that will fit every project. Working on optimisations before your app is working is usually a bad idea. Before asking yourself where you should implement a cache layer, the first step is to be sure that your application works well (even if slowly) without any cache optimisation.

When this first step is achieved, you can start profiling the app, listing the features that seem to be using a lot of resources (may it be CPU, memory, i/o, database access) or taking a lot of time to complete (usually because of the same symptoms).

Once you have a list of features that you think can be optimized with a cache system, there are two questions you need to ask yourself :

  • "How can I improve all these features at the same time" (macro focus) : An obvious answer to this one is often data-access cache. You usually don't want to send the same query to your database server over and over again if the data you get in return is always the same. So storing this type of data in cache, with a clever lifespan, will always be a good idea.

  • "How can I improve each feature" (micro focus) : This is tricky, and you need to understand your application very well to figure this one out. Some data can be cached, some shouldn't, some mustn't. A debugger and a profiler are usually great tools for this step, because they help you being sure why a feature is slow, and give you hints about how they should be optimized.

The optimisations you're going to figure out could be related to any layer of your application (presentation, business logic, data), but that doesn't mean you should implement them all. There are several important things you should take into account :

  • Does this feature really need to be optimized ? (is it a noticeable gain for the customer ? For the hardware ? For the whole app ? For other apps ?)
  • What performance gain can I achieve ? (1%, 200%, ...)
  • How much time will it take me to optimize it ? (1 hour, 12 days, ...)
  • How risky is it to optimize it ? (could it break things for the app ? For the customer ?)

Once you have the answers to these questions, it's time to talk about this with your project manager, with your colleagues, or even with people that don't work on the application with you. Having neutral opinion is good, as well as having non-technical (or less technical) opinions. Talking with these people should help you figure out what should be done and what shouldn't.

At this point you should have a list of optimisations that's pretty clear, that you thought through several times, and you should have no problem coding and testing them.

Nicolas
Waheed Sayed