Possiamo inserire un server cache tra la nostra applicazione e il database per rendere le nostre applicazioni più veloci. Ma non è sufficiente quando dobbiamo ridimensionare le nostre applicazioni. Vediamo due modelli di memorizzazione nella cache per prestazioni migliori e come NCache li implementa.
Scalabilità attraverso il partizionamento dei dati
Con il partizionamento dei dati, dividiamo grandi insiemi di dati in più piccoli e li distribuiamo tra i nodi. In questo modo, suddividiamo letture e scritture tra i nodi, migliorando le prestazioni complessive delle nostre applicazioni. NCache supporta diversi topologie di memorizzazione nella cache. In questo contesto, una topologia è una strategia di archiviazione, replica e connettività client dei dati. Esistono due topologie che implementano il partizionamento dei dati: il Topologie partizionate e Partition-Replica. In queste due topologie, NCache divide i dati in bucket e posiziona tali bucket nei nodi del nostro cluster.
NCache utilizza 1000 bucket e li divide equamente tra i nodi in un cluster. Ad esempio, se avviamo un cache cluster con un singolo nodo, NCache assegna tutti i bucket al nostro singolo nodo. Se aggiungiamo un altro nodo, NCache divide quei 1000 bucket in due nodi da 500 bucket. Inoltre, se rimuoviamo un nodo, NCache distribuisce i propri bucket nei nodi rimanenti.
Dal NCache divide i nostri dati in bucket e nodi, un client cache si connette a tutti i nodi ma esegue operazioni di lettura e scrittura direttamente sul nodo che contiene un elemento. Anche se un nodo non è disponibile, un client cache reindirizza le nostre richieste utilizzando i nodi attivi per completare le nostre operazioni. NCache distribuisce i bucket tra i nodi mantenendo quasi la stessa dimensione dei dati in ogni nodo. In questo modo, non solo dividiamo le letture e le scritture tra i nodi, ma aumentiamo anche la capacità di archiviazione del nostro cluster con ogni nodo che aggiungiamo.
Grazie al partizionamento dei dati, le topologie Partition e Partition-Replica ridimensionano il carico delle transazioni e la capacità di archiviazione. Naturalmente Partition e Partition-Replica sono solo due delle topologie supportate. NCache ha di più topologie con diverse strategie di archiviazione e replica dei dati. Ad esempio, alcuni di essi sono adatti ad applicazioni con più letture o scritture.
Strategie di memorizzazione nella cache
Con il partizionamento dei dati, miglioriamo la disponibilità e le prestazioni delle nostre applicazioni poiché possiamo memorizzare nella cache più elementi nel nostro cluster che in un singolo server. Inoltre, possiamo migliorare le prestazioni della nostra applicazione scegliendo come popolare la nostra cache. Esistono due strategie per popolare la nostra cache: cache-aside e Read-Through/Write-Through.
Con la strategia cache-aside, il nostro server cache si trova accanto al nostro database. Se la nostra cache non contiene un elemento, la nostra applicazione lo legge dal nostro database e lo memorizza nella cache. Con questa strategia, il cache server non interagisce direttamente con il nostro database. Probabilmente, la strategia cache-aside è la prima cosa che ci viene in mente quando pensiamo al caching.
A differenza della strategia cache-aside, con le strategie Read-Through/Write-Through, la nostra cache funziona come la principale fonte di dati. Qui, la nostra cache legge e scrive i dati nel database. Pertanto, queste strategie funzionano meglio con i dati di riferimento che leggiamo frequentemente e cambiamo periodicamente, e con le righe del database possiamo facilmente mappare agli elementi della cache.
Con Read-Through/Write-Through, spostiamo parte del codice di accesso ai dati dalla nostra applicazione alla cache, rendendo il codice dell'applicazione più semplice e più piccolo. NCache supporta le strategie di memorizzazione nella cache Read-Through e Write-Through.
Memorizzazione nella cache di lettura
NCache usa un provider Read-Through personalizzato per chiamare il database sottostante se si verifica un errore nella cache. Inoltre, possiamo forzare NCache leggere sempre il database anche se non abbiamo cache miss. Il nostro provider Read-Through dovrebbe implementare il formato Interfaccia IReadThruProvider. Contiene metodi come Carica da origine ed Caricatipodatidaorigine.
Una volta che abbiamo un file Provider di lettura continua distribuito al nostro server di cache, tramite il NCache Manager o script PowerShell, possiamo usarlo dalle nostre applicazioni client passando l'oggetto ReadThruOptions come parametro al metodo Get, in questo modo,
1 2 3 4 5 6 7 8 9 10 11 |
// After having NCache up and running... var key = $"Product:123456"; var readThruOptions = new ReadThruOptions { Mode = ReadMode.ReadThru }; // Retrieve a cached item with Read-Thru enabled var data = cache.Get<Product>(key, readThruOptions); // Do something with the cached product here... |
Memorizzazione nella cache di scrittura
D'altra parte, con la strategia Write-Through, NCache aggiorna prima la nostra cache e, solo successivamente, il nostro database. NCache può aggiornare il nostro database in modo sincrono o asincrono. NCache chiama gli aggiornamenti Write-Through asincroni: Write-Behind.
Il nostro provider Write-Through dovrebbe implementare il Interfaccia IWriteThruProvider. Contiene il metodo WriteToDataSource con overload per elementi singoli e multipli e strutture di dati. Il nostro provider Write-Through deve supportare le operazioni di scrittura per aggiungere, eliminare e aggiornare gli elementi.
Analogamente alla distribuzione di un provider Read-Through, dobbiamo distribuire il nostro Provider di scrittura alla nostra cache. Una volta implementato il nostro provider, nelle nostre applicazioni client, dovremmo passare il file Opzioni WriteThru oggetto quando si inseriscono elementi nella cache, come questo,
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// After having NCache up and running... var product = BuildProduct(); var key = $"Product:{product.ProductId}"; var cacheItem = new CacheItem(product); var writeThruOptions = new WriteThruOptions { Mode = WriteMode.WriteThru; } // Add an item with Write-Thru enabled cache.Insert(key, cacheItem, writeThruOptions); |
Read-Through e Write-Through ci aiutano a migliorare la scalabilità e le prestazioni delle nostre applicazioni. Con Read-Through, i nostri elementi memorizzati nella cache sono sempre disponibili da allora NCache può leggere automaticamente gli elementi scaduti. E, con Write-through, la nostra applicazione non deve attendere le scritture del database da allora NCache può aggiornare il nostro database in modo asincrono e, anche con un meccanismo di limitazione, riducendo la pressione sul nostro database.
Conclusione
Questi sono due modelli di memorizzazione nella cache per prestazioni e scalabilità migliori: partizionamento dei dati e strategie di memorizzazione nella cache. Possiamo usare NCache per implementarli nelle nostre applicazioni. Con il partizionamento dei dati, dividiamo le letture e le scritture tra i nodi e aumentiamo la capacità di archiviazione della nostra cache. Abbiamo NCache Topologie di partizione e partizione-replica per questo. E con Read-Through/Write-Through, rendiamo il nostro server cache la fonte dei dati, alleviando un po' la pressione dal nostro database.
Per ulteriori dettagli sul partizionamento dei dati e Read-Through/Write-Through, consulta queste due guide: Topologie partizionate e partizione-replica ed Fornitori di origini dati per cache. Se vuoi beneficiare di questi due modelli di memorizzazione nella cache per ridimensionare le tue applicazioni, dai NCache un tentativo.