Utilizzo della memorizzazione nella cache di .NET in EF Core tramite i metodi di estensione

Webinar registrato
Ron Hussain e Nick Zulfiqar

Entity Framework (EF) Core è la nuova versione multipiattaforma e leggera del popolare Entity Framework di Microsoft. EF Core è un motore di mappatura relazionale a oggetti per .NET che elimina la necessità della maggior parte del codice di accesso ai dati che gli sviluppatori scrivono altrimenti.

EF Core viene sempre più utilizzato in applicazioni server con transazioni elevate (ASP.NET, WCF e altre app server .NET). Inoltre, queste applicazioni necessitano di scalabilità per gestire grandi quantità di richieste degli utenti senza rallentamenti. Tuttavia, il database diventa un collo di bottiglia e la memorizzazione nella cache distribuita deve essere utilizzata per eliminare questo collo di bottiglia.

Scopri come utilizzare la cache distribuita come NCache nella vostra Applicazioni EF Core per rimuovere i colli di bottiglia della scalabilità del database.

Questo webinar tratterà (compresi esempi pratici di fonti:

  • Introduzione a EF Core e alle sue nuove funzionalità (Modello, Query, Salvataggio dei dati)
  • Colli di bottiglia della scalabilità del database in EF Core e modo in cui la cache distribuita li risolve
  • Varie opzioni di utilizzo NCache in EF Core (API dirette e metodi di estensione EF Core)
  • Dettagli sull'uso dei metodi di estensione EF Core per la memorizzazione nella cache
  • Come gestire la memorizzazione nella cache di raccolte e relazioni per i dati di riferimento e transazionali?
  • Alcune caratteristiche importanti di una buona cache distribuita come NCache

EF Core è un motore di mappatura relazionale a oggetti per .NET e .NET Core applicazioni. Ciò consente agli sviluppatori di generare automaticamente il codice di accesso ai dati, normalmente dovrebbero scrivere quel codice da soli. Simile a .NET Core, EF Core è anche multipiattaforma e intendo dire che potresti eseguirlo su Windows, Linux, Mac e sta diventando molto popolare tra la comunità di sviluppatori.

In questo webinar parleremo delle esigenze di prestazioni e scalabilità nelle app EF Core e dimostreremo diverse strategie per memorizzare nella cache i dati di riferimento e transazionali utilizzando i metodi di estensione di EF Core. Quali sono le sfide in termini di prestazioni e scalabilità che dovresti affrontare in una tipica applicazione EF Core e quindi parleremo di varie opzioni per l'uso della memorizzazione nella cache all'interno di Entity Framework Core Applications.

Mi concentrerò principalmente sui metodi di estensione, i metodi di estensione EF che abbiamo implementato per le applicazioni principali di Entity Framework. Quindi, esaminerò tutti i metodi di estensione di Entity Framework Core di NCache e poi parleremo di diverse strategie per gestire i dati di riferimento e i dati transazionali come suggerito da Nick. Vedremo anche come mantenere i dati sincronizzati quando i dati sono presenti in due posizioni diverse quando inizi a utilizzare una cache distribuita. Quindi, questo è ciò che abbiamo in agenda per il webinar di oggi. Comincerò rapidamente. Abbiamo molto da coprire. Ci sono molti esempi pratici che voglio mostrare. Quindi, iniziamo rapidamente.

Che cos'è Entity Framework/EF Core?

Quindi, la prima diapositiva è più un'introduzione a Entity Framework ed EF Core.

che-cosa-è-entità-framework-core

EF ed EF Core, questo è un motore di mappatura relazionale a oggetti per .NET e .NET core applicazioni. L'ultima versione di Entity Framework è denominata EF Core. Sai, di recente abbiamo visto EF Core 2.1 rilasciato insieme a .NET Core 2.1. Sai, semplifica la programmazione del tuo database. Sai, ti consente di generare automaticamente il tuo modello di accesso ai dati. Quindi, non devi scriverlo tu stesso. Riduce lo sforzo di sviluppo necessario per questo. Non è necessario scrivere codice di persistenza che in genere scriveresti tu stesso a livello ADO.NET e quindi è necessario disporre di una mappatura tra il modello dati e il modello a oggetti. Quindi, lo ottimizza semplicemente per te.

Quindi, è molto flessibile. Sta diventando molto popolare con, all'interno della comunità di sviluppatori e della sua multipiattaforma ed è molto popolare in .NET e .NET Core Applicazioni, in particolare applicazioni transazionali elevate che hanno a che fare con un carico di richieste elevato.

Diagramma architettonico di Entity Framework

Questo è un diagramma architettonico di Entity Framework.

diagramma-architettura

Sai, si applica anche su EF Core. Ci sono poche differenze tra EF ed EF Core. EF Core è leggero. Ha un approccio modulare. Non ce ne sono molti, non è necessario eseguire l'installazione completa. Puoi avere un approccio modulare. Lo hanno scomposto in pacchetti più piccoli, quindi puoi lavorare con il pacchetto che ti interessa.

Quindi, non è necessario eseguire l'installazione completa per quella materia e si sono anche sbarazzati di .edmx e quei file di mappatura. Quindi, sai, i pacchetti NuGet e ci sono alcuni comandi che esegui e genera il modello per te e quindi lavori semplicemente con le API LINQ to Entities sul livello dell'applicazione e l'approccio generale rimane lo stesso.

Che cos'è la scalabilità?

In genere, in un'applicazione EF Core che conosci, parleremo dei requisiti di prestazioni e scalabilità. La scalabilità è un'abilità all'interno di un'applicazione in cui è possibile aumentare la quantità di richieste che l'applicazione deve gestire. Ad esempio, il carico dell'utente aumenta o gli utenti che contribuiscono al caricamento delle richieste, il carico delle richieste aumenta all'interno di un'applicazione e se l'applicazione rallenta, l'applicazione non è scalabile.

Quindi, prestazioni elevate con carichi di picco è ciò che classifichiamo come scalabilità. Se la tua applicazione funziona abbastanza bene, in meno di un millisecondo, con una latenza inferiore a cinque utenti, dovrebbe avere lo stesso tipo di prestazioni, lo stesso tipo di latenza, una bassa latenza al di sotto, diciamo, di cinquemila utenti o cinquecentomila utenti e molto di carico della richiesta.

Quindi, prestazioni elevate sotto carico di stress elevato, sotto carichi di picco, questo è ciò che classifichiamo come scalabilità. EF Core.

Quali sono le applicazioni che necessitano di scalabilità?

che-applicazioni-hanno-bisogno-scalabilità

Potrebbe essere un'applicazione web ASP.NET. ASP.NET o ASP.NET Core che potrebbe avere a che fare con molte richieste. Potrebbe essere .NET e .NET Core servizi web, sempre sul sito. Poi abbiamo le applicazioni server IoT. Anche in questo caso potrebbe essere .NET o .NET Core o qualsiasi altro .NET generale e .NET Core Applicazioni che potrebbero gestire molte richieste o utenti nei propri domini.

Quindi, quelli sono i candidati per la scalabilità.

Dov'è esattamente il problema della scalabilità?

In genere, EF ed EF Core vengono distribuiti in una Web farm. Se si tratta di un'applicazione Web, si ridimensionano in modo lineare. Non si verificano problemi di scalabilità nel livello dell'applicazione, ma devono sempre parlare con un'origine dati relazionale back-end. Potrebbe essere un server SQL. Potrebbe essere Oracle Server o qualsiasi altro archivio di dati supportato da EF o EF Core. In EF Core hanno molti fornitori di dati. C'è un elenco di fornitori tra cui puoi scegliere. Quindi, finisci per parlare con un database.

Sebbene il livello dell'applicazione si espanda bene, ma questa archiviazione di dati, il database, il database relazionale diventa una fonte di contesa. È lento all'inizio perché non è in memoria. Sebbene EF Core abbia escogitato un provider di dati in memoria, ma si tratta di un archivio InProc e per i test locali. Ciò semplifica i test, ma una volta che l'applicazione è stata distribuita in produzione, devi avere a che fare con un database relazionale che è lento e non scalabile. È molto utile per l'archiviazione, ma non si ridimensiona quando è effettivamente necessaria quella scalabilità all'interno dell'applicazione.

Quindi, è una singola fonte che può soffocare sotto carichi estremi.

La Soluzione

La soluzione è molto semplice che inizi a utilizzare un sistema di cache disturbato come NCache, per la tua applicazione principale EF, la usi in combinazione con un database relazionale.

Architettura di distribuzione

Ecco l'architettura di distribuzione di NCache.

architettura di distribuzione

Prima di tutto, è in memoria. Quindi, è super veloce in confronto. Quindi hai più server che stanno archiviando, i dati che di solito ti consentono di recuperare dall'origine dati relazionale back-end. Puoi portarlo nella cache e potrebbe essere il tuo ASP.NET o ASP.NET Core App, .NET o .NET, Web Services o potrebbe essere .NET o .NET Core Applicazioni server o qualsiasi tipo di .NET o .NET Core Le applicazioni o anche le applicazioni Java possono trarre vantaggio da questo sistema di memorizzazione nella cache distribuito. Risparmia i tuoi viaggi costosi verso le origini dati relazionali. È in memoria. È possibile aggiungere più server e aumentare la capacità di questo cluster di cache in modo lineare.

Quindi, non è un singolo punto di errore. Non è una performance, collo di bottiglia. Non è un collo di bottiglia della scalabilità. Quindi, questo è l'approccio consigliato per seguirlo ed è ciò che tratteremo in dettaglio oggi, come utilizzare la memorizzazione nella cache .NET e sarà NCache come prodotto di esempio in un'applicazione EF Core tramite metodi di estensione.

3 Casi d'uso di cache distribuita comunemente usati

casi d'uso a cache distribuita

Alcuni casi d'uso comuni della cache distribuita. Puoi usarlo per la memorizzazione nella cache dei dati. Puoi utilizzare chiamate API dirette. Oppure usa Entity Framework o metodi di estensione anche per EF Core Applications e risparmi il più possibile i tuoi viaggi nel database.

Poi sul sito web, il sito web delle cose, hai ASP.NET, ASP.NET Core Memorizzazione nella cache. Potrebbe essere un'applicazione web o un servizio web. Se si tratta di un'applicazione Web, se potresti voler utilizzare le sessioni. Potresti voler usare ASP.NET e ASP.NET Core SignalR Backplane, Memorizzazione nella cache delle risposte per un ASP.NET Core. Allo stesso modo, è disponibile l'interfaccia IDistributedCache, visualizza lo stato e la cache di output. Queste sono tutte opzioni senza codice per le tue applicazioni.

E poi hai una potente messaggistica Pub/Sub. Puoi avere un argomento a cui ti iscrivi e quindi condividere messaggi tra diverse applicazioni. Editori e abbonati possono scambiarsi messaggi.

Quindi, questa è un'idea generale. Oggi ci concentreremo maggiormente sulla memorizzazione nella cache dei dati all'interno di un'applicazione EF Core e ti guiderò attraverso semplici passaggi per iniziare e poi ci espanderemo ulteriormente, condividendo sempre più dettagli su diversi scenari.

Quindi, iniziamo rapidamente con questo.

Memorizzazione nella cache dei dati dell'APP: Entità principali di EF

La prima cosa che vorrei trattare oggi è la memorizzazione nella cache dei dati dell'applicazione.

what-ef-core-entities-to-cache

Hai un'entità EF Core. Quindi, quelle entità devono essere memorizzate nella cache. Quindi, potresti vedere una singola entità. Ad esempio, hai un conteggio, somma. Questo è un valore o potresti, stai facendo un po' di smistamento e ne ottieni il primo cliente o i criteri sono tali che restituisca un singolo cliente, un singolo prodotto, un unico ordine. Quindi, questa è una singola entità, come memorizzarla nella cache? Allo stesso modo, abbiamo risultati di query che potrebbero essere una raccolta di entità. Quindi, non è una singola entità. È un insieme di entità. Ci sono due opzioni. Puoi memorizzare nella cache l'intera raccolta come un elemento nella cache oppure puoi memorizzare nella cache ogni elemento della raccolta, ciascuna entità all'interno di quella raccolta separatamente nella cache distribuita.

Opzioni di memorizzazione nella cache delle entità di EF Core

Quindi, esaminiamo gli approcci intorno a questo.

efcore-entità-caching-opzioni

Come discusso in precedenza, puoi usare direct NCache API. NCache L'API è un archivio di valori chiave a cui aggiungi dati NCache te stesso e poi ne ricevi tu stesso oppure puoi utilizzare EF Core Extension Methods e prenderti in carico di questa, singola entità e raccolta di entità.

Quindi, lascia che ti mostri prima la diretta NCache Approccio API comune a tutti i tipi di applicazioni. Puoi usarlo in EF Core. Puoi usarlo in EF normale o in qualsiasi altra applicazione .NET e poi parlerò dei metodi di estensione di base di EF che sono progettati specificamente per le tue applicazioni di base di EF e questo ti rende la vita molto più semplice dove vengono eseguite molte cose automaticamente per te e devi solo chiamare questo metodo di estensione insieme alle tue domande. Quindi, ti mostrerò entrambi questi approcci uno per uno e poi ci concentreremo maggiormente sui metodi di estensione in futuro.

Memorizzazione nella cache di una singola entità di EF Core: NCache API dirette

Quindi, il nostro primo esempio è la memorizzazione nella cache di una singola entità di EF Core.

Customers GetCustomer (string CustomerId)
{
	string key = "Customer:CustomerId:" + CustomerId;
	Customers customer = (Customers)_cache.Get(key);
	
	if (customer != null)
	{
		return customer;
	}
	else
	{
			customer = (from cust in database.Customers
					where cust.CustomerId == CustomerId
					select cust).FirstOrDefault();
                    _cache.Insert(key, customer);
	
		return customer;
}
}

Abbiamo un metodo GetCustomer, proprio qui. Te lo mostrerò con l'aiuto di un'applicazione di esempio che ho formulato per questo. Quindi, questo è il nostro primo metodo. Spero che tu possa vedere il mio schermo. Quindi, abbiamo Ottieni cliente. Sta prendendo il nostro ID cliente e l'idea qui è che questo sta restituendo una singola entità, giusto. Quindi, in genere con l'API diretta, la sfida è che devi, prendere in considerazione o qualcosa che devi implementare tu stesso.

Prima di tutto, devi avere una chiave e quella chiave è qualcosa in cui identifichi un'entità all'interno NCache ed è necessario mantenere tutte le chiavi nello stesso formato. Puoi trovare un formato di esempio, come mostrato sullo schermo. C'è una parola chiave cliente, quindi l'ID cliente e un parametro di runtime dell'ID cliente che costituisce la chiave della cache.

In NCache tutto è memorizzato in una coppia chiave-valore. La chiave è una chiave stringa e il valore è un oggetto consentito .NET e potrebbe essere anche qualsiasi entità EF Core, ma si formula la chiave e quindi si utilizza l'entità come oggetto da archiviare NCache. Ora per prima cosa controlli se quella chiave esiste già nella cache o meno chiamando la cache. Ottieni e se ottieni quel cliente direttamente dalla cache e questo è un diretto NCache API cache.Get, passi la chiave e se ottieni quel cliente restituisci il codice da qui, se non è nullo. Ma, se è null, ad esempio, stai eseguendo quella query per la prima volta, giusto, non c'è ancora nulla nella cache. Quindi, in tal caso, eseguiresti su Entity Framework Core, l'API LINQ sul database e quindi recuperi quel cliente dal database e chiami anche cache. Inserisci, archivialo con la stessa chiave che hai formulato e quindi il cliente è il entità che si desidera aggiungere e poi anche restituirla.

Quindi, è così che tratteresti effettivamente una singola entità utilizzando l'API giusta.

Memorizzazione nella cache della raccolta di entità di EF Core: NCache API dirette

Poi la raccolta. La raccolta può essere una raccolta come un singolo oggetto o ancora come una singola entità.

List<Customers> GetCustomersByCity (string CustomerCity)
{
	string key = "Customers:City = " + CustomerCity;
	List<Customers> custList;
    custList = (List<Customers>)_cache.Get(key);

	if (custList != null)
	{
		return custList;
	}
	else
	{
		custList = (from cust in database.Customers
					where cust.City == CustomerCity
					select cust).ToList();

		_cache.Insert(key, custList);
		return custList;
	}
} 

Ogni voce di raccolta potrebbe essere una singola entità aggiunta separatamente nella cache. Quindi, per questo abbiamo i clienti per città, quindi questo è il metodo successivo. Sta restituendo un elenco di clienti. Anche in questo caso, il criterio è superare la città del cliente. Ancora una volta, formuli una chiave. Ancora una volta, questo è lo sai, questo rappresenta una raccolta di clienti in base alla città e quindi questa città potrebbe essere un parametro di runtime qui. New York, Parigi, Londra e poi vai a prendere prima chiamando la cache. Prendi tu stesso dalla cache e poi controlli se esiste nella cache, se lo fa torni da qui, in caso contrario lo memorizzi semplicemente come unica collezione.

Quindi, questo elenco di clienti viene archiviato come un unico oggetto. Un'altra alternativa potrebbe essere quella di scorrere l'elenco dei singoli, dei clienti nelle entità cliente e chiamare la cache. Inserisci individualmente come mostrato qui. Giusto? Quindi, singole entità e raccolte di entità che utilizzano direct NCache API che verranno memorizzate nella cache utilizzando questi approcci. Ora abbiamo coperto le API dirette. Questo è qualcosa che puoi usare in qualsiasi applicazione.

Memorizzazione nella cache di entità singola di EF Core: metodi di estensione di EF Core

Concentriamoci sui metodi di estensione di Entity Framework Core. Quindi, lo stesso per una singola entità e raccolta di entità che utilizzano il NCache metodi di estensione. Quindi, presenterò FromCache.

Customers GetCustomer (string CustomerId)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities
	};
	
	Customers customer  = (from cust in database.Customers
							where cust.CustomerId == CustomerId
							select cust).FromCache(out string cacheKey,
                            options).FirstOrDefault();
	return customer;
}

Questo è il nostro primo metodo di estensione e, a proposito, per utilizzare questo metodo di estensione, prima di tutto devi introdurlo NCache Pacchetto NuGet Entity Framework Pacchetto NuGet di base all'interno dell'applicazione. Quindi, questo è un must. Se vai su installato, questo è un Alachisoft.NCachePacchetto .EFCore NuGet. Questo è ciò che devi introdurre all'interno della tua applicazione, questo è uno e poi tutto ciò che devi fare è, lasciami, aprire il contesto. Quindi, all'interno del contesto, chiami semplicemente NCacheConfiguration.Configure e sta prendendo un cacheID che sto leggendo dalle impostazioni dell'app e quindi sta anche prendendo il tipo di, se stai usando le dipendenze, questa è una funzionalità avanzata all'interno dei metodi di estensione di Entity Framework Core. È necessario fornire il tipo di origine dati.

Ma, una volta che hai chiamato NCache Configura metodo, ci sono varie cose che questo metodo richiede. Puoi anche impostare un logger, ma il gioco è fatto. Ciò ti consente di iniziare a chiamare NCache, Metodi di estensione EF Core all'interno dell'applicazione.

Memorizzazione nella cache della raccolta di entità di EF Core: metodi di estensione di EF Core

Quindi, lo stesso sai, metodo, ma questa volta ottieni il cliente attraverso metodi di estensione.

List<Customers> GetCustomersByCity (string CustomerCity)
{
	List<Customers> custList; 
	CachingOptions options = new CachingOptions
	{	
		StoreAs = StoreAs.Collection
	};
	custList = (from cust in database.Customers
				where cust.City == CustomerCity
				select cust).FromCache(out string cacheKey,
                options).ToList();
	return custList;	
}

Renderà tutto molto più semplice. Non devi controllare i dati nella cache da solo e non devi chiamare in modo esplicito inserisci tu stesso e, soprattutto, non devi chiamare, non devi costruire tu stesso la chiave della cache. Questo è completamente automatizzato come parte dell'implementazione di questo "FromCache".

Ora, da un punto di vista comportamentale, questo è esattamente ciò che abbiamo mostrato in precedenza. FromCache, prima di tutto accetta un'opzione di memorizzazione nella cache, le opzioni e 'cacheKey' è un riferimento esterno. Quindi, costruisce automaticamente la chiave della cache dietro le quinte. Devi solo chiamare dalla cache insieme alla tua query come metodo di estensione e devi semplicemente passare le opzioni di archiviazione che se restituisce sempre una raccolta, giusto. Quindi, in tal caso, puoi scegliere che sia un'entità separata o una raccolta separata, giusto. Quindi, potrebbe essere una raccolta di entità o potrebbero essere entità separate da quella raccolta.

Quindi, FromCache funziona in modo tale che se un'entità o se una query che hai eseguito e quelle entità risultanti sono già nella cache, la otterrebbe da NCache automaticamente. Ma, se non sono nella cache, in tal caso, eseguirebbe automaticamente quella query sul database e il set di risultati viene restituito e allo stesso tempo viene memorizzato nella cache e abbiamo anche allegato il contesto del database per le chiamate successive.

Ad esempio, se chiami FromCache per la prima volta, lo memorizza nella cache. La prossima volta che viene eseguita la stessa query, ovviamente verrà eseguita sulla cache ma non sul database. Questa volta il tuo contesto, se è stato eliminato in precedenza e per questa richiesta stavi utilizzando il costrutto using per quella materia, se apporti modifiche alle entità che allegano anche quelle modifiche al contesto. E quando chiami Salva modifiche, tutte le modifiche apportate a quelle entità che sono state recuperate dalla cache vengono effettivamente applicate al database. Quindi, questo è leggermente, ancora una volta un concetto leggermente avanzato. Passerò un po' più di tempo, in una fase successiva, ma solo per farti sapere, il metodo from cache funziona in modo tale che se qualcosa non è nella cache, lo preleverebbe dal database e lo inserirà nella cache. Ma, se qualcosa è già disponibile nella cache, lo restituirebbe semplicemente da lì. Quindi, questo automatizza l'intero approccio API diretto per te, ma costruisce anche le chiavi. Inoltre, organizza automaticamente i dati in un'entità separata o in una raccolta separata e devi solo chiamare dalla cache e passare la chiave e le opzioni di uscita.

Stesso caso per le collezioni. Per una raccolta, ottieni cliente per città. Verrebbe archiviato come una raccolta e poi di nuovo puoi chiamare dalla cache. Quindi, è così semplice iniziare con i metodi di estensione di Entity Framework Core.

Quali dati memorizzare nella cache in EF Core?

Il nostro prossimo argomento è in giro, il nostro prossimo argomento riguarda ancora l'utilizzo del tipo di dati nella cache.

cosa-dati-mettere-nella-cache-in-efcore

Potresti avere dati di riferimento o dati transazionali. C'è una domanda?

Sì, Ron, ho una domanda qui. Metodi di estensione di NCache lavorare con EF Core, mi consigliate .NET Core 2.0 Framework o a .NET Framework?

Bene. Quindi, poiché EF Core stesso può essere eseguito su .NET e in .NET Core, quindi, è molto flessibile. NCache i metodi di estensione funzionerebbero perfettamente. In effetti, sto eseguendo questa applicazione di esempio .NET framework 4.6.1 e ho un'altra applicazione di esempio su cui credo stia lavorando .NET core 2.0. Quindi, questo è .NET Core 2.0. Quindi, funziona con entrambi .NET frameworkse fondamentalmente è preferibile che tu usi .NET Core, ma è flessibile. Funzionerà per entrambi. Spero che risponda alla tua domanda.

Andando avanti, il segmento successivo all'interno della presentazione è quando inizi a pianificare la memorizzazione nella cache in modo corretto e ovviamente i metodi di estensione del core del framework di entità rendono la tua vita molto più semplice in termini di memorizzazione nella cache. Quindi, in realtà, molte cose vengono eseguite automaticamente. Quindi, la prossima domanda è quali dati memorizzare nella cache, giusto?

Quindi, ho classificato i dati in due categorie. Abbiamo dati di riferimento. Questa è una ricerca di dati e poi abbiamo i nostri dati transazionali, che vengono creati dinamicamente e cambiano molto frequentemente. Quindi, dati di riferimento, un rapido esempio sarebbero prodotti, dipendenti. Non è un dato statico al 100% ma è qualcosa che non cambia così frequentemente. Ma cambia, la frequenza del cambiamento non è così grande. E per questo dovresti pianificare di memorizzare nella cache interi dati di riferimento. Tutti i dati di riferimento devono essere memorizzati nella cache come un must e quindi i dati transazionali sono dati creati dinamicamente. Come ordini, account, alcune elaborazioni del flusso di lavoro su una raccolta specifica di dati e l'ambito di tale raccolta è solo per quel flusso di lavoro. Una volta che il flusso di lavoro ha completato l'esecuzione, quei dati non sono più necessari e anche questi dati possono cambiare molto frequentemente. Tanto che può cambiare in cinque minuti. Considerando che i dati di riferimento sono in genere dati di ricerca che possono cambiare tra le ore. Da 1 a 2 ore, da 5 a 10 ore o anche in giorni.

Abbiamo una domanda qui. Come identificheresti questo oggetto memorizzato nella cache durante il recupero utilizzando le estensioni EF proprio come chiavi create automaticamente? In realtà, non recuperare ma eliminare una chiave particolare?

Bene. Quindi, abbiamo un metodo di estensione per il recupero. Il metodo di estensione viene eseguito insieme a EF Core. Pertanto, l'oggetto restituito verrebbe identificato sulle stesse righe in cui la query LINQ lo identificherebbe. Penso che la domanda sia più focalizzata su cosa succede quando prevedi di aggiornare i record e per questo abbiamo una serie di API. Ti diamo un metodo che ti consente di generare una chiave contro un'entità. C'è un metodo di generazione delle chiavi che abbiamo reso pubblico. Quindi, prima di apportare direttamente una modifica alla cache e presumo che questa domanda sia più focalizzata sull'eliminazione di qualcosa nella cache o sull'aggiornamento di qualcosa nella cache o sulla rimozione o sull'aggiunta esplicita di qualcosa nella cache. Abbiamo esposto la classe cache che ti mostrerò tra un po' e poi c'è una generazione di chiavi. Ancora una volta, si passa una stringa e si utilizza il riferimento out e si passa anche l'entità. Quindi, contro quell'entità utilizziamo lo stesso approccio e ti forniremo una chiave e usando quella chiave puoi identificare l'oggetto quell'entità, se esiste nella cache dovresti essere in grado di aggiornarla e rimuoverla.

Penso che verso la fine ti mostrerò un esempio di come ottenerlo, ma solo per farti sapere, ci sono metodi a cui siamo stati esposti, prendi la chiave da NCache anche. Spero che risponda alla tua domanda.

Memorizzazione nella cache dei dati di riferimento in EF Core

Andare avanti. Quindi, abbiamo parlato dei dati di ricerca e quindi dei dati creati dinamicamente.

memorizzazione nella cache dei dati di riferimento in ef-core

Quindi, analizzerò uno per uno diversi approcci per gestirlo. Quindi, prima di tutto parleremo dei dati di riferimento in EF Core. Come ho già detto, di solito si tratta di dati di ricerca. Quindi, ci sono due cose che dovresti fare come un must. Dovresti prima di tutto caricare interi dati, interi dati di riferimento nella cache come un must e la motivazione qui è che questi dati sono qualcosa che non cambia così frequentemente. È un catalogo prodotti in un EF, in un'applicazione di e-commerce. Ci sono alcuni sconti su alcuni prodotti mentre quello sconto è abilitato, diciamo per tre giorni. Questi prodotti potrebbero non cambiare, quindi è meglio memorizzare nella cache tutti quei prodotti NCache e salva i tuoi costosi viaggi nel database per farlo il più possibile. 100%, i dati devono essere caricati nella cache. Quindi, non devi tornare all'origine dati e quindi memorizzarli sempre nella cache come entità separate. Come mai? Poiché i prodotti, l'intero set di dati potrebbe essere costituito da migliaia e migliaia di prodotti.

Diciamo, database Northwind. I prodotti possono variare da 50,000 a 100,000 prodotti. Ma potresti aver bisogno solo, diciamo, di 10 di quelli o 100 di quelli per una determinata richiesta. Quindi, se li archivi come entità separate, puoi eseguire query LINQ. NCache supporta anche LINQ attivo NCache direttamente. Quindi, puoi eseguire LINQ per ottenere il sottoinsieme dei dati interrogando il sottoinsieme delle entità da NCache come pure.

Quindi, queste sono due regole che dovresti seguire come must e ho un esempio e qui sto introducendo il nostro secondo metodo di estensione chiamato Load Into the Cache.

Memorizzazione nella cache dei dati di riferimento in EF Core: precaricamento della cache

Ora, funziona in questo modo e questo è destinato solo ai dati di riferimento. Questo è un precaricatore nella cache.

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};	
	
	// Loads all products into cache as individual entities
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();
}

Quindi, la motivazione qui è che dovresti chiamare questo metodo, diciamo Carica tutti i prodotti e dovresti assicurarti di archiviarlo come entità separate e dovresti eseguire una query che dice dai prodotti nel database prodotti e selezionare prodotti . Quindi, non stai specificando alcun criterio che significhi che questo caricherebbe tutti i 60,000 prodotti nella cache e quindi stai utilizzando LoadIntoCache, giusto. Quando dici entità separate devi solo passare questa opzione e creeremo semplicemente un'entità separata per ogni prodotto nella cache e questo è di nuovo un pre-caricatore, giusto. Dovresti precaricare questo..

Ci sono due opzioni. È possibile eseguire un'applicazione separata per questo che può assumersi la responsabilità di precaricare la cache. Potrebbe trattarsi dell'avvio dell'applicazione o di un'applicazione separata oppure potrebbe essere un'implementazione del caricatore di cache di NCache anche. C'è un caricatore di cache e nelle versioni future si stava lavorando anche sull'aggiornamento della cache.

La responsabilità del caricatore di cache è che viene effettivamente eseguito all'avvio della cache e quindi si assicura che tutti i dati che si desidera caricare nella cache vengano caricati come parte di esso. È la tua implementazione ma NCache semplicemente lo chiama. Ma, come ho già detto, puoi inventare un metodo in questo modo e assicurarti di chiamarlo una volta all'avvio dell'applicazione o fare in modo che un'applicazione separata lo faccia e condivida questi dati su tutte le istanze dell'applicazione.

Ora, una volta fatto, come interrogare i dati fuori dalla cache ea quel punto. Introdurrò il mio terzo metodo di estensione che è From Cache Only.

Memorizzazione nella cache dei dati di riferimento in EF Core: ricerca dei dati di riferimento solo dalla cache
List<Products> FindDiscontinuedProducts (NorthwindContext database)
{
	//Fetch discontinued products only out of all products 
	List<Products> discontinuedProducts;
	
	discontinuedProducts = (from product in database.Products 
   	 where product.Discontinued == true
   	 select product).FromCacheOnly().ToList();
	
	return discontinuedProducts;

}

Quindi, il primo metodo di estensione era FromCache che era, se qualcosa è nella cache, prenderlo da lì. In caso contrario, vai automaticamente al database e recuperalo. LoadIntoCache viene sempre eseguito sul database. Non viene mai eseguito sulla cache sebbene stia tornando, ma questo viene restituito dal database come must in modo che il set di dati venga aggiornato. Un nuovo dato viene caricato e quindi memorizzato nella cache, quindi FromCacheOnly viene eseguito solo su NCache perché questo è progettato solo per i dati di riferimento. Quindi, per i dati di riferimento dovresti usare una combinazione di LoadIntoCache. In modo che i dati tutti i set di dati esistano nella cache come entità separate e quindi chiamerai FromCacheOnly in modo che solo il set di dati a cui sei interessato, ovvero i prodotti fuori produzione in questo caso, siano stati portati solo dalla cache. Quindi, non devi assolutamente accedere al database. Parlerò di come mantenere aggiornati questi dati quando i dati cambiano nel database. Quindi, spero che questo abbia senso. Lascia che ti mostri questo esempio proprio qui.

Quindi, sto chiamando questo metodo proprio qui e poi sto restituendo un elenco di prodotti, prodotti fuori produzione utilizzando un semplice EF, l'API LINQ direttamente su NCache entità.

Quindi, questo non verrebbe eseguito affatto sul database. Questo verrebbe eseguito solo sulla cache perché sto usando FromCacheOnly, metodo di estensione. Spero che aiuti. Abbiamo trattato tre metodi di estensione, FromCache che è più un caso d'uso di dati transazionali e quindi abbiamo trattato LoadIntoCache e FromCacheOnly. Per i dati di riferimento dovresti concentrarti sull'utilizzo di interi dati usando LoadIntoCache e quindi separare le entità e quindi per le query dovresti usare FromCacheOnly.

Memorizzazione nella cache dei dati transazionali in EF Core

Successivamente, parleremo di dati transazionali e poi parleremo di come mantenere questi dati aggiornati sia per riferimento che per transazione.

memorizzazione nella cache dei dati transazionali in efcore

Ora, i dati transazionali sono solitamente un working set. Ho già spiegato che si tratta di dati creati dinamicamente. È necessario solo per un utente corrente, una richiesta corrente o un flusso di lavoro in esecuzione e una volta eseguito, potresti non aver più bisogno di quei dati. Quindi, è probabile che solo l'istanza dell'applicazione che effettivamente recupera quei dati che quelle entità siano necessarie solo da quell'istanza dell'applicazione. Quindi, non ha senso archiviare tutti i tuoi dati transazionali nella cache. Non è un requisito. Dovresti solo memorizzare nella cache il working set. Quindi, questo è il passaggio numero uno. Quindi, dovresti memorizzare nella cache i risultati della query. Puoi recuperare le entità più facilmente accessibili e il secondo passaggio è che ci sono due opzioni 2a, 2b.

Recupera e memorizza nella cache come raccolta

Puoi memorizzare nella cache i tuoi dati transazionali come un'intera raccolta. Questo è un approccio preferito.

List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs = StoreAs.Collection,
	};

	//Fetch from cache. If not found then fetch from DB.
	orderList = (from customerOrder in database.Orders 
				where customerOrder.Customer.CustomerId==CustomerID 
				select customerOrder)
				.FromCache(out string cacheKey, options).ToList();
	
	return orderList;
}

Di solito hai sempre bisogno dell'intera collezione, perché ci stai lavorando e quindi puoi anche archiviare, anche entità separate. Dipende interamente da te e questo è per lo scenario in cui, sebbene tu abbia memorizzato nella cache una raccolta, la memorizzi comunque come entità separate perché potresti aver bisogno solo di due o tre entità di quella raccolta. Quindi, è meglio avere un approccio granulare durante l'archiviazione delle raccolte e abbiamo GetCustomerOrders. Gli ordini sono dati piuttosto transazionali. Ci deve essere un'unità di elaborazione che si occupa di determinati ordini ed è probabile che ogni flusso di lavoro che lo sta facendo abbia il proprio insieme di ordini.

Quindi, ti mostrerò questo esempio molto velocemente. Quindi, funziona in modo tale da inserire molte opzioni di memorizzazione nella cache. In realtà non entriamo nei dettagli qui. Conserva come collezione. È così che scegli di archiviarlo come raccolta e quindi sto usando FromCacheOnly. Il motivo per i dati transazionali, sto usando FromCache perché i dati possono esistere nella cache e se fa l'intera raccolta devo solo usarli. Non devo andare al database. Ma se non esiste nella cache e anche questi dati cambiano molto frequentemente, abbiamo anche impostato una scadenza su di esso, diciamo, 30 secondi, quindi potresti voler tornare al database. Se usi FromCacheOnly puoi restituire un valore null se non esiste nella cache, se è già scaduto.

Pertanto, per i dati transazionali utilizzare il metodo di estensione From Cache, per i dati di riferimento utilizzare LoadIntoCache per precaricare e quindi utilizzare FromCacheOnly. Quindi, questo è l'approccio per farlo.

Recupera e memorizza nella cache come entità separate

Per entità separate, tutto ciò che devi fare è archiviare, chiamarlo.

List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs.SeperateEntities
	};

	//Fetch from cache. If not found then fetch from DB.
	orderList = (from customerOrder in database.Orders 
				where customerOrder.Customer.CustomerId==CustomerID 
				select customerOrder)
				.FromCache(out string cacheKey, options).ToList();
	return orderList;
}

Lasciami usare questo e invece di usare un'entità separata dì solo, (devo commentare avrei dovuto commentare) Giusto, archivia come entità separate. Questo è tutto ciò che devi fare.

Quindi, Ron, mentre stai esaminando questo, c'è una domanda. Nell'esempio precedente, durante la query dei dati di riferimento, è presente un'indicizzazione? Perché, solo questo è quello che faresti sul database per farlo….

Assolutamente, questa è un'ottima domanda e per i dati di riferimento, poiché viene eseguita solo in base alla cache, questa query LINQ richiede che il tuo prodotto e l'attributo lungo il quale stai eseguendo la query LINQ siano indicizzati e di fatto lo sono utilizzando i dati dell'indice ed è molto semplice da indicizzare, devi solo fornire il tipo, il modello e quindi fornire gli attributi che devi indicizzare. Quindi, questi sono attributi dell'indice e stiamo effettivamente eseguendo query sugli attributi dell'indice. Spero che risponda alla tua domanda.

Mantenere la cache fresca

Passerò rapidamente alla nostra parte pratica, ti mostrerò il prodotto reale in azione e poi il segmento più importante di questo webinar come mantenere aggiornati i dati della cache rispetto al database e anche per quanto riguarda i dati di riferimento e dati transazionali.

Va bene, quindi ho intenzione di aprire un nuovo progetto. Va bene, quindi, la parte demo pratica ti mostrerò rapidamente il prodotto reale in azione in modo che tu sappia come appare una cache distribuita e quindi eseguiremo l'applicazione su di essa e ti mostrerò come mantenerla è fresco, i dati e la cache sono freschi.

Ho già installato NCache su due delle mie scatole 107 e 108. Li userò come i miei server cache e la mia macchina personale proprio qui, il mio laptop fungerà da client.

Quindi, prima di tutto lancerò il NCache strumento di gestione che viene installato con NCache e creerò una cache, diciamo, chiamiamola EF Core cache. Userò due server. Mantieni le repliche delle partizioni come topologia di memorizzazione nella cache e quindi l'opzione di replica asincrona perché è più veloce e qui ho specificato i server che ospiteranno la mia cache. Quindi, ho due server, demo 1 e demo 2 e una porta TCP/IP per la comunicazione. È tutto guidato da TCP/IP per quanto riguarda la comunicazione tra server e client.

Dimensioni della cache, in base ai dati che prevedi di memorizzare nella cache. Se si tratta di dati di riferimento, dovresti tenere in considerazione che stai caricando tutti i prodotti, tutti i clienti. Allo stesso modo, se si tratta di dati transazionali, è necessario tenere conto del working set e anche un po' più di spazio per quello. Mantieni tutto semplice, scegli la finitura e il gioco è fatto. È così semplice iniziare NCache e configurare una cache.

Dato che sto eseguendo applicazioni sulla mia macchina, devo solo aggiungere la mia casella come macchina client. Posso avviare e testare questo cluster di cache e dopo posso eseguire l'applicazione di esempio per connettermi ad esso. Ecco com'è semplice. Abbiamo un regolare NCache webinar sull'architettura e il ridimensionamento delle app .NET in cui parliamo di queste configurazioni in dettaglio. Quindi, se ci sono domande, potresti voler esaminare anche quei webinar.

Ti mostrerò anche alcuni aspetti di monitoraggio. Finestra delle statistiche e poi la aprirò NCache strumento di monitoraggio in modo da poter effettivamente eseguire l'applicazione dello strumento di stress test che viene installata NCache e vedere le cose in azione. Quindi, questo è uno strumento di stress test. Lo eseguirò su questo perché la mia casella è un client, quindi posso semplicemente fornire il nome e dovrebbe connettersi a questo e dovrei essere in grado di simulare un carico fittizio sul mio cluster di cache, ecco fatto. La dimensione della cache sta crescendo, gli elementi vengono aggiunti e il caricamento delle richieste al secondo mostra anche l'attività su entrambi i server e quindi questo strumento di monitoraggio, penso che stia richiedendo tempo, stia creando dashboard.

strumento di stress test

Quindi, lascialo andare e nel frattempo fammi eseguire un'altra istanza di questo strumento dal server stesso. Colpa mia. Bene, quindi puoi vedere la maggiore quantità di richieste al secondo in crescita. Per qualche motivo ci vuole del tempo per caricare la dashboard, lo strumento di monitoraggio. Penso che lo lascerò qui non appena tornerà ti mostrerò i dettagli di monitoraggio di questo strumento.

Mantieni la cache fresca: dati di riferimento

Bene, il nostro prossimo segmento all'interno di questo webinar è mantenere aggiornati i dati della cache all'interno di un'applicazione Entity Framework Core e per questo utilizzerò nuovamente dati di riferimento ed esempi di dati transazionali. Quindi, inizieremo con i dati di riferimento.

Keep-cache-fresh-reference-data

Abbiamo già stabilito che per memorizzare nella cache i dati di riferimento è necessario memorizzare nella cache l'intero set di dati. Ad esempio, se hai dei prodotti, dovresti caricare tutti i prodotti nella cache e quindi caricarli come entità separate. Allora qual è il problema con questo?

Poiché, i dati di riferimento, tutti i dati di riferimento nella cache e quindi si utilizza solo la cache utilizzando il metodo di estensione FromCacheOnly. Ora, non vuoi permetterti un set di dati parziale dalla cache. Se si tratta di prodotti fuori produzione o stai eseguendo alcuni criteri, vuoi che tutti quei prodotti siano nella cache. Ma ci sono possibilità che quei prodotti cambino effettivamente nel database. Ora i dati esistono in due luoghi diversi. Hai un database che è la tua copia principale e sebbene tu abbia caricato interi dati nella cache, ci sono ancora possibilità che il database venga aggiornato al di fuori dell'ambito delle tue applicazioni.

Quindi, per mantenere aggiornati i dati della cache, è necessario assicurarsi di disporre di una sorta di meccanismo che aggiorni automaticamente i dati e la cache e per questo abbiamo due opzioni. L'opzione numero uno è utilizzare la scadenza.

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};
	
	options.SetAbsoluteExpiration(DateTime.Now.AddHours(10)); 	
    options.SetResyncProviderName("MyEFCoreResyncProvider");
	
	// Load all products into cache with Expiration and Auto-Reload
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();

}

Questa è una scadenza basata sul tempo e quindi la mescoli, la usi in aggiunta con la funzione di ricarica automatica. NCache la funzione di scadenza ti consente di far scadere i dati, rimuovere i dati dopo il periodo di tempo specificato, diciamo, 5 ore, 10 ore e con dati di riferimento poiché sono lunghi, i dati in esecuzione sono dati di ricerca, dati anagrafici, quindi la frequenza di modifica non lo è fantastico, quindi puoi trovare un numero comodo di te, ore o sai, potrebbero essere 5 ore, 10 ore, 24 ore. Quindi, in base a ciò puoi impostare un tempo di scadenza. Ma, come accennato in precedenza, non vuoi davvero perdere o rimuovere quei dati dalla cache.

Quello di cui hai veramente bisogno è che i dati che vengono modificati, diciamo, 10 prodotti sono scaduti in base alla scadenza di quello che hai specificato, dovrebbe ricaricare automaticamente quei dati nella cache con meccanismo di ricarica automatica. e NCache te lo fornisce con l'aiuto di un gestore read-through. Quindi, tutto ciò che devi fare è caricare di nuovo interi dati e la cache utilizzando il caricamento nella cache, utilizzare entità separate ma insieme a queste utilizzarle per caratteristiche. Ad esempio, Imposta scadenza assoluta.

Questo è il valore di scadenza che imposteresti su tutti i prodotti che verranno caricati nella cache e quindi imposti il ​​provider di risincronizzazione, che essenzialmente chiama il tuo provider di lettura all'interno NCache. La lettura è combinata con la scadenza. Quindi, invece di rimuovere i dati dalla cache, in realtà si ricarica, poiché conosce tutte le chiavi e tutte le informazioni relative al database, abbiamo solo bisogno che tu passi il contesto e in base a quel contesto chiamiamo effettivamente il tuo provider automatico e risincronizziamo. Otteniamo il valore aggiornato dall'origine dati.

Lascia che te ne mostri un esempio funzionante. Ecco un metodo. Sto memorizzando questo come entità separate. In genere, imposterei una scadenza di 5 ore, ma dato che non abbiamo molto tempo, quindi, quello che farei davvero è che imposterò una scadenza di circa 30 secondi e metterò un punto di interruzione proprio qui e caricherò tutti i prodotti nella cache. A questo punto non imposterei un provider di risincronizzazione solo per mostrarti come funzionano le scadenze e non appena la scadenza entra in gioco rimuoverà gli elementi dalla cache e poi ti mostrerò come, prenditi cura di questo scenario in modo tale che invece di rimuovere, ricaricare semplicemente utilizzando il gestore read-through.

Quindi, userò la cache locale per questo bit di esempio. Cancellerò solo il contenuto solo per essere al sicuro, quindi eseguirò questo pezzo di codice e raggiungerò il punto di interruzione. Giusto. Quindi, ha 30 secondi di scadenza e ho appena colpito e ho ricevuto i prodotti fuori produzione, giusto. Quindi, abbiamo tutti i prodotti qui e abbiamo circa mille voci qui. Dopo 30 secondi questi mille elementi scadranno in base a questa scadenza assoluta, segnala che abbiamo impostato ed eseguirò di nuovo questa query e vedresti che non restituirebbe nulla perché nella cache non esiste nulla. Sta usando solo dalla cache. Quindi, abbiamo articoli scaduti. Lo eseguirò ancora una volta e noterai che ho un valore 0.

Quindi, questo non è ciò che è consigliato o preferito, considerando che questi sono i tuoi dati di riferimento, tutti i dati sono già caricati nella cache e stai chiamando il metodo di estensione From Cache Only. Quindi, hai bisogno di tutti i dati disponibili, non la risposta parziale o i dati mancanti e allo stesso tempo dovrebbero essere ricaricati dopo la tua scadenza. Invece di rimuoverlo dovrebbe ricaricare ed è esattamente quello che faremo con l'aiuto di questo nome del provider di risincronizzazione impostato.

Ho un provider di risincronizzazione di esempio, che è proprio qui, IReadThruProvider. Quello che fa davvero è che ti abbiamo fornito un'implementazione predefinita di questo.

namespace Alachisoft.NCache.EFSampleResyncProvider
{
    public abstract class EFDefaultResyncProvider : IReadThruProvider
    {
        public virtual void Init(IDictionary parameters, string cacheId)
        {
            db = InitializedDbContext();
        }
        public virtual void LoadFromSource(string key, out 					
        ProviderCacheItem cacheItem)
        {
            cacheItem = new ProviderCacheItem(FetchItemFromDb(key));
            cacheItem.AbsoluteExpiration = DateTime.Now.AddHours(10);
            cacheItem.ResyncItemOnExpiration = true;
        }
        public virtual void Dispose()
        {
            db.Dispose();
        }
    }
}

Questo è il nostro IReadThruProvider. Tutto quello che devi fare è mostrarlo con l'aiuto della cache che abbiamo configurato. Devi configurare il gestore read-through. Ad esempio, fammi solo creare una nuova cache, fammi solo creare una cache locale. Giusto. Quindi, è solo una cache locale. Mi limiterò a configurare una fonte di supporto. Abilita lettura, Aggiungi e diciamo EF predefinito e questo deve essere impostato e posso usarlo come progetto e l'implementazione è già stata eseguita.

Funziona in modo tale da aver implementato il gestore IReadThru. Questo è il provider di risincronizzazione predefinito, giusto. Ha alcuni metodi. Ha l'inizializzazione in cui si inizializza il contesto DB. LoadFromSource che viene chiamato in scadenza e all'interno di questo sto ricevendo l'elemento dal database. Se entro nella definizione, in realtà si prende cura di tutte le chiamate relative al database e questo è qualcosa che stiamo fornendo come parte della nostra implementazione. Il nostro pacchetto NuGet lo copre come parte di esso. Quindi, stiamo ottenendo la chiave e in base a quella chiave si passa al contesto e il contesto viene utilizzato per ottenere l'oggetto effettivo direttamente dal database.

Tutto quello che devi fare è sapere, ereditare, implementare questo provider di risincronizzazione predefinito EF e fornire la tua implementazione e fornirci il contesto del database.

Quindi, questa è una classe astratta che ti abbiamo dato. Devi solo fornire il contesto del tuo database Northwind o qualsiasi contesto del database che hai e in base a quello una volta che questo metodo è stato sovrascritto / implementato, devi semplicemente registrarlo con la tua cache. Ad esempio, questo è un provider di risincronizzazione. Se lo apro, ne contiene due. Uno è predefinito e l'altro è la tua implementazione e puoi passare la tua stringa di connessione e altre informazioni se necessario e il gioco è fatto. Devi semplicemente distribuire questo. Lasciami portare a questo punto e ti darebbe solo un successo su questo. Quindi, questo deve essere fatto. Come ho detto, questo è già stato fatto come parte di NCache, implementazione. Il pacchetto NuGet viene fornito con un provider di risincronizzazione che puoi semplicemente implementare implementando questo particolare metodo qui e fornendoci il contesto e il resto del lavoro viene svolto da questo provider di risincronizzazione predefinito di esempio, che in realtà funziona sulle stesse linee dell'estensione i metodi funzionano.

Costruiamo la tua chiave, quindi sappiamo quale chiave rappresenta quale entità e in base a tale entità e a quelle informazioni chiave interroghiamo effettivamente il database utilizzando Entity Framework, API. Ora questo è già stato fatto per la mia cache. Quello che ho fatto qui è che ho, è stato distribuito con successo. Quindi, per la mia cache l'ho già fatto. Ho questo EF predefinito e l'ho distribuito. Quindi, eseguirò lo stesso caso d'uso ma questa volta invece di farlo semplicemente scadere, lo ricaricherei. Quindi, questo è quello che ho intenzione di fare. Tutto quello che devo fare è impostare il nome del provider di risincronizzazione e quindi, poiché ho intenzione di aggiornare anche alcuni valori, utilizzerò 60 secondi. In genere, per i dati di riferimento, avresti molto più tempo specificato come scadenza assoluta, ad esempio 5 ore o anche più. Quindi, lo eseguirò con 60 secondi e questa volta vedo che il mio provider di risincronizzazione è impostato.

Quindi, eseguirò questo caso d'uso ancora una volta e ti mostrerò come viene aggiornato invece della scadenza, invece della rimozione. Quindi, questo è stato eseguito e si spera che torni a questo punto. Bene. Quindi, abbiamo i prodotti caricati. Lo eseguirò ancora una volta e, in questo periodo, poiché ha 60 secondi di scadenza, aggiornerò questo particolare prodotto, ID prodotto 17 e quello che faremo è dire semplicemente aggiornalo, va bene.

Sebbene sia aggiornato nel database, non verrebbe ancora aggiornato nel contesto dell'applicazione, poiché utilizza solo i dati della cache e non è ancora scaduto. Quindi, continueremo a ottenere i valori più vecchi e se noti nella mia cache che abbiamo migliaia di elementi e c'è un Readthru/sec, questo mostrerebbe alcune attività dopo, 60 secondi, quindi chiamerebbe automaticamente il gestore di lettura che abbiamo basta impostare.

Quindi, lasciami eseguire ancora una volta e mi aspetto di nuovo i valori dell'ordine, se non sono già stati ricaricati, ma ci sarebbe un punto in cui si ricaricherà semplicemente e dopodiché semplicemente invece di scadere ricaricherà semplicemente il 999 di i prodotti. C'è un elemento extra, di solito è un riferimento. Ecco qua. Quindi, invece della scadenza, solo un articolo è scaduto perché è un elenco di chiavi, altrimenti, tutti i dati di riferimento basati sulla mia query, lascia che ti mostri la query, dice dove l'ID prodotto è inferiore a 1000. Quindi, in realtà quello rappresenta 1000 prodotti.

Quindi, eseguirò questa query ancora una volta e questa volta poiché i dati sono già stati aggiornati alla scadenza, anziché alla rimozione. Quindi, mi aspetto che il prodotto aggiornato venga aggiunto nella cache. Quindi, ecco qua. Quindi, il mio prodotto è stato aggiornato come parte di questo. Quindi, questo è ciò che consigliamo come parte della nostra opzione numero uno che dice di utilizzare la scadenza ma con la funzione di ricarica automatica. Quindi, invece della scadenza, ricarichi semplicemente i dati e questo si occuperebbe di mantenere freschi i dati della cache. Quindi, ti viene in mente un tempo comodo che ti consente di mantenere i dati nella cache, continui a ricevere dati più vecchi e non appena quei dati più vecchi stanno per scadere, potrebbe essere un giorno di tempo, diciamo, 24 ore , potrebbero essere 2 giorni, una settimana, a seconda dell'ora comoda all'interno dell'applicazione. Potrebbero essere necessarie anche alcune ore e successivamente ricaricherebbero semplicemente quei dati nella cache.

Quindi, questa è la nostra opzione numero uno. Spero sia stato abbastanza semplice.

L'opzione numero due è che non usi una scadenza. Quindi, questo risolverebbe questo problema proprio qui dove i dati esisterebbero sempre nella cache. Ma i dati possono essere obsoleti nella cache e potrebbero essere obsoleti per sempre. Per questo, dovresti ricaricare manualmente e anche questo è molto semplice.

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};
		
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();

}

Tutto quello che devi fare è semplicemente chiamare questo Carica tutti i prodotti dopo un intervallo periodico. Ad esempio, se torniamo a questo punto proprio qui. Quindi, questo metodo deve essere chiamato dopo alcuni intervalli e, ancora una volta, come accennato in precedenza, di solito viene eseguito all'avvio dell'applicazione e potrebbe essere una delle applicazioni che se ne sta occupando, che si occupa di tutto questo. Quindi, potrebbe essere quello o potrebbe essere una delle applicazioni, un'applicazione separata che lo sta facendo. Quindi, potrebbe essere la tua applicazione, una delle tue istanze dell'applicazione o potrebbe essere un'applicazione completamente separata e quell'applicazione può chiamare periodicamente questo metodo dopo, diciamo, 5 ore, 24 ore, di nuovo che è il tuo tempo a tuo agio dopo il quale vuoi questo deve essere eseguito sul database e desideri che i tuoi prodotti vengano ricaricati.

Quindi, LoadIntoCache si prenderebbe cura di quel particolare scenario in cui verrebbe eseguito sul database e caricherebbe nuove copie nella cache. Quindi, è così che prendi in carico i dati di riferimento. Spero di essere stato abbastanza diretto.

Mantieni la cache fresca: dati transazionali

Passiamo al segmento successivo in cui utilizziamo i dati transazionali. Ora i dati transazionali sono qualcosa di breve durata, giusto. È un set di lavoro, come spiegato in precedenza. Quindi, puoi utilizzare da 5 a 10 minuti di scadenza. Quindi, cosa devi davvero fare qui, dal momento che stai usando FromCache che viene eseguito sulla cache, se esiste nella cache e se non esiste nella cache, lo eseguirà sempre automaticamente sul database. Quindi, questo è integrato in questo metodo di estensione, a differenza di FromCacheOnly che usi con lo scenario dei dati di riferimento, giusto, che viene eseguito solo sulla cache. Quindi, va bene avere alcuni dati disponibili, sia che tu li abbia archiviati come raccolta o come entità separata.

Scadenza breve, nessuna ricarica automatica
 private List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs = StoreAs.Collection
	};
	
	options.SetAbsoluteExpiration(DateTime.Now.AddSeconds(60));

    	List<Orders> orderList = (from customerOrder in database.Orders 					
        where customerOrder.Customer.CustomerId==CustomerID 
        select customerOrder).FromCache(out string cacheKey,
        options).ToList();

	return orderList;
 }

Quindi, usi semplicemente una scadenza breve, diciamo 60 secondi, anche se ho usato quell'esempio per i dati di riferimento, ma era per il bene di questa particolare demo, ma per i dati di riferimento di solito hai da 5 a 10 ore di scadenza e per i dati transazionali che hai da qualche parte tra 60 secondi o correlati, scadenza collegata e poiché stai utilizzando From Cache, diamo effettivamente un'occhiata a Ottieni ordini cliente, poiché stai utilizzando FromCache che dovrebbe consentirti di utilizzare, prendiamolo come esempio.

Bene, quindi, imposti qui una scadenza e chiami questo metodo di estensione FromCache e questo dovrebbe occuparsi di ottenerlo dal database se non esiste nella cache e dopo un po' se stai lavorando il set è attivo in la cache la otterresti dalla cache, se non è attiva nella cache è probabile che non sia più necessaria, giusto. Quindi, potresti finire per tornare al database e questa è la cosa giusta da fare con i dati transazionali. Quindi, spero che questo copra i nostri dati di riferimento, nonché gli scenari dei dati transazionali e come mantenere aggiornati i dati della cache rispetto a questi due.

Gestione delle relazioni nella cache

Passerò al nostro prossimo segmento, che è Gestione delle relazioni nella cache.

Ron, ho un paio di domande qui. Fa il NCache o gli elementi memorizzati nella cache risiedono in NCache server o sono in ombra in ogni server delle applicazioni?

Risiedono in NCache. Giusto, quindi gli oggetti esistono effettivamente NCache, giusto. Quindi, il repository effettivo viene mantenuto all'interno NCache e in realtà costruiamo le chiavi e gli oggetti insieme a questi metodi di entità. Quindi, questa è l'idea qui.

Un'altra domanda è: possiamo avere più caricatori di cache configurati o tutti devono essere configurati in uno, quando stavamo aggiungendo dati di riferimento alla cache?

Puoi perché il caricamento nella cache è un metodo generico, giusto. Quindi, in realtà carica qualsiasi cosa, la query che stai pianificando di eseguire correttamente. Quindi, è legato alla query. Puoi avere un multiplo di carico nella cache e potrebbe esserci un'applicazione separata o potrebbero essere posizioni diverse all'interno dell'applicazione. Quindi, è anche molto flessibile da questo punto di vista.

Gestione delle relazioni nella cache: uno-molti

List<Region> GetRegionWithTerritories(NorthwindContext database)
{
	List<Region> regionDetails;
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities
	};

	regionDetails = (from region in database.Region select region)
					.Include(region => region.Territories)
					.FromCache(options).ToList();

	return regionDetails;
}

Ci sono alcuni concetti importanti che voglio evidenziare. Come gestire le relazioni? Uno-a-molti e sai, molti-a-molti esempio.

Concentriamoci sull'uno a molti. Se hai diciamo regioni e poi ci sono territori che ne fanno parte, regioni e c'è una relazione uno a molti in corso tra regioni e territori. Andiamo all'approccio di sincronizzazione e all'interno, in realtà prendiamo le regioni da qui.

Va bene, quindi, prendi le regioni con i territori. L'idea di base qui è che hai la parola chiave Include e quindi usi FromCache e la memorizzi sempre come entità separata. L'idea qui è che l'elemento padre della regione verrà archiviato come elemento separato nella cache. Poiché la regione ha anche una relazione uno-a-molti con i territori ed esiste una raccolta di territori all'interno di ciascuna entità regionale, quindi, NCache obbedirebbe. Non appena chiami FromCache, otterrebbe semplicemente la regione e tutte le regioni vengono archiviate come entità separate e in base all'ambito specificato e tutti i territori con l'aiuto di FromCache verranno archiviati come raccolta separata all'interno di ciascuna regione .

Quindi, è un'entità che ha molti lati, il lato della raccolta come oggetto correlato. Quindi, è così che affronti il ​​caso d'uso da uno a molti.

Operazioni di aggregazione di memorizzazione nella cache

Quindi hai operazioni di memorizzazione nella cache di aggregazione. Sai, puoi risultare in un'entità o risultare in un valore.

operazioni di aggregazione nella cache

Ad esempio, ottenere un mittente Primo o Predefinito, giusto. Quindi, questo è qualcosa, diciamo, se faccio solo un primo o un predefinito qui, questo mi porterebbe il primo mittente e quindi sai in base a questo, questo verrà archiviato in NCache.

E allo stesso modo, potrebbe essere count sum. Potrebbe essere qualsiasi operazione aggregata, quindi potrebbe essere un valore. Anche in questo caso è possibile memorizzarlo NCache come entità separata.

Shippers GetFirstShipperInstance (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{ 
		StoreAs = StoreAs.Collection
	};

	Shippers shipper = database.Shippers.DeferredFirstOrDefault()
						.FromCache(out string cacheKey, options);

	return shipper;

}

E allo stesso modo, potrebbe essere count sum. Potrebbe essere qualsiasi operazione aggregata, quindi potrebbe essere un valore. Ancora una volta, questo può essere memorizzato in NCache come entità separata.

int GetTotalShippersCount (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.Collection 
	};

	int count = database.Shippers.DeferredCount()
				.FromCache(out 	string cacheKey, options);
	
	return count;

}

Architettura di cache distribuita

Quindi, questo copre il nostro webinar per quanto riguarda la parte tecnica. Verso la fine ti mostrerò un'architettura di cache distribuita.

Alta disponibilità

NCache come prodotto è molto, scalabile, veloce. È qualcosa che si basa sull'architettura peer-to-peer nel protocollo. Non esiste un singolo punto di errore. Puoi aggiungere o rimuovere i server al volo da una cache in esecuzione. Non è necessario arrestare la cache o nessuno dei client ad essa collegati. In modo dinamico puoi apportare modifiche a un cluster di cache in esecuzione.

elevata disponibilità

Topologie di memorizzazione nella cache

Quindi la nostra topologia più popolare è Cache di replica della partizione. Ciò consente di distribuire semplicemente i dati su tutti i server sotto forma di partizioni. Quindi, stanno mettendo insieme le risorse di memoria, le risorse di calcolo e questo ti offre una capacità logica e ogni servizio ha anche un backup. Server1 è backup su 2. Serve2 è backup su 1 e Serve3 è backup su Serve1. Quindi, in modo round robin, ogni server ha un backup su un altro server.

topologie di memorizzazione nella cache

Cache client (vicino alla cache)

Allo stesso modo, questa è la topologia molto veloce, molto scalabile e più popolare. Puoi anche avere un cache del cliente che può essere eseguito sulla tua casella di applicazione. È una cache locale ma è sincronizzata con la cache del server. Il sottoinsieme dei dati verrebbe automaticamente portato nella cache e senza modifiche al codice. Ciò migliora le tue prestazioni se i tuoi dati sono per lo più di natura di riferimento. Quindi, una volta caricato nella cache e quindi iniziando a chiamare questo sottoinsieme di dati chiamando FromCacheOnly, la cache del client sarebbe davvero di aiuto in quel caso.

cache del client

Replica WAN della cache

Replica WAN è un'altra caratteristica, la replica del bridge. Puoi avere siti di dati attivo-passivo o attivo-attivo. Tutti i dati, i dati EF Core, le sessioni ASP.NET o i dati regolari possono essere trasferiti nel sito di destinazione attraverso la WAN in modo attivo-passivo o attivo-attivo. Quindi, questo è cosa NCache copre come parte di esso.

wan-replicazione

Conclusione

Tanto per ribadire che mi prenderò un altro minuto prima di consegnarlo a Nick. Quindi, abbiamo parlato di entità singola e di archiviazione di raccolte di entità utilizzando API dirette. Era leggermente diverso in termini di metodi di estensione e poi abbiamo parlato di metodi di estensione che erano di natura molto più semplice e, sai, anche di natura più flessibile. FromCache è stato il primo metodo che recupera qualcosa dalla cache se esiste, in caso contrario, lo recupera automaticamente dall'origine dati, a differenza delle API dirette in cui devi implementarlo da solo. Costruisce anche le chiavi e le relative opzioni impostate qui.

Poi abbiamo parlato di dati di riferimento e transazionali. Per gestire i dati di riferimento, è necessario caricare interi dati usando LoadIntoCache e chiamare FromCacheOnly. LoadIntoCache viene sempre eseguito sul database e quindi, FromCacheOnly, viene eseguito solo sulla cache e quindi abbiamo parlato di dati transazionali che puoi gestire con l'aiuto di FromCache e hai impostato alcune scadenze. Dati di riferimento, per mantenerli aggiornati è necessario utilizzare le scadenze e quindi utilizzare il ricaricamento automatico o non utilizzare le scadenze e quindi ricaricare manualmente utilizzando LoadIntoCache. Quindi abbiamo parlato dei dati transazionali, che devi trovare, una sorta di scadenza e utilizzare FromCache in modo che se esiste nella cache lo ottieni. Se non esiste nella cache, lo ottieni sempre dal database.

Quindi, questo conclude la nostra presentazione. Per favore fatemi sapere se c'è qualche domanda.

Puoi sempre raggiungerci a support@alachisoft.com. In caso di domande tecniche, puoi contattarci anche tramite sales@alachisoft.com. Se vuoi dargli un'occhiata, scaricare il prodotto, puoi andare sul nostro sito alachisoft.com e puoi scaricare NCache e viene fornito con una versione di prova di 30 giorni che puoi utilizzare e se ci sono domande, faccelo sapere, altrimenti, grazie mille per aver partecipato a questo spettacolo oggi, al webinar, e ci vediamo la prossima volta. Grazie mille Ron. Grazie ragazzi.

Cosa fare dopo?

 
© Copyright Alachisoft 2002 - . Tutti i diritti riservati. NCache è un marchio registrato di Diyatech Corp.