Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net caching limit? [duplicate]

Possible Duplicate:
ASP.NET cache maximum size

I'm caching quite a lot of datatables using asp.net caching (the floowing code):

HttpContext.Current.Cache.Insert(GlobalVars.Current.applicationID + "_" + cacheName, itemToCache, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(240));

However I think that the cache on the server is getting full and having to re-obtain the datatable data from the database. Is there any limit to the amount of data that can be cached on the server or any IIS settings that can be tweaked?

like image 535
dhardy Avatar asked Dec 26 '12 23:12

dhardy


2 Answers

There is a way to upgrade the limit but I would strongly recommend that you use other kind of Caching System (more about this below).

.NET Cache

To know more about the .NET Caching limitation, please read this great answer from a Microsoft .NET Team member.

If you want to see the current limits of .NET Cache, you can try:

var r = new Dictionary<string, string>();

using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache % Machine Memory Limit Used", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_MachineMemoryUsed", String.Concat(pc.NextValue().ToString("N1"), "%"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache % Process Memory Limit Used", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_ProcessMemoryUsed", String.Concat(pc.NextValue().ToString("N1"), "%"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache API Entries", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_Entries", pc.NextValue().ToString("N0"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache API Misses", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_Misses", pc.NextValue().ToString("N0"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache API Hit Ratio", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_HitRatio", String.Concat(pc.NextValue().ToString("N1"), "%"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache API Trims", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_Trims", pc.NextValue().ToString());
}

MemCached

I'm currently using Memcached, and if you're hosting your site somewhere, you can use a paid service like:

  • http://www.memcachier.com/

Or, if you're using your own server, you can download Couchbase Community Edition and hosted our own.

You will find more questions here about the use of MemCache, such as:

  • Which .NET Memcached client do you use, EnyimMemcached vs. BeITMemcached?
  • how to start with memcached

Make room for any Cache system

To use other cache system without changing your code, you could adopt to create an interface, like

public interface ICacheService
{
    T Get<T>(string cacheID, Func<T> getItemCallback) where T : class;
    void Clear();
}

then is you're using .NET Cache, your implementation would be something like

public class InMemoryCache : ICacheService
{
    private int minutes = 15;

    public T Get<T>(string cacheID, Func<T> getItemCallback) where T : class
    {
        T item = HttpRuntime.Cache.Get(cacheID) as T;
        if (item == null)
        {
            item = getItemCallback();
            HttpRuntime.Cache.Insert(
                cacheID,
                item,
                null,
                DateTime.Now.AddMinutes(minutes),
                System.Web.Caching.Cache.NoSlidingExpiration);
        }
        return item;
    }

    public void Clear()
    {
        IDictionaryEnumerator enumerator = HttpRuntime.Cache.GetEnumerator();

        while (enumerator.MoveNext())
            HttpRuntime.Cache.Remove(enumerator.Key.ToString());
    }
}

and you would use it as:

string cacheId = string.Concat("myinfo-", customer_id);
MyInfo model = cacheProvider.Get<MyInfo>(cacheId, () =>
{
    MyInfo info = db.GetMyStuff(customer_id);
    return info;
});

if you're using Memcached, all you need to do is create a new class that implement ICacheService and select the class you want, either by using IoC or direct call as:

private ICacheService cacheProvider;

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
    if (cacheProvider == null) cacheProvider = new InMemoryCache();

    base.Initialize(requestContext);
}
like image 121
balexandre Avatar answered Sep 18 '22 14:09

balexandre


The cache uses the memory allocation for the worker process. By default the worker process is allowed to get 60 percent of the machine memory in order to do its work .

As per the link, this can be changed to allow more of the machine memory to be used by the worker process by editing the machine.config file. Presumably you have the cache built to already update when it detects that data is out of date, so this should allow you to put more objects into cache.

like image 20
BrianC Avatar answered Sep 20 '22 14:09

BrianC