Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suggestions for simple .NET distributed caching solution

We have one server running Windows Server 2003 for our production web server. Our web site has different modules to it and each is ran within it's own application pool. This makes caching a bit of a problem since each module has it's own cache and often times multiple modules cache the same items. The problem is when an item in the cache is altered in one module, another module caching the same item cannot easily be refreshed.

Our site is written in ASP.NET 4.0 and we cache datasets, business objects, collections, lists, etc. using the standard HttpRuntime.Cache object as a simple key/value store. We don't use any file dependencies but we do use a time expiration. We only have about 400 users at once so we aren't doing anything too crazy.

It sounds like some sort of shared/distributed cache would help resolve this issue but I am not sure which one to use or if it would be better to roll our own since we do not need a lot of the features available in most of the products I've seen. I've seen some examples using WCF but most have suggested not to use their examples in production and I know little about WCF.

I'm looking for something simple, fast, lightweight, safe to run in production, and preferably free if possible but it does not have to be. It needs to run on Windows Server 2003 & work with ASP.NET 4.0.

Any suggestions or info?

like image 413
Billy Avatar asked Dec 08 '11 14:12

Billy


People also ask

What are the different caching techniques available in .NET Core?

ASP.NET Core supports two types of caching out of the box: In-Memory Caching – This stores data on the application server memory. Distributed Caching – This stores data on an external service that multiple application servers can share.

Is Redis a distributed cache?

Redis is an open-source in-memory data structure project implementing a distributed caching, in-memory key-value database. Redis supports different kinds of abstract data structures, such as strings, lists, maps, sets, sorted sets, hyper log, bitmaps, streams, and spatial indexes.

What is the use of caching in a distributed system give an example?

The distributed architecture allows incremental expansion/scaling by adding more computers to the cluster, allowing the cache to grow in step with the data growth. A distributed cache pools the RAM of multiple computers into a single in-memory data store used as a data cache to provide fast access to data.


4 Answers

Simple, fast, lightweight and safe sound like things like redis and memcached, which can be very effective as a central cache. For stackoverflow we use redis via BookSleeve (client) but most stores will work similarly. There is also an AppFabric cache, but that is considerably more complex.

Key points though:

  • your data will need to be serializable in some way
  • if you are currently using cache of large objects (like a big DataTable) you'll need to consider bandwidth implications, or make it more granular
  • you'd probably benefit from a 2-tier cache (one local memory, with the central store as secondary)
  • which means you'd also need to consider invalidation (we do that via the pub/sub API in redis)
like image 109
Marc Gravell Avatar answered Oct 12 '22 10:10

Marc Gravell


memcached along with an ASP.NET provider is a popular choice. Bear in mind though that in .NET 4.0 the recommended way to do caching is to use the new ObjectCache instead of HttpRuntime.Cache. There is a built in memory implementation into the .NET framework (MemoryCache) and also you may checkout an implementation for memcached.

like image 44
Darin Dimitrov Avatar answered Oct 12 '22 10:10

Darin Dimitrov


Give Dache a try. It is an open source .NET distributed caching solution that is extremely performant. http://www.getdache.net

like image 25
Haney Avatar answered Oct 12 '22 09:10

Haney


I implemented a simple Distributed Cache using Redis:

 public class RedisCacher
{
    private static Lazy<ConnectionMultiplexer> _lazyConnection;

    public static ConnectionMultiplexer Connection
    {
        get
        {
            return _lazyConnection.Value;
        }
    }

    public RedisCacher()
    {
        string redisConnectionString = $"your redis connection(IP, Port ...)";

        _lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
        {
            return ConnectionMultiplexer.Connect(redisConnectionString);
        });
    }

    public void Delete(string key)
    {
        var redis = Connection.GetDatabase();
        redis.KeyDelete(key);
    }

    public T GetValue<T>(string key)
    {
        var redis = Connection.GetDatabase();

        string valueAsStringFromRedis = redis.StringGet(key);
        var value = JsonConvert.DeserializeObject<T>(valueAsStringFromRedis);
        return value;
    }

    public void Add<T>(string key, T value, TimeSpan expirationTime)
    {
        var redis = Connection.GetDatabase();
        string valueAsString = JsonConvert.SerializeObject(value);
        redis.StringSet(key, valueAsString, expiry: expirationTime);
    }
}

And the usage is:

 var cacher = new RedisCacher();
 cacher.Add(id.ToString(), request.Request.ProductTree, DateTimeOffset.UtcNow.AddMinutes(30).TimeOfDay);

.....
 var cacher = new RedisCacher();
 var productTree = cacher.GetValue<ProductTreeItem>(id);
like image 25
Brachy Avatar answered Oct 12 '22 10:10

Brachy