2011-12-11 6 views
62

Desidero aggiungere funzionalità di memorizzazione nella cache alla mia applicazione utilizzando lo spazio dei nomi System.Runtime.Caching e probabilmente vorremmo utilizzare la memorizzazione nella cache in più posizioni e in diversi contesti. Per fare ciò, voglio utilizzare diverse istanze di MemoryCache.Utilizzo di più istanze di MemoryCache

Tuttavia, vedo here che l'utilizzo di più di un'istanza di MemoryCache è sconsigliato:

MemoryCache non è un Singleton, ma è necessario creare solo pochi o potenzialmente una sola istanza MemoryCache e codice che memorizza nella cache articoli dovrebbe usare quelle istanze.

In che modo più istanze di MemoryCache possono influire sulla mia applicazione? Trovo questo tipo di strano perché mi sembra che usare più cache in un'applicazione sia uno scenario piuttosto comune.

MODIFICA: In particolare, ho una classe che dovrebbe mantenere una cache per ogni istanza. Dovrei evitare di usare MemoryCache e cercare una diversa soluzione di caching? Sta usando MemoryCache in questa situazione considerata male, e se sì, perché?

+1

Qual è la differenza tra una cache singola e molte cache? Dopotutto, faranno tutti la stessa cosa. – spender

+9

Per uno, non dovrò più preoccuparmi delle collisioni tra chiavi. Inoltre, ritengo che sia più organizzato e più facile da eseguire il debug rispetto all'utilizzo di un oggetto che trattiene tutte le cache dell'applicazione. –

+5

Significa che non dovresti creare molte cache che memorizzano nella cache la stessa cosa. È molto meglio memorizzare nella cache il più possibile da una cache centrale. Ma è perfettamente ok creare molte cache che fanno cache di cose diverse. –

risposta

57

Recentemente l'ho passato anch'io. Considerando che una cache in memoria verrà elaborata in modo specifico (non condivisa tra più istanze di un sito Web o di un'app business nativa o più server) non c'è alcun vantaggio nell'avere più istanze MemoryCache eccetto per motivi organizzativi del codice (che possono essere ottenuti in altri modi) .

La memoria cache deve essere utilizzata da sola principalmente a causa delle sue capacità di gestione della memoria. Oltre ai contatori delle prestazioni (che hanno un sovraccarico), MemoryCache è anche in grado di scadere gli elementi quando esaurisce la memoria allocata.

Se l'istanza corrente della cache supera il limite impostato memoria dalla proprietà CacheMemoryLimit, l'implementazione della cache rimuove voci della cache. Ogni istanza cache nell'applicazione può utilizzare la quantità di memoria specificata dalla proprietà CacheMemoryLimit.

da MemoryCache.CacheMemoryLimit Property

Utilizzando solo un'istanza del MemoryCache si può applicare questa gestione della memoria efficiente attraverso l'intera istanza dell'applicazione. Scadenza degli elementi meno importanti nell'intera applicazione. Ciò garantisce il massimo utilizzo della memoria, senza superare le capacità dell'hardware. Limitando l'ambito di ogni MemoryCache (come per un'istanza di una classe) non è più possibile gestire in modo efficace la memoria per l'applicazione (in quanto non può "vedere" tutto). Se tutte queste cache fossero "occupate", potrebbe essere più difficile gestire la memoria e non sarà mai così efficiente.

Questo è particolarmente sensibile nelle applicazioni che non hanno il lusso di un server dedicato.Immagina di eseguire la tua app su un server condiviso in cui ti è stata assegnata solo una memoria RAM da 150 MB (comune $ 10/mese di hosting a basso costo) che devi contare sulla tua cache per utilizzarla al massimo senza superarla. Se superi questa quantità di memoria, il tuo pool di app verrà riciclato e la tua app perde tutte le cache in memoria! (pratica comune di hosting a basso costo) Lo stesso potrebbe valere per un'applicazione non web ospitata in house su alcuni server aziendali condivisi. Allo stesso modo, ti viene detto di non intrattenere tutta la memoria su quella macchina e di coesistere pacificamente con qualche altra linea di app aziendali.

Questo limite di memoria, riciclo di app pool, perdita di cache è un comune "tallone d'Achille" per le app Web. Quando le app sono più affollate, si reimpostano più spesso a causa del superamento delle allocazioni di memoria, perdendo tutte le voci della cache e quindi facendo la maggior parte dei lavori di re-fetching che avrebbero dovuto essere memorizzati nella cache in primo luogo. Significa che l'app in realtà perde le prestazioni a carico massimo invece di guadagnare.

So che MemoryCache è la versione non web specifica dell'implementazione System.Web.Caching.Cache, ma questo illustra la logica dietro l'implementazione della cache. La stessa logica può essere applicata in un progetto non Web se non si dispone dell'utilizzo esclusivo dell'hardware. Ricorda che se la tua cache impone alla macchina di iniziare a fare swap con i pagefile, la tua cache non sarà più veloce della cache sul disco. Avrai sempre un limite da qualche parte, anche se quel limite è di 2 GB o qualcosa del genere.

Nel mio caso, dopo aver letto tutto ciò, sono passato a utilizzare una "memoria statica pubblica" nella mia app e ho semplicemente separato gli elementi della cache con le loro chiavi di cache. Ad esempio se si desidera memorizzare una cache per istanza si potrebbe avere una chiave di cache come qualcosa come "instance- {instanceId} -resourceName- {resourceId}". Consideralo come il nome che spazia tra le voci della cache.

Spero che questo aiuti!

+2

Grazie, era utile. Tuttavia, non sto cercando di limitare la mia cache in base alle dimensioni della memoria, ma possibilmente per capacità - dove voglio che ogni istanza abbia una certa capacità e non mi interessa la cache combinata. Separare gli elementi della cache con una convenzione di denominazione non è un bene per quel caso, e sembra un po 'forzato in entrambi i casi. –

+1

@AdiLester Hai ragione. Idealmente, Microsoft finirebbe di implementare la cache "Regions" per il loro 'MemoryCache' in modo da non avere bisogno di queste chiavi forzate" namespace "e si potrebbe interrogare il numero di elementi memorizzati nella cache in qualsiasi Regione. Ma non è attualmente supportato per l'implementazione della cache non web. :-(Nel frattempo sembra che tu conosca i tuoi limiti e stia bene con loro – BenSwayne

+0

Puoi per favore mostrare qualche esempio di codice che spiega il vantaggio dell'uso sopra su Single Instance. In questo sarà più utile e più popolare. –

4

Ne uso anche io. Generalmente uno per tipo.

Guardando allo MemoryCache vedo che si aggancia agli eventi AppDomain e mantiene i contatori delle prestazioni. Sospetto quindi che ci sia un eccesso di risorse in termini di risorse usando più di una (ad es. CPU, contatori e memoria) ed è per questo che è scoraggiato.