Inside ModelVirtualCasting #9: Cache con Windows Server AppFabric

di Daniele Bochicchio, in ASP.NET,

Previously, on ModelVC:

  1. Introduzione ai repository
  2. Architettura interna dei repository
  3. La cache
  4. Come funziona CacheThis?
  5. II servizi
  6. SEO con ASP.NET 4.0
  7. Come ti creo una form MVC in 20 secondi (a dire tanto...)
  8. Applicazioni Silverlight sul client (OOB)

ModelVC ha un sistema di cache a provider, che sfrutta le novità in tal senso di .NET Framework 4.0. Nel trunk trovate un provider per cache in memoria, uno per ScaleOut ed uno per AppFabric. L'argomento è stato comunque già approfondito in una puntata precedente.

Questo post è un post riparatore, perchè dopo la "RTM" della 0.2, mi sono imbattutto in un caso reale di utilizzo di AppFabric che ha fatto sì che il download originale contenesse una versione non pronta per la produzione. Mi spiego meglio.

Recentemente, ho finito di scrivere il capitolo riguardante stato e cache per ASP.NET 4.0 in practice, che uscirà a breve. Me lo sono tenuto per ultimo per poter fare 2 cose:

  • usare l'RTM :)
  • mettere la mia (vera, effettiva) esperenzia con lo scenario.

A tal proposito, segno di quanta differenza faccia l'esperienza reale con le fuffe mentali in scenari come questo, ho preso la palla al balzo, decidendo di applicare AppFabric Cache ad ASPItalia.com & fra te lli. Premessa: abbiamo circa una 30ina di siti, intensi come permutazioni dei vari domini e sottodomini, con tanti pezzi in comune. Tutto gira su un solo server web. E' vero che un meccanismo di cache distribuita da' vantaggi soprattutto in ambito distribuito (altrimenti non si chiaremerebbero così :)), però in questo caso abbiamo ottenuto altri vantaggi di non poco conto:

  • deploy a caldo semplificati: gli oggetti restano in cache a prescindere dallo stato dell'app domain. Questo vuol dire che se faccio un deployment, ricaricherà gli assembly, non gli oggetti in cache, che restano lì. Morale: parte in una frazione di tempo;
  • minore occupazione di RAM: perchè molti di questi siti, di fatto, accedono ad elementi in comune (profili utenti, ultimi aggiornamenti, etc) e quindi traggono un enorme beneficio da questa architettura;
  • sincronizzazione degli oggetti in memoria: per farlo con il sistema in memoria, ho dovuto inventarmi una roba assurda, ovviamente con AppFabric Cache è tutto centralizzato e quindi il problema non si pone. Rimuovi dal sito A, tutti gli n altri siti sono in automatico in sync. Figata :)

Torniamo a ModelVC, che mi è servito come base di partenza. Nell'implementazione originale, ho commesso un paio di errori. Il primo, è considerare che la region di default fosse come le altre; invece non è così, ha bisogno di overload specifici, che ora sono codificati. Il secondo, è pensare che l'istanza del DataCacheFactory, che è la classe che accede fisicamente al servizio, potesse essere create e distutta ad ogni richiesta. Invece, l'esperienza con ASPItalia.com mi ha aiutato, non poco, a capire che l'istanza va conservata e va fatto riferimento a questa dai vari metodi:

private static DataCache CacheFactory 

{ 

  get 

  { 

    if (factory == null) 

    { 

      lock (syncObj) 

      { 

        if (factory == null) 

        { 

          DataCacheFactory cacheFactory = new DataCacheFactory(); 

          factory = cacheFactory.GetDefaultCache(); 

        } 

      } 

    } 



    return factory; 

  } 

}

Non farlo vuol dire che se avete un utente per volta (su ModelVC è la normalità, su ASPItalia.com no :)) tutto funzionerà, altrimenti farà allegramente puff.

Il codice sorgente lo trovate qui. Occhio che se usate una region custom, dovete crearla ogni volta. Purtroppo, da questo punto di vista, le API sono immature e quindi vi tocca affogare l'eccezione che risulta, se già esiste:

private void CreateRegionIfNeeded() 

{ 

  // verifichiamo se la region esiste 

  // se già esiste, viene scatenata un'eccezione 

  try 

  { 

    CacheFactory.CreateRegion(DefaultRegionName); 

  } 

  catch (DataCacheException ex) 

  { 

    if (!ex.ErrorCode.Equals(DataCacheErrorCode.RegionAlreadyExists)) 

      throw ex; 

  } 

}

Il team stesso indica come l'unica possibile questa via. Avrebbero potuto fare un semplice metodo RegionExists per evitare questa poco elegante forma di gestione.

L'ultima cosa: è preferibile usare il metodo Put anzichè Insert, perchè quest'ultimo, se l'oggetto già esiste, scatena un'eccezione. Se preferite non tenere lock vari in fase di inserimento, questa può essere una buona scelta, in quanto al massimo sovrascrive l'elemento correntemente in cache.

Per fortuna AppFabric Caching si installa anche su Windows 7 e funziona in modalità single node, quindi potete tenerlo sulla vostra postazione di sviluppo e farci tutti i test che vi pare.

La schermata di cui sopra viene da ASPItalia.com ed è stata presa circa 10 minuti fa.

Dopo un mese e spicci di uso continuo, posso dire che il servizio è molto stabile, a patto che non lo riavviate: in questo caso, infatti, non ho capito bene perchè, tende a diventare un po' incasinato ed occorre fare il kill del processo perchè si riavvii. Nei primi giorni avevo messo il riavvio automatico del processo di notte, anche per ripulire la cache, ma poi ho optato per rimuovere questa procedura: gli elementi scadono tutti in base al tempo, quindi si rimuovono da soli e non resta roba che non serve in memoria.

Per semplificare la rimozione di elementi collegati, dato che non ho fatto uso (per ora) dei ChangeMonitors, ho messi in piedi un sistema che usa i DataCacheTag: praticamente, potete taggare un elemento in cache e poi rimuoverli tutti insieme. Questo mi consente, per esempio, di rimuovere la cache del forum relativa ad un forum, quando uno dei post viene aggiornato/inserito.

E, per non saper nè leggere nè scrivere, se entri 3 secondi AppFabric non risponde, viene fatto il fallback sulla cache in memoria. Tutti i provider sono stati dotati di un fantastico metodo Ping, che viene invocato per garantire che risponda.

In estrema analisi, posso dire che AppFabric Caching era davvero il pezzetto che mancava all'application server Microsoft ed è un'aggiunta più che benvenuta. E, ancora una volta, ribadisco che l'unica via per comprendere appieno come funziona qualcosa è quella di provarla nel mondo reale: le simulazioni, almeno in questo campo, non sono significative!

Infine, risorse sull'argomento:

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese