Domanda

Supponiamo che stiamo costruendo un sito e-commerce che permette ai consumatori di cercare i prodotti digitando parole chiave. Dicono che ci sono al massimo 200.000 prodotti, e ci sono milioni di consumatori che utilizzano il sistema. Diciamo che la tabella dei prodotti viene aggiornato abbastanza frequentemente. Dal momento che il numero di prodotti non è così in alto e probabilmente possiamo memorizzare l'intero tavolo prodotto in memoria e cerchiamo contro di essa invece di colpire la base di dati. Speriamo di creare cache distribuita che memorizzano gli stessi dati, ma risiedono in server diversi (per l'alta disponibilità e la ragione di performance) e abbiamo bisogno di essere in grado di sincronizzare i dati tra questi cache e invalidare le cache quando la tabella prodotto viene modificato.

La nostra applicazione è costruito utilizzando ASP.NET MVC e NHibernate. Sto cercando di capire se di NHibernate cache di livello-2 avrebbe aiutato con la mia situazione. Vorrei davvero apprezzare se voi potete far luce su questo.

Mi rendo conto che la memorizzazione nella cache di livello 2 vi aiuterà risultato della query cache in modo, se due utenti diversi sono alla ricerca utilizzando la stessa parola chiave, la cache L2 servirà il risultato dalla cache invece che dal database. Ma non ci aiuta molto in quanto la tabella dei prodotti viene aggiornato frequentemente e il risultato in cache sarà stantio. La mia domanda è sto capendo L2 di cache in modo corretto ed è esiste nulla che aiutano a gestire la cache del modo in cui mi piacerebbe fare (più cache, gli stessi dati, la sincronizzazione tra cache e invalidare la cache). Ogni pensiero è molto apprezzato.

È stato utile?

Soluzione

Avendo sia la cache di secondo livello utilizzato (utilizzando il provider memcached) e il NHibernate.Search add-on mi sembra che si potrebbe trarre vantaggio da entrambi.

Il componente NHibernate.Search dipende Lucene.Net e ricerca per parola chiave è disaccoppiato dal database è di per sé. Un file di diverso indice è stato creato per classe mappata e ottimizzazioni può essere impostato sul livello di proprietà utilizzando attributi, dando un ulteriore livello di granularità. Inoltre, è possibile implementare migliore partita e proposizioni (check Lucene in azione e / o Hibernate Cerca in azione). Come una nota, non c'è bisogno di mantenere l'indice (a meno che non si richiede esplicitamente ricostruzione di un indice); l'attuazione gestisce tutto dietro le quinte, anche se è possibile manipolare l'indice se si desidera farlo. Quindi, l'aggiunta / cancellazione / aggiornamento di un prodotto aggiornerà automaticamente l'indice di base.

Per la cache di secondo livello si ottiene spinta immediata delle prestazioni. In un ambiente di prova con un set di dati di circa 2 mil righe avevo miglioramento superiore al 20% anche su un conteggio richiesta estremamente bassa. L'incremento delle prestazioni è a poco a poco più grande come la richiesta aumenta di conteggio - l'applicazione colpisce prima la cache di 2 ° livello e se non lo trova poi colpisce il DB per recuperare le righe richieste e li inserisce sulla cache per le query future. Anche in questo caso è possibile gestire cose come la durata della cache e altre impostazioni di configurazione, così come in modo inequivocabile la cache (tutto questo, una parte di essa, o le voci particolari), se si desidera farlo. Si noti che lo stato della cache è gestita dall'applicazione durante salvataggio / aggiornamento / cancellazione.

Per scallability * La cache di 2 ° livello dipende dal provider (ad esempio memcached è altamente performante e scalabile e supporta distribuito casi). * Per la Lucene.Net/NHibernate.Search è necessario impostare un luogo specifico che gli indici si risiedono e quel luogo devono essere accessibili per la lettura / scrittura da tutte le istanze web-applicazioni. Si noti qui che il collegamento è sensibile I / O e il conflitto di file, in modo da creare una segreteria con un più veloce di file di sistema di illuminazione sarà evitare che ciò accada (parlo per lo scenario con molte migliaia di richieste di ricerca al secondo)

Come nota a margine mi raccomando NHibernate.Search in quanto è estremamente più veloce di domande come ed è più facile da usare rispetto attuazione ricerca full-text di SQL-Server all'interno dell'applicazione (che ho fatto).

Altri suggerimenti

Se una cache di secondo livello aiuterà dipende esattamente la frequenza con la vostra tavola prodotto viene aggiornato in relazione a riscontri nella cache. Se si aggiungono 100 nuovi prodotti all'ora, ma riceve 10.000 query all'ora, anche un tasso di successo della cache 10% farà una grande differenza. Se i tassi sono invertiti, una seconda cache di livello sarà di quasi nessun valore.

Vi suggerisco di impostare un ambiente di test di stress che si avvicina molto l'ambiente di produzione e di eseguire analisi comparativa sui diversi fornitori di cache di secondo livello.

Verificare inoltre che il DB è configurato correttamente per uno scenario di aggiornamento-pesante.

Mi consiglia di utilizzare NHibernate.Search w / Lucene. Si collabora con la cache di 2 ° livello. Lucene può fare sofisticata ricerca di testo strappo veloce e poi tornare indietro le chiavi di entità per NHibernate, che tira l'entità completa dalla sua cache di 2 ° livello. L'estensione NHibernate.Search fa il lavoro di mantenere il vostro indice di Lucene in sincronia.

TekPub ha fatto un recente episodio dello scenario esatto di cercare descrizioni dei prodotti. L'episodio mette a confronto le query SQL, NHibernate indicizzazione full-text e Lucene w / NHibernate.Search.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top