Utiliser Couchbase comme serveur de cache

Publié par Fabrice Michellonet sous le(s) label(s) , , le 11 avril 2014

Dernièrement, je vous présentais une façon simple d'utiliser le cache dans vos applications .NET
Cependant cette solution possède plusieurs inconvénients. En voici quelque uns :

  • Le cache est lié au processus système de votre application (executable / IIS etc...). Si votre programme plante ou est fermé, vous perdez votre cache
  • Si vos besoins en mémoire augmentent, cette solution n'est pas scalable
  • Rien n'est mis a disposition pour monitorer votre cache
  • Vous n'avez pas d'interface de gestion du cache (augmentation de la mémoire allouée etc...)
  • Vous ne pouvez pas invalider le cache sans arrêter l'application.
  • etc...
Bref, vous avez compris, c'est une solution pour démarrer petit.

Aujourd'hui, je voudrais partager avec vous une solution qui répond à tous les manques évoqués plus haut et plus encore.
Couchbase est une base NoSQL Key/Value; la value ayant comme particularité d'être un document json.
Couchbase est issu du mariage heureux de Membase (cache mémoire avec réplication des caches, persistance et interface d’admin Web sexy) et
CouchDB (NoSQL orienté document). Ce qui nous intéresse plus particulièrement aujourd'hui sont les fonctionnalités qui en font un bon serveur de cache.


Installation


Pour l'installer, tout commence par télécharger le setup ici

Je vous passe le scénario d'installation qui a le bon gout de se faire en "Next" > "Next" > "Next"

Passons à la configuration :

Dans la première étape, il vous faudra spécifier l'emplacement des fichiers (base et index) ainsi que la mémoire dévolue à Couchbase.

configure server

Un peu plus loin nous allons créer le l'espace qui accueillera les objets que l'on va mettre en cache (bucket).

bucket

Quelques instant plus tard vous voila avec un Couchbase flambant neuf sur votre machine.

up and running

Note : si la page ne s'ouvre pas automatiquement dans votre browser, la console d'admin de couchbase se trouve a l'adresse suivante : http://localhost:8091/


Implementation


Couchbase dispose d'un très bel écosystème qui gravite autour, et la plateforme .NET ne fait pas exception.
Je me propose d'adapter le cache manager vu dans le précédent article.
Pour rappel nous avions l'interface suivante :


public interface ICacheManager
{
    T GetOrInsert<T>(string key, Func<T> callback) where T : class;
}

Passons à l'implémentation. Il va nous falloir un driver, que l'on peut aisément installer via nuget :



son utilisation est des plus simple, avec des méthodes explicites comme Get() et Store().
Voici une implémentation de cache respectant notre interface basée sur Couchbase.


public class CouchbaseCacheManager : ICacheManager
    {

        private readonly CouchbaseClient _client;

        public CouchebaseCacheManager()
        {
            _client = new CouchbaseClient();
        }

        public T GetOrInsert<T>(string key, Func<T> callback) where T : class
        {
            T elmnt;
            try
            {
                if (_client.KeyExists(key))
                    return _client.Get<T>(key);
                elmnt = callback();
                _client.Store(StoreMode.Add, key, elmnt);
            }
            catch (Exception)
            {
                elmnt = callback();
            }
            return elmnt;
        }
    }

Et vous, quel type de cache utilisez vous dans vos projets?

Poor man's cache

Publié par Fabrice Michellonet sous le(s) label(s) , , le 4 avril 2014

Depuis la version 4 du framework .NET, la gestion d'un cache est profondement encrée dans l'adn de notre framework.
Il devient alors extrêmement facile de stocker en mémoire à peu près n'importe quoi.
Je vous livre dans ce court billet, une implémentation extrêmement simple que j'utilise souvent dans mes projets.
Commençons par définir une interface, qui nous permettra d'injecter notre cache manager un peu partout :

public interface ICacheManager
{
    T GetOrInsert<T>(string key, Func<T> callback) where T : class;
}

et finalement voici une implémentation extra simple de notre cache manager

public class CacheManager : ICacheManager
{
    public T GetOrInsert<T>(string key, Func<T> callback) where T : class
    {
        ObjectCache cache = MemoryCache.Default;
        if (cache.Contains(key))
            return cache[key] as T;
        T elmnt = callback();
        cache.Add(new CacheItem(key, elmnt), new CacheItemPolicy());
        return elmnt;
    }
}

Voici un exemple d'utilisation.

IEnumerable<Product> products = _cache.GetOrInsert("Ma_Clef_Unique_Cache", 
() => { return _productService.GetFrenchProducts(); } );

Simple non?