DEVintersection 2016

Skalierung von .NET-Anwendungen mit verteiltem Caching

Von Iqbal Khan
Präsident & Technologie-Evangelist

Bei Ihren .NET-Anwendungen können aufgrund der zunehmenden Transaktionslast Datenbank- oder Speicherengpässe auftreten. Erfahren Sie, wie Sie Engpässe beseitigen und Ihre .NET-Anwendungen mithilfe von verteiltem Caching skalieren. Dieser Vortrag umfasst:

  • Schneller Überblick über Skalierbarkeitsengpässe in .NET-Anwendungen
  • Beschreibung des verteilten Caching und wie es Leistungsprobleme löst
  • Wo können Sie verteiltes Caching in Ihren Anwendungen verwenden?
  • Einige wichtige Funktionen in einem verteilten Cache
  • Praktische Beispiele mit einem verteilten Cache

Überblick

Hallo zusammen. Mein Name ist Iqbal Khan. Ich bin Technologie-Evangelist bei Alachisoft. Wir sind ein Softwareunternehmen mit Sitz in der San Francisco Bay Area. NCache ist unser Flaggschiffprodukt, ein verteilter Cache, und das ist heute mein Thema. Mein Thema ist nicht etwa NCache Heute ist es das Caching im Allgemeinen. NosDB ist ein weiteres Produkt, das wir haben, es ist eine Open Source NoSQL database für .NET. Ich werde Azure verwenden, um den verteilten Cache zu demonstrieren, damit Sie sehen können, wie er tatsächlich verwendet wird.

Das heutige Thema ist also die Skalierung von .NET-Anwendungen für verteiltes Caching. Ich bevorzuge interaktivere Diskussionen. Also, während ich rede, wenn Sie eine Frage haben, heben Sie bitte Ihre Hand. Also können wir gleich an dieser Stelle darüber reden, anstatt bis zum Ende zu warten. Ich finde, das macht das Gespräch viel sinnvoller.

Also, lassen Sie mich anfangen. Okay! Also werden wir ein paar Definitionen durchgehen. Ich bin sicher, die meisten von Ihnen wissen das bereits, aber dies dient der Vervollständigung.

Skalierbarkeit

Die erste Definition ist Skalierbarkeit. Skalierbarkeit ist eine hohe Anwendungsleistung unter Lastspitzen. Wenn Sie also beispielsweise eine ASP.NET-Anwendung oder eine beliebige .NET-Anwendung haben, die superschnell arbeitet, mit beispielsweise fünf Benutzern, ist diese nicht unbedingt skalierbar. Wenn es mit fünf Benutzern nicht schnell funktioniert, haben Sie natürlich andere Probleme als dieses. Aber die meisten Anwendungen arbeiten superschnell mit fünf Benutzern, aber wenn Sie auf 5,000 oder 50,000 oder 500,000 Benutzer gehen, fangen die Dinge wirklich an zusammenzubrechen. Wenn Sie also möchten, dass Ihre Anwendung skalierbar ist, muss sie unter Spitzenlasten funktionieren.

Lineare Skalierbarkeit

Lineare Skalierbarkeit bedeutet, dass Ihre Anwendungsarchitektur, Ihre Bereitstellungsstrategie, wenn sie so durchgeführt wird, dass Sie durch das Hinzufügen weiterer Server schrittweise mehr Transaktionen verarbeiten können, als Sie linear skalierbar sind.

Lineare Skalierbarkeit

Das heißt, wenn Sie zwei Server haben und wenn Sie hinzufügen, sagen wir tausend Benutzer mit einem drei Server, sollten Sie 1500 Benutzer oder so ähnlich haben.

Nichtlineare Skalierbarkeit

Wenn Ihre Anwendung jedoch nicht linear skalierbar ist, sieht sie eher wie eine logarithmische Kurve aus, die auf und ab geht, was bedeutet, dass es ab einem bestimmten Punkt nicht mehr wirklich wichtig ist, ob Sie weitere Server hinzufügen.

Nichtlineare Skalierbarkeit

Es wird die Dinge verlangsamen. Wenn Sie mehr Transaktionen haben, können Sie einfach nicht aussteigen. Sie können sich aus diesem Problem nicht freikaufen. Sie wollen also nicht nur Skalierbarkeit, sondern lineare Skalierbarkeit.

Welche Anwendungen benötigen Skalierbarkeit?

Die folgenden Anwendungen sind diejenigen, die normalerweise diese Art von Problemen haben. Dies sind ASP.NET-Webanwendungen, dies sind Webdienste, dies sind Internet-IOT-Back-Ends, die normalerweise auch Webdienste sind. Möglicherweise haben Sie Big Data-Verarbeitung, die in .NET normalerweise nicht so üblich ist, aber Big Data-Verarbeitung ist auch etwas die skaliert werden muss oder andere Serveranwendungen. Sie können ein Finanzinstitut sein, das eine Compliance-Anforderung hat, eine bestimmte Anzahl von Transaktionen zu verarbeiten.

Sie haben also möglicherweise eine Serveranwendung, die eine Compliance-Anforderung hat, sagen wir, wenn Sie eine Banküberweisungsanwendung sind, müssen Sie die Gelder für den nächsten Geschäftstag oder bis zu einer bestimmten Zeit überweisen. Sie müssen also in der Lage sein, immer mehr Transaktionen zu verarbeiten. Wenn Sie also eine dieser Anwendungen haben, dann sind Sie hier genau richtig.

Das Skalierbarkeitsproblem

Lassen Sie uns also das Skalierbarkeitsproblem definieren. Die meisten von Ihnen wissen, dass Ihre Anwendungsarchitekturen heute, wenn Sie eine ASP.NET- oder Webdienstanwendung haben, die Architektur der Anwendungsebene linear skaliert. Sie können also weitere Server hinzufügen, da dies normalerweise kein Problem darstellt. Das Problem liegt wirklich bei Ihrer Datenspeicherung, und wenn ich das Wort Datenspeicherung verwende, meine ich damit relationale Datenbanken und Mainframes. Es gibt Altdaten. Jeder Datenspeicher, den Sie traditionell verwendet haben und der zu einem Engpass wird, und wenn er zu einem Engpass wird, haben Sie dieses Problem. Das NoSQL databases, ich sollte sagen, dass sie nicht immer die Antwort sind. Aber NoSQL Bewegung begann teilweise deswegen. Denn relationale Datenbanken waren nicht so skalierbar NoSQL databases sind skalierbar, aber sie sind nicht in allen Situationen gut, weil sie es erfordern, dass Sie alle Ihre Daten aus Ihrer bestehenden Datenbank in eine verschieben NoSQL database was Sie für viele neue Daten tun können, aber die traditionellen Geschäftsdaten, Ihre Kunden, ihre Konten, all diese Daten müssen sowohl aus geschäftlichen als auch aus technischen Gründen in Beziehung bleiben. Technische Gründe sind natürlich, dass eine relationale Datenbank ein Ökosystem hat, das mit keinem vergleichbar ist NoSQL database und geschäftliche Gründe sind natürlich gleicher Natur.

So, das NoSQL database ist nicht immer die Antwort und obwohl wir haben NoSQL database Produkt, das wir verkaufen, heißt NosDB, das nur als Erweiterung relationaler Datenbanken verwendet wird. Sie können also relationale Datenbanken nicht verlassen. Relationale Datenbanken sind gekommen, um zu bleiben. Sie müssen also mit dieser Realität leben. Sie müssen also die Skalierbarkeit mit relationalen Datenbanken lösen, die immer noch im Bild sind.

Die Skalierbarkeitslösung

Die Lösung besteht natürlich darin, dass Sie einen verteilten In-Memory-Cache verwenden sollten. NCache ist eine solche Lösung. Es ist ein verteilter Open-Source-Cache. Wir sind der älteste verteilte .NET-Cache auf dem Markt. Uns gibt es seit 10 Jahren, eigentlich schon 11. Und wir sind der einzige wirklich native .NET-Cache.

Die meisten von Ihnen haben davon gehört Redis, Rechts? Also, vor mehr als 2 Jahren haben wir noch nie davon gehört Redis weil sie wirklich nicht darauf konzentriert waren. Erst als Microsoft eine Partnerschaft mit ihnen für Azure eingegangen ist.

Verteilte Cache-Bereitstellung

Der Vorteil eines verteilten In-Memory-Cache besteht darin, dass Sie ihn mit Ihren vorhandenen Datenbanken verwenden können. Sie können also das Problem lösen, das Ihnen Ihre relationalen Datenbanken durch einen verteilten In-Memory-Cache bieten. Also, wie lösen Sie dieses Problem? Sie lösen dieses Problem, indem Sie dieses Bild hier sehen.

Verteilte Cache-Bereitstellung
Verteilte Cache-Architektur

Sie haben also eine Anwendungsebene, die aus Ihren Webanwendungen, Ihrem Webdienst und allen anderen Serveranwendungen besteht, und Sie können hier weitere Server hinzufügen. Für Webanwendungen und Webdienste gibt es dort oben normalerweise einen Load Balancer, den ich hier nicht gezeichnet habe. Sie können also auf dieser Ebene weitere Server hinzufügen. Sie können keine weiteren Server auf der Datenbankebene hinzufügen. Ja! Sie können weitere Server in hinzufügen NoSQL Schicht, aber wie gesagt, es ist nicht immer die Antwort. Sie müssen also diese beiden Kästchen lösen. Sie platzieren also einen verteilten In-Memory-Cache zwischen der Anwendungsebene und der Datenbank.

Der verteilte Cache bildet normalerweise einen Cluster. Daher bilden nicht alle verteilten Caches Cluster. Memcached hat nie ein Clustering gebildet, obwohl es sich um einen verteilten Cache handelte. Redis bildet einen Cluster, NCache bildet auf jeden Fall einen Cluster. Ein verteilter Cache bildet hier einen Cluster aus zwei oder mehr Servern. Der Grund, warum ich zwei sage, ist für Redundanzzwecke und für die Replikation und für viele andere und auch für Skalierbarkeitszwecke. Wenn Sie nur einen Cache-Server benötigen, benötigen Sie wahrscheinlich keinen verteilten Cache. Sie sollten hier also mindestens zwei Cache-Server haben, und dieser Cache-Cluster bündelt tatsächlich den Arbeitsspeicher und die CPU-Ressourcen aller Cache-Server in einer logischen Kapazität. Das bedeutet, dass Sie mehr Arbeitsspeicher, mehr CPU-Verarbeitung und mehr Netzwerkkartenkapazität erhalten, wenn Sie weitere Server hinzufügen. Das sind die drei Engpässe für die Skalierbarkeit; Arbeitsspeicher, CPU und Netzwerkkarte. Netzwerkkarten sind heutzutage … ein Gigabit oder zehn Gigabit sind ziemlich Standard. Es ist ziemlich schwierig, das Maximum aus einer Gigabit-Karte oder zehn Gigabit herauszuholen, es sei denn, Ihre Objektgrößen sind groß. Aber wenn Ihre Objektgrößen groß sind, bedeutet groß Hunderte von Kilobyte pro Objekt, dann ist es ziemlich einfach, eine Netzwerkkarte auszulasten, wenn Sie viel Datenverkehr haben. Aber wenn Sie mehr Server haben und das sind natürlich mehr Netzwerkkarten und dann Speicher, ist es genauso.

Der Grund dafür, dass es sich um einen verteilten In-Memory-Cache handelt, liegt darin, dass der Arbeitsspeicher viel schneller ist als die Festplatte, und das ist es, was den Wert wirklich erhöht. Es ist schneller, es ist skalierbarer. Das Ziel hier ist also, etwa 80 % des Anwendungszugriffs zu erfassen, der auf den verteilten Cache geht. Es bleiben also nur 20 % übrig, um in die Datenbank zu gehen.

Viele Leute sahen Caching zunächst als Leistungssteigerung. Ja! Es ist eine Leistungssteigerung, da In-Memory schneller ist. Aber was noch wichtiger ist, es ist ein Bedarf an Skalierbarkeit, da Sie ohne so etwas in Ihrer Infrastruktur nicht skalieren können. Tatsächlich machen es immer mehr Unternehmen mittlerweile fast zum Standard, dass sie neben einer Datenbank in ihrer Anwendungsumgebung auch einen verteilten Cache haben. Einige Leute nennen es In-Memory-Datengrid, das sich auf der Java-Seite befindet, das ist ein Begriff. Manche Leute nennen es ein bisschen Data Fabric, aber verteilter Cache ist der gebräuchlichste Name für das .NET-Ökosystem. Das ist also eine Infrastruktur. Sobald Sie es eingerichtet haben, können Sie es als wirklich mächtiges Werkzeug verwenden. Das Verhältnis zwischen den Anwendungsservern und dem Caching-Tier beträgt normalerweise etwa 4:1, 5:1, wenn man davon ausgeht, dass es sich um ziemlich ausgelastete Server in Bezug auf die Transaktionen handelt. Sie können auch mehr als 5:1 gehen, abhängig von der Art dieser. Und ein typischer Cache-Server hat etwa 16 GB bis 32 GB Speicher und eine Dual-CPU-Quad-Core-Konfiguration. Also keine sehr hochwertige Box. Tatsächlich möchten Sie in dieser Schicht keine sehr hochwertige Box. Sie möchten mehr Boxen als ein paar sehr hochwertige Boxen. Wenn Sie mehr Speicher hinzufügen, können Sie bis zu 128 oder 256 Gig Speicher erreichen, aber mehr Speicher bedeutet, dass Sie eine stärkere CPU benötigen. Warum ist das so? Denn wenn Sie mehr Speicher haben, ist Ihr Heap größer, Ihre Garbage Collection wird eine viel größere Aufgabe und Garbage Collection ist nicht die schnellste Sache in .NET und es wird Ihre CPU auffressen. Sie sehen also immer mehr wie eine Datenbank aus. Es ist also besser, 16 bis 32 GB zu haben, das ist ein ziemlich guter Sweet Spot pro Cache-Server. Irgendwelche Fragen bis jetzt?

NCache Skalierbarkeitszahlen

Hier sind die Skalierbarkeitszahlen von NCache. Unterschiedliche Caches hätten unterschiedliche Nummern, aber das Ziel ist, dies skalierbar zu machen. Die Lesevorgänge skalieren also auf diese Weise, die Schreibvorgänge skalieren dies. Die Lesevorgänge sind langsamer als Schreibvorgänge, da die Replikation mit Lesevorgängen erfolgt. Ich werde über diese Fähigkeiten sprechen.

NCache Skalierbarkeitszahlen

Der Grund, warum Sie Replikation benötigen, ist, dass Speicher flüchtig ist. Wenn also ein Server ausfällt, verlieren Sie diese Daten. Daher möchten Sie diese Daten in vielen Fällen nicht verlieren.

Allgemeine Verwendung von verteiltem Cache

Das Ziel des Vortrags war bisher, Ihnen zu zeigen, warum Sie verteiltes Caching brauchen. Und nachdem wir diesen Fall geklärt haben, wollen wir darüber sprechen, wofür Sie einen verteilten Cache verwenden werden.

App-Daten-Caching

Der häufigste Anwendungsfall ist das, worüber ich gesprochen habe, nämlich das Zwischenspeichern von Anwendungsdaten. Sie speichern die Daten, die in Ihrer Datenbank vorhanden sind, genau hier. Sie cachen also so viel davon wie möglich und verbessern dann Ihre Leistung und Skalierbarkeit.

Das Wichtigste, was beim Caching von Anwendungsdaten zu beachten ist, ist, dass die Daten an zwei Stellen vorhanden sind. Einer in der Datenbank, einer im Cache. Wann immer das passiert, was ist die erste Sorge, die Ihnen in den Sinn kommt, was schief gehen könnte, wenn es an zwei Orten existieren würde? Ja, Konsistenz!

Daher ist es wirklich wichtig, dass ein guter verteilter Cache damit umgeht. Denn wenn ein Cache nicht in der Lage ist, die Tatsache zu bewältigen, dass Daten an beiden Stellen konsistent sein müssen, sind Sie gezwungen, mehr schreibgeschützte Daten zwischenzuspeichern. Schreibgeschützte Daten machen etwa 10 % bis 15 % oder 20 % der Daten aus. Die Mehrheit der Daten sind das, was ich als Transaktionsdaten bezeichne. Das sind Ihre Kunden, Ihre Konten. Das sind Daten, die sich ändern. Sie kann sich alle paar Sekunden ändern, obwohl sie sich meistens alle zwei Minuten ändert. Selbst wenn Sie es also eine Minute oder 30 Sekunden zwischenspeichern könnten, würden Sie immer noch davon profitieren, dass Sie es mehrmals lesen würden, und wenn Sie das mit der Gesamtzahl der Transaktionen multiplizieren, die an einem bestimmten Tag stattfinden, haben Sie Millionen von Transaktionen die nicht mehr in die Datenbank gehen. Daher ist es wirklich wichtig, dass ein guter verteilter Cache für das Caching von Anwendungsdaten diese Konsistenz handhaben muss, und ich werde auf die Funktionen eingehen, die für diese Konsistenz wirklich wichtig sind. Beim Zwischenspeichern von Anwendungsdaten werden also permanente Daten zwischengespeichert. Permanente Daten bedeutet, dass diese dauerhaft in Ihrer Datenbank vorhanden sind.

ASP.NET-spezifisches Caching

Der zweite Anwendungsfall ist, wenn Sie eine ASP.NET-Anwendung haben, gilt dies natürlich auch für andere Webanwendungen, aber ich konzentriere mich auf .NET. Sie können Ihren Sitzungsstatus und Ihren Ansichtsstatus zwischenspeichern, wenn Sie das MVC-Framework nicht verwenden, und Sie können Ihre Ausgabe, die Seitenausgabe, zwischenspeichern. All diese Daten sind temporärer Natur. Es ist nicht dauerhaft. Alle Daten, die nicht dauerhaft sind, sollten nicht wirklich in der Datenbank vorhanden sein. Es sind vorübergehende Daten.

Wenn Daten vorübergehend sind, wenn sie temporär sind und nicht in der Datenbank, sondern nur im Cache vorhanden sind, was ist die größte Sorge, die Ihnen in den Sinn kommt, was schief gehen könnte? Beharrlichkeit … oder Mangel daran. Wenn Sie also nicht darauf bestehen, verlieren Sie Daten. Was ist, wenn dieser Cache-Server ausfällt und Sie diesen Einkaufskorb oder was auch immer haben und sagen wir, Sie sind eine Fluggesellschaft und dieser Kunde von Ihnen hat gerade diese Flugsuche durchgeführt und er kauft 10 Tickets oder vier Tickets im Wert von mindestens 5,000 $ und die letzte Seite sagen sie absenden oder was auch immer die letzte Seite und plötzlich ist die Sitzung weg, weil der Cache-Server ausgefallen ist und sie wieder von vorne anfangen müssen. Die gesamte Aktivität geht verloren. Sie könnten diesen Kunden verlieren. Keine sehr gute Erfahrung.

Alles, was Sie zwischenspeichern und vorübergehend sind, muss der Cache replizieren. Jeder Cache, der keine Replikation durchführt, ist kein brauchbarer Cache. Und die Replikation ist mit Kosten verbunden, daher muss der Cache eine effektive und effiziente Replikation durchführen. Der Sitzungsstatus ist ein sehr häufiger Anwendungsfall für einen verteilten Cache, da Sitzungen in ASP.NET sehr häufig vorkommen.

Laufzeitdatenfreigabe durch Ereignisse

Der dritte übliche oder der dritte Anwendungsfall, der eigentlich nicht sehr bekannt ist, wird als Runtime Data Sharing bezeichnet. Dies ist der Fall, wenn Sie mehrere Anwendungen haben, die gemeinsam genutzt werden müssen. Eine Anwendung produziert etwas oder aktualisiert etwas, das eine andere Anwendung oder die andere Instanz dieser Anwendung verwenden muss. Normalerweise würden Sie dafür traditionell Nachrichtenwarteschlangen verwenden oder Sie würden diese Daten einfach in die Datenbank stellen und die andere Anwendung wird sie abrufen. Aber ein verteilter Cache ist für diesen Anwendungsfall sehr gut. Es ist nicht dazu da, Nachrichtenwarteschlangen zu ersetzen. Nachrichtenwarteschlangen haben ihre andere Verwendung, aber wenn Ihre Anwendung im selben Rechenzentrum ausgeführt wird, müssen alle Instanzen Daten gemeinsam nutzen, dann ist dies eine viel skalierbarere Daten- oder Datenfreigabeplattform, da alle Anwendungen mit derselben Plattform verbunden sind und dies Plattform kann in einem Pub/Sub-Modell Ereignisse auslösen. Pub bedeutet, dass eine Anwendung der Herausgeber ist, sie veröffentlichen etwas und sie lösen ein Ereignis aus. Alle Abonnenten davon werden benachrichtigt und sie werden diese Daten verbrauchen.

Es gibt auch andere Arten von Benachrichtigungen. Wenn bestimmte Artikel geändert werden, kann Ihre Anwendung Interesse an bestimmten Artikeln zeigen, und wenn sich dieser Artikel ändert, benachrichtigen Sie mich. Oder es gibt eine kontinuierliche Abfrage kennzeichnen Sie das NCache hat, was wie a ist SQL-Abhängigkeit Funktion in SQL Server, wo NCache ermöglicht es Ihnen, eine SQL-Abfrage zu sagen, die besagt WÄHLT Kunden AUS, WO Customers.City = "New York". Wenn also ein Kunde mit diesen Kriterien jemals den Cache hinzugefügt, aktualisiert oder aus dem Cache entfernt hat, benachrichtigt.

Es ist also eine viel intelligentere Art, Änderungen am Cache zu überwachen. All diese Dinge ermöglichen es Ihnen also, Daten zwischen Anwendungen auf sehr schnelle und skalierbare Weise zur Laufzeit auszutauschen. Und dies sind auch vorübergehende Daten, obwohl viele dieser Daten in der Datenbank vorhanden sind, die Form, in der Sie sie freigeben, jedoch wahrscheinlich nicht. Es ist also vorübergehend. Das muss also auch nachgeahmt werden. Haben Sie bis jetzt noch Fragen? Entweder ihr kennt das Zeug schon komplett oder ich bin super gut.

Übersicht über das Zwischenspeichern von App-Daten

Sehen wir uns also den Quellcode an, wie … welche Funktionen Sie verwenden sollten und wie Sie sie verwenden. Ich werde verwenden NCache wie das Beispiel, aber wie gesagt, mein Fokus liegt mehr auf den eigentlichen Funktionen.

Hier ist eine typische Art und Weise, wie Sie einen Cache verwenden würden.

Customer Load(string customerId)
{
    // Key format: Customer:PK:1000
    string key = "Customers:CustomerID:" + customerId;
    
    Customer cust = (Customer) _cache[key];
    
    if (cust == null)
    {
        // Item not in cache so load from db
        LoadCustomerFromDb(cust);
        // Add item to cache for future reference
        _cache. Insert(key, cust);
    }
    return cust;
}

Sie würden einen Kunden aus einer Datenbank laden. Bevor Sie zur Datenbank gehen, überprüfen Sie den Cache und verwenden den Schlüssel, einen zeichenfolgenbasierten Schlüssel. Sagen wir mal Kunden: Kunden-ID und die tatsächliche Kunden-ID ist möglicherweise 1000 oder so und Sie sagen, überprüfen Sie den Cache. Wenn Sie es im Cache haben, brauchen Sie nicht zur Datenbank zu gehen, Sie haben es. Wenn Sie ihn nicht im Cache haben, gehen Sie zur Datenbank, laden diesen Kunden und legen ihn in den Cache. Wenn du es in den Cache legst, wirst du es beim nächsten Mal, wenn du oder jemand anderes kommt, im Cache finden. Das ist also ein sehr einfaches Paradigma. Sobald Sie dies tun, findet jeder Dinge, die mehr wert sind als der Cache.

Natürlich gibt es viele andere Funktionen, mit denen Sie den Cache mit vielen Daten vorbelegen können, von denen Sie glauben, dass sie sowieso benötigt werden. So sparen Sie viele Datenbankzugriffe im Voraus und fügen dann immer noch inkrementell Daten zum Cache hinzu, die nicht im Cache gefunden werden. Hier ist zum Beispiel ein Visual Studio-Projekt. Wenn Sie verwenden würden NCache Sie würden zwei dieser Assemblys verknüpfen. Einer ist NCache.Laufzeit und einer ist NCache.Netz. Sie werden hier zwei der Namespaces ähnlich verwenden NCache.Laufzeit und NCache.Web.Caching. Wir haben unsere Namespaces so benannt, dass sie dem ASP.NET-Cache ziemlich nahe kommen. Damit Sie wissen, wann NCache kam heraus, dass der ASP.NET-Cache der einzige verfügbare Cache war. Also, Sie haben dies und am Anfang Ihrer Anwendung ist dies natürlich eine Konsolenanwendung, Ihre wird eine andere sein. Sie stellen eine Verbindung zum Cache her und erhalten ein Cache-Handle. Jeder Cache hat einen Namen und Sie haben einen Cache-Handle, und dann fügen Sie Ihre Objekte dem Cache hinzu. Nehmen wir also an, Sie haben gerade hinzugefügt, Sie tun es cache.Hinzufügen hier. Sie geben Ihren Schlüssel an. Obwohl dies wahrscheinlich nicht David Jones sein sollte, sollte es eine Art Kunden-ID sein, und dann haben Sie das eigentliche Objekt und dann haben Sie Ablaufzeiten angegeben. Und Sie geben die absoluten Ablaufzeiten von einer Minute an. Sie sagen, dass dieses Element nach einer Minute aus dem Cache abläuft. Alles andere hast du einfach auf Default gehalten. Und später können Sie tun Cache.Get und erhalten Sie denselben Kunden von einem anderen Ort. Also nur einfache Cache-Operationen.

using System;
using Alachisoft.NCache.Runtime;
using Alachisoft.NCache.Web.Caching;
using Alachisoft.NCache.sample.data;

namespace BasicOperations
{
    public class BasicOperations
    {
        public static void Main(string[] args)
        {
            try
            {
            //Initialize cache via 'initializeCache' using 'Cache Name'
            //to be initialized. 
            Cache cache = NCache.InitializeCache("demoCache");
            cache.Clear();

            //Another method to add item(s) to cache is via CacheItem  object
            Customer customer = new Customer();
            customer.Name = "David Johnes";
            customer.Age = 23;
            customer.Gender = "Male";
            customer.ContactNo = "12345-6789";
            customer.Address = "Silicon Valley, Santa Clara, California";

            DateTime calendar = new DateTime();
            calendar.AddMinutes(1);

            //Adding item with an absolute expiration of 1 minute
            cache.Add("Customer:DavidJohnes", customer, calendar, Cache.NoSlidingExpiration, CacheItemPriority.Normal);
            Customer cachedCustomer = (Customer) cache.Get("Customer:DavidJohnes");
            ...

Hands-on-Demo

Im Falle von NCache, alle Caches sind benannt. Ich werde Ihnen jetzt schnell zeigen, wie ein Cache aussieht, und dann kommen wir auf den Code zurück. Ich habe eine Reihe von VMs in Azure eingerichtet. Du kannst also laufen NCache in Azure, in Amazon, eine lokale. In allen Fällen sind die Cache-Server selbst nur VMs. Dies sind nur Windows 2008, 2012-VMs. Der Cache-Client in Azure kann entweder eine VM, eine Webrolle, eine Workerrolle oder eine Website sein.

Demo-Cache Azure

Erstellen Sie einen geclusterten Cache

Ich habe mich hier beim Demo-Client angemeldet. Ich gehe jetzt schnell los und erstelle einen Cache. So kann ich zeigen, wie der Cache aussieht. Verwenden Sie dieses Tool namens the NCache Manager, grafisches Tool und lässt Sie … Ich werde hierher kommen und sagen, dass es einen „neuen Clustered Cache“ erstellt.

Erstellen Sie einen geclusterten Cache

Alle Caches drin NCache sind benannt. Also werde ich nur meinen Cache benennen. Alles andere nehme ich zu diesem Zeitpunkt als Standard.

Geben Sie den Cache-Namen an

Ich wähle eine Topologie für das partitionierte Replikat aus. Ich werde am Ende dieses Vortrags schnell darauf eingehen. Partitioniertes Replikat ist meine Topologie.

Caching-Topologie

Ich verwende die asynchrone Replikation.

Replikationsstrategie

Ich wähle meinen ersten Cache-Server, nämlich demo2. Das sind also zwei meiner Cache-Knoten.

Hinzufügen von Cache-Knoten

Ich drücke auf Weiter. Ich nehme alle Standardeinstellungen. Ich gebe an, wie viel Speicher ich diesem Cache zuweisen möchte. Auf diese Weise verbraucht der Cache also nicht mehr Speicher als hier angegeben. Ich habe gerade einen Gig gegeben, aber deiner wird natürlich viel größer sein. Das ist die Größe einer Partition.

Speichergröße

Sobald der Cache also so viel Speicher verwendet, ist der Cache voll. Entweder werden neue Elemente abgelehnt oder einige der vorhandenen Elemente werden entfernt. Also, ich werde sagen, 5% des Caches dafür entfernen, und ich werde sagen, am wenigsten kürzlich verwenden ist der zu verwendende Algorithmus, und ich habe gerade den Cache erstellt.

Ich werde fortfahren und einen Kunden hinzufügen.

Client-Knoten hinzufügen

Also, ich habe gerade einen Cache erstellt und wir werden den Cache starten.

Starten Sie den Cache

Stress simulieren und Cache-Statistiken überwachen

Ich werde die Statistiken auswählen, damit ich einige PerfMon-Statistiken verwenden kann. Ich werde auch den Cluster überwachen. Also, ich habe gerade den Cache gestartet. Dieser Cache wird als Demo-Cache bezeichnet. Ich werde es einfach schnell testen. Also habe ich gerade ein Stresstest-Tool ausgeführt, das mitgeliefert wird NCache und lässt Sie den Cache schnell in Ihrer eigenen Umgebung testen.

Stresstest-Tool

Dieser Cache funktioniert also jetzt. Was also passiert ist, auf der Client-Box, und der Client meint ihre Anwendungsserver-Box. Ich habe eine Konfigurationsdatei, genau hier. Also habe ich gerade einen Cache erstellt und er weiß jetzt, was die Cache-Server sind. Lassen Sie mich nun auf den Code zurückkommen. Also, als ich diesen Cache-Namen tatsächlich ausgewählt habe, ist das passiert, meine Anwendung hat sich jetzt mit allen Cache-Servern im Cluster verbunden und mir ein Cache-Handle gegeben, sodass, wenn ich a cache.Hinzufügen, es wird es tatsächlich an der richtigen Stelle im Cache hinzufügen und auch die Replikation für mich erledigen, all das ist erledigt.

Die API verbirgt also all diese Details, aber ich wollte Ihnen zeigen, wie dieser Cache hinter den Kulissen aussieht und wie einfach es ist, ihn zu verwenden NCache in dieser Situation. Kommen wir also zurück zu unserer Hauptsache. So würde die API aussehen.

  • Cache-Verbindung
    ICache cache = CacheManager.GetCache(“myDistributedCache”);
    cache.Dispose();
  • Abrufen von Daten
    Employee employee = cache.Get<Employee>("Employee:1000"); 
    bool isPresent = cache.Contains("Employee:1000");
  • Schreiben von Daten
    cache.Add("Employee:1000", employee);
    cache.AddAsync("Employee:1000", employee);
    
    cache.Insert("Employee:1000", employee);
    cache.InsertAsync("Employee:1000", employee);
    
    Employee employee = (Employee) cache.Remove("Employee:1000");
    cache.RemoveAsync("Employee:1000");

Du tust ein Cache.Get, Cache.Contains, Cache.Add, Einfügen, Entfernen. Einfügen bedeutet hinzufügen, wenn es nicht vorhanden ist, andernfalls aktualisieren.

App-Daten-Caching-Funktionen

OK, jetzt, wo wir eine Vorstellung davon haben, wie ein Cache aussieht, was ist eine einfache API. Kommen wir zu dem Feature, über das wir gesprochen haben. Welche für einen verteilten Cache wichtig sind.

Halten Sie den Cache frisch

Das erste, was wir gesagt hatten, war, dass ein verteilter Cache die Daten aktuell halten muss, den Cache aktuell. Es gibt also vier Möglichkeiten, wie es das tun kann. Nummer eins ist Ablauf, die viele Caches haben, fast jeder Cache ermöglicht es Ihnen, Dinge ablaufen zu lassen.

Es gibt also eine Absoluter Ablauf und es gibt eine Gleitender Ablauf. Absolute Expiration ist das, was ich Ihnen gerade gezeigt habe, was bedeutet, dass dieser Gegenstand in fünf Minuten abläuft, unabhängig davon, was passiert. Und der Grund, warum ich das sage, ist, weil, wie gesagt, diese Daten in der Datenbank existieren und ich ihnen nur fünf Minuten lang vertrauen kann, dass sie sich nicht in der Datenbank ändern werden. Ich möchte es nicht länger im Cache behalten, da es sich in der Datenbank ändern könnte. Sie machen also eine Vermutung über die Art der Daten. Einige Daten können Sie stunden- und tagelang zwischenspeichern. Wissen Sie, das können Ihre Nachschlagetabellen sein. Vielleicht ändern sich Ihre Preise einmal am Tag oder so. Sie können dies also 24 Stunden lang zwischenspeichern.

Andere Daten sind Ihre Transaktionsdaten. Sie können es nur für vielleicht 30 Sekunden oder eine Minute zwischenspeichern, weil das so lange ist, wie Sie sich wohl fühlen. Der absolute Ablauf gilt also für dauerhafte Daten und ist eine Möglichkeit, abzuschätzen oder zu erraten, wie lange es sicher ist, die Daten im Cache aufzubewahren. Es ist sehr wichtig. Ich möchte eine Unterscheidung zwischen den absoluten Verläufen und dem Gleiten treffen.

Das gleitende Ablaufdatum besagt im Grunde, dass dieses Element für dieses Intervall aus dem Cache entfernt wird, wenn es niemand mehr berührt. Berühren bedeutet Abrufen oder Aktualisieren. Also zum Beispiel ein Sitzungszustand. Wenn Sie sich abmelden, wird ein Sitzungsstatus von niemandem mehr berührt. Also muss es nach etwa 20 Minuten aus dem Cache entfernt werden.

Gleitender Ablauf wird normalerweise für transiente Daten verwendet. Es ist eher eine Aufräumaktion. Es hat nichts mit der Aktualisierung der Daten zu tun. Es hat damit zu tun, dass Sie es einfach loswerden, weil Sie es nicht mehr brauchen. Aber absolutes Ablaufdatum ist das, was Sie brauchen, um die Daten aktuell zu halten. Zweitens, wissen Sie, Ablauf ist eine sehr wichtige Sache. Jeder Cache muss es haben und die meisten haben es, ich denke eigentlich alle, zumindest absolutes Verfallsdatum.

Synchronisieren Sie den Cache mit der Datenbank

Das zweite Merkmal ist etwas, das die meisten von ihnen nicht tun. Und hier möchten Sie den Cache mit der Datenbank synchronisieren.

Verwenden von Datenbankabhängigkeiten

Sie sagen, wissen Sie, ich kann wirklich nicht vorhersagen, wie oft oder wann dies in der Datenbank aktualisiert wird. Ich weiß nicht, wann die Daten in der Datenbank aktualisiert werden. Weil ich mehrere Anwendungen habe, die es aktualisieren. Möglicherweise berühren andere Personen die Daten direkt. Ich möchte also nur, dass der Cache die Datenbank überwacht. Also, und der Cache sollte sich dieser Änderung in der Datenbank bewusst sein. Dies ist eine Funktion, die NCache verfügt über. Es heißt SQL-Abhängigkeit. Tatsächlich verwendet es eine SQL-Server-Funktion namens SQL-Abhängigkeit, wo NCache wird Client der Datenbank.

Lassen Sie mich Ihnen schnell zeigen, wie das aussieht. Also, wenn ich hier einen Cache habe. Also noch einmal, genauso wie wir es mit den Bibliotheken gemacht haben, und dann verbinden Sie sich mit dem Cache. Jetzt, wenn Sie das Element zum Cache hinzufügen, genau hier. Wenn ich hierher komme und dann sage ich 'AddProductToCacheWithDependency', weiter zur Definition. Also, hier sagen Sie zu diesem Cache, hier ist meine SQL-Anweisung.

private static void AddProductToCacheWithDependency (Product product)
{
// Any change to the resulset of the query will cause cache to invalidate the dependent data
string queryText = String.Format("SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice FROM dbo.PRODUCTS WHERE PRODUCTID = {0}", product.ProductID);

//Let's create SQL depdenency
CacheDependency sqlserverDependency = new SqlCacheDependency(connectionString, queryText);

CacheItem cacheItem = new CacheItem(product);
cacheItem.Dependency = sqlserverDependency;

//Inserting Loaded product into cache with key: [item:1]
string cacheKey = GenerateCacheKey(product);
cache.Add(cacheKey, cacheItem);
}

private static string GenerateCacheKey (Product product)
{
string cacheKey = "Product#" + product.productID;
return cachekey;
}

Ihre SQL-Anweisung spiegelt also normalerweise diese eine Zeile in der Tabelle wider. Wenn Sie also ein Produkt hinzufügen, sollte die SQL-Anweisung mit der Produkt-ID dieser entsprechen. Sie erstellen also diese SQL-Anweisung für SQL Server. Denn dies übergeben Sie als Teil der SQL-Abhängigkeit an SQL Server. Sie werden es weitergeben NCache. Sie übergeben dies also an die Client-Box NCache. Sie geben dies also als Ihre SQL-Anweisung an. Sie erstellen ein „Cache-Element“-Objekt und geben innerhalb des Cache-Elements die „SQLServer-Abhängigkeit“ an. So, SQLCacheDependency ist eine Klasse von NCache, eigentlich. Dies ist nicht dasselbe wie die SQL-Server-Abhängigkeit. Dieser hat bis auf die SQL-Cache-Abhängigkeit den gleichen Namen. Dadurch bleibt diese SQL-Anweisung erhalten, Sie geben dies an und fügen das Element dem Cache hinzu. Sie haben dies also getan und sitzen jetzt auf dieser Kiste, genau hier.

Verteilter Cache

Also gibst du das weiter an NCache. Es geht zu einem der Cache-Server. Dieser Cache-Server wird nun zum Client der Datenbank. Denn Sie haben auch Informationen zur Verbindungszeichenfolge angegeben. Irgendwo hier geben Sie die Verbindungszeichenfolge an. So, NCache Server wird ein Client Ihrer Datenbank. Nun könnte diese Datenbank ein SQL-Server sein, das könnte Oracle sein und NCache baut eine SQL-Abhängigkeitsverbindung auf. SQL Server erstellt eine Datenstruktur innerhalb von SQL Server, die den Datensatz überwacht.

Also, genau wie NCache hatte diese kontinuierliche Abfragefunktion, über die ich für die gemeinsame Nutzung von Laufzeitdaten gesprochen habe, wo NCache überwachte alle Kunden, wobei Customer. Stadt = „New York“. Jetzt überwacht der SQL-Server dieses Dataset innerhalb des SQL-Servers, und wenn eine Zeile, die diesen Kriterien entspricht, entweder hinzugefügt, aktualisiert oder aus der SQL-Datenbank entfernt wird, benachrichtigt der SQL-Server den Cache-Server. Der Cache-Server weiß nun, dass sich diese Daten in der Datenbank geändert haben. Es hat also zwei Möglichkeiten. Es kann das entweder aus dem Cache entfernen, was das Standardverhalten ist, oder es kann eine neue Kopie neu laden.

Read-Through/Write-Through verwenden

Die Art und Weise, wie eine neue Kopie neu geladen wird, ist, wenn Sie ein anderes Future of verwenden NCache namens durchlesen. Ich werde das überspringen und muss darauf zurückkommen. Es gibt also eine Funktion namens Durchlesen, die Ihr Code ist. Sie implementieren einen Read-Through-Handler und ich zeige Ihnen den Read-Through-Handler. Also, hier ist ein IReadThroughBereitgestellt.

{
    // <summary>
    // Contains methods used to read an object by its key from the master data source.
    // </summary>

    public class SqlReadThruProvider : Alachisoft.Ncache.Runtime.DatasourceProviders. IReadThruProvider
    {
        private SqlDatasource sqlDatasource;
        // <summary>
        // Responsible for loading the object from the external data source.
        // Key is passed as parameter.
        // <param name="key">item identifier; probably a primary key</param>
        // <param name="exh">Current expiration hint; you can modify the value and attach a new hint</param>
        // <param name="evh">Current eviction hint; you can modify the value and attach a new hint</param>
        // <returns></returns

        public void LoadFromSource(string key, out ProviderCacheItem cacheItem)
        {
            cacheItem = new ProviderCacheItem(sqlDatasource.LoadCustomer(key));
            cacheItem.ResyncItemonExpiration = true;
            cacheItem.ResyncProviderName = sqlDatasource.ConnString;
        }
        // <summary>
        // Perform tasks like allocating resources or acquiring connections
        // </summary>
        ...

Sie setzen dies um. Es hat eine Init-Methode, die es initialisiert. Eine Dispose-Methode und eigentlich wie eine Get-Methode. Das Get gibt Ihnen also den Schlüssel und Sie geben ihm das Cache-Element zurück. Sie gehen also zu Ihrer Datenquelle und laden dieses Element, geben das Ablaufdatum oder irgendetwas anderes an und leiten es an zurück NCache. Dieser Code von Ihnen läuft auf dem Cache-Server. Dies ist eine wichtige Sache, die Sie im Auge behalten sollten.

Das Durchlesen läuft also tatsächlich auf dem Cache-Server selbst. Eigentlich habe ich ein anderes Diagramm.

Read-Thru-Cache-Loader

Das Durchlesen läuft also auf dem Cache-Server selbst. Der Cache-Server muss also in .NET entwickelt werden, damit Ihr .NET-Code darauf ausgeführt werden kann, richtig? Also, wenn Ihr .NET-Shop, wenn Ihre Anwendung in .NET ist, der Grund, warum ich gesagt habe, dass Ihr gesamter Stack wegen all dieser Vorteile .NET sein sollte.

Also, kommen Sie zum Beispiel Redis, Redis ist ein Linux-basierter Cache. Es ist also ein großartiger Cache, ich habe nichts dagegen, aber wenn Sie ein .NET-Shop sind, müssen Sie all diese Dinge tun, und Ihr Code muss auf dem Cache-Server ausgeführt werden, damit sich der Cache mit ihm synchronisieren kann die Datenbank und laden Sie dieses Element automatisch aus der Datenbank neu. Ihr Read-Through-Handler wird also aufgerufen, wenn eine SQL-Abhängigkeit ausgelöst wird, wenn Sie dies so wünschen. Wenn Sie das nicht möchten, wird dieses Element einfach aus dem Cache entfernt. Und wenn es dann aus dem Cache entfernt wird, wird es das nächste Mal, wenn Ihre Anwendung danach sucht, es nicht finden und wird es aus der Datenbank holen. In bestimmten Fällen handelt es sich beispielsweise um einen Produktkatalog, den Sie zwischengespeichert haben, und Sie haben gerade den Preis aktualisiert. Warum das Produkt aus dem Cache entfernen, Sie haben gerade den Preis aktualisiert? Denn jetzt muss die Anwendung über die Logik verfügen, um sie aus der Datenbank abzurufen. Es ist besser, automatisch neu zu laden.

Wenn Sie also glauben, dass viele Daten immer wieder benötigt werden, entweder wenn sie ablaufen oder wenn die Datenbanksynchronisierung stattfindet, ist es besser, sie neu zu laden, als sie zu entfernen. Denn dann muss die Anwendung dies nicht tun. Je mehr davon der Cache leistet, desto einfacher wird die Anwendung. Also eine andere Möglichkeit, wie sich der Cache mit der Datenbank synchronisieren kann. Wenn Sie also keinen SQL-Server oder Oracle haben, sagen wir, Sie haben MySQL oder DB2, dann können Sie diese beiden vorhandenen Funktionen verwenden, dann können Sie die DB-Abhängigkeit verwenden, die eine weitere Funktion von ist NCache dass wo NCache Pools einer bestimmten Tabelle und Sie ändern Ihre Datenbank-Trigger, um das Flag in dieser Zeile zu aktualisieren. NCache hebt es auf und sagt, dieser Artikel hat Wechselgeld. Sie müssen es also entfernen oder neu laden.

Verwenden von gespeicherten CLR-Prozeduren

CLR-Prozeduren sind eine weitere Möglichkeit, den Cache mit der Datenbank zu synchronisieren. Wo schreibt man eigentlich a CLR-Verfahren. Sie rufen es von Ihrem Tabellenauslöser auf. Nehmen wir also an, Sie haben einen Add- oder Update-Trigger oder einen Delete-Trigger. Sie rufen diese CLR-Prozedur auf, sie ruft auf NCache oder es ruft den Cache auf.

Im Falle des CLR-Verfahrens müssen Sie sicherstellen, dass der Cache asynchrone Methoden unterstützt, die NCache tut. Sie können also in einem Cache wie einen Insert-Async-Aufruf tätigen und die Kontrolle kommt sofort zu Ihnen zurück. Denn wenn Sie den asynchronen Aufruf nicht durchführen, beginnen Ihre Datenbanktransaktionen mit einer Zeitüberschreitung. Da Sie mehrere Server im Cache aktualisieren, gehen Sie über das Netzwerk, wofür eine Datenbanktransaktion nicht vorgesehen ist. Sie müssen also einen asynchronen Anruf haben.

Das sind also die drei Möglichkeiten, wie Sie den Cache synchronisieren können. Also, jeder Cache, den Sie bezahlt haben, müssen Sie sicherstellen, dass Sie die Daten aktuell halten können. Dies sind die beiden Wege.

Synchronisieren Sie den Cache mit dem nicht-relationalen

Genauso, wenn Sie eine nicht relationale Datenquelle haben, sagen wir, Sie haben Ihre Daten in der Cloud oder an einem anderen Ort. Sie können sogar einen Webmethodenaufruf durchführen. Sie können tatsächlich eine benutzerdefinierte Abhängigkeit implementieren, die wiederum Ihr Code ist, der sich auf den Cache-Servern registriert und dort ausgeführt wird NCache ruft es auf und sagt, bitte gehen Sie und überprüfen Sie Ihre Datenquelle, ob sie sich geändert hat oder nicht. Sie überprüfen die Datenquelle, wenn sie sich geändert hat, benachrichtigen Sie sie NCache dass sich diese Daten und die Datenquelle geändert haben. So, NCache kann es entweder entfernen oder neu laden.

Also wieder mit einer relationalen Datenbank NCache tut alles für dich. Im Falle von nicht relational müssen Sie eine benutzerdefinierte Abhängigkeit erstellen.

Umgang mit relationalen Daten

Der letzte Aspekt, um ihren Cache frisch zu halten, sind die Abhängigkeitsfunktionen. Angenommen, Sie haben eine Eins-zu-Viele-Beziehung zwischen einem Kunden und einer Bestellung und Sie speichern beide zwischen. Was ist, wenn das Kundenobjekt aus dem Cache entfernt wird? Sollen die Bestellungen im Cache bleiben oder nicht? Was wäre, wenn Sie den Kunden tatsächlich aus der Datenbank gelöscht hätten? Nun, normalerweise löscht man die Kunden nicht, wenn ich Eins-zu-Viele sage. Nehmen wir an, was wäre, wenn die eine Seite, die Sie aus dem Cache entfernen, wirklich bedeutet, dass Sie sie möglicherweise auch aus der Datenbank entfernt haben. Das bedeutet, dass die viele Seite nicht mehr gültig ist. Also, wer soll das alles im Auge behalten? Wenn der Cache das für dich tun kann, dann macht es dein Leben viel einfacher.

Beispielsweise hat das ASP.NET-Cacheobjekt diese Funktion aufgerufen Cache-Abhängigkeit. NCache hat es implementiert und soweit ich weiß, hat kein anderer .NET-Cache diese Funktion. Aber im Grunde registrieren Sie die Beziehung zwischen Elementen und sagen, dass dies von diesem Element abhängt. Wenn dieses Element jemals aktualisiert oder entfernt wird, entfernen Sie dieses Element bitte automatisch. Der Cache erledigt also die Bereinigung für Sie.

Je mehr davon der Cache für Sie erledigt, desto besser für Sie, da Sie sicher sein können, dass Ihre Daten aktuell sind. Sobald Sie dieses Vertrauen haben, können Sie so ziemlich alle Daten zwischenspeichern. Es ist nur eine Frage der Strategie, mit der Sie die Daten aktuell halten.

Daten suchen

Jetzt, da Sie sicher sein können, dass die Daten aktuell sind, werden Sie damit beginnen, viele Daten zwischenzuspeichern. Nun, sobald Sie anfangen, alle Daten zwischenzuspeichern, ist das nächste, was kommt, dass der Cache nun anfängt, mehr und mehr wie eine Datenbank auszusehen. Es ist keine Datenbank, es ist immer ein temporärer Speicher. Aber besonders bei vielen dieser Referenzdaten speichern Sie so ziemlich den gesamten Datensatz im Cache. Wenn das passiert, möchten Sie in der Lage sein, danach zu suchen. Anstatt es immer nur anhand von Schlüsseln zu finden, ist das sehr umständlich. Es ist nicht immer bequem, einen Gegenstand anhand des Schlüssels zu finden. Sie möchten in der Lage sein, das mit anderen Mitteln zu suchen.

Eine Möglichkeit ist, eine zu machen SQL-Suche. Nochmal, SELECT Kunden WHERE Kunden.Stadt = "New York". Genau wie Sie es tun würden oder sagen würden, geben Sie mir alle meine Produkte dieser Kategorie. Sie erhalten also eine Sammlung dieser Objekte aus dem Cache zurück, nicht aus der Datenbank. Aus dem Cache zu kommen bedeutet natürlich, dass die Datenbank diesen Treffer nicht mehr hinnehmen muss und sich alles im Speicher befindet. Es ist viel schneller, wenn es von mehreren Servern gleichzeitig kommt.

All dies sind also parallele Abfragen. Und damit Sie dies tun können, muss der Cache die Indizierung unterstützen, was NCache tut. Ich bin mir nicht sicher, ob andere Produkte dies tun oder nicht, aber stellen Sie sicher, dass der Cache die Indizierung unterstützt. Andernfalls werden es wirklich sehr langsame Abfragen sein.

Datengruppierung

Eine Sache, die Sie in einem Cache nicht tun können, ist das Verbinden mehrerer Objekte oder mehrerer Tabellen, was Sie in einer relationalen Datenbank tun können. Es gibt also Möglichkeiten, dies zu umgehen, nämlich dass Sie Dinge gruppieren können, Sie können sie auf bestimmte Weise markieren, damit Sie sie zurückbekommen, und auf diese Weise können Sie Daten basierend auf einigen logischen Zuordnungen oder Gruppierungen abrufen, die sich im Cache befinden. Nehmen wir also an, wenn Sie alles zwischenspeichern, gebe ich Ihnen ein Beispiel. Nehmen wir zum Beispiel an, Sie haben eine Sammlung von Kunden zurück. Ich habe also eine Sammlung von Objekt-Tags und möchte jedes Objekt separat im Cache zwischenspeichern. Aber später möchte ich in der Lage sein, alles in einem Anruf abzurufen.

//Caching Query Results (Collection)
//Cache Collection Objects Separately
static void CacheSupplierProducts(NorthwindEntities context, int supplierId)
{
    Tag[] productTags = new Tag[1];
    productTags[0] = new Tag("SupplierProducts:" + supplierId);
    
    IQueryable<Product> products = context.Products;
    
    var result = from product in products
                  where product.SupplierID == supplierId
                  select product;
                  
    foreach (Product p in result)
    {
        String key = "Products:ProductId:" + p.ProductID;
        _cache.Insert(key, p, productTags);
    }
}
...
ICollection productList = _cache.GetByAnyTag(productTags).Values;

Also, entweder ich gebe dieselbe Abfrage, eine SQL-Abfrage, und ich sage, gib mir alle Dinge zurück. Aber ich habe diese Objekte aus der Datenbank bekommen, ich habe sie nicht aus dem Cache bekommen. Und sie sind kein vollständiger Datensatz. Sagen wir, welches Set ich mir damals holen wollte. Also habe ich jedes Objekt einzeln zwischengespeichert, auf das ich möglicherweise einzeln zugreifen muss. Aber ich möchte in der Lage sein, alles als eine Sammlung zurückzuholen. Also verwende ich das Konzept eines Tags. Ich habe sie alle mit dem gleichen Tag versehen. Und dieses Tag könnte eine beliebige eindeutige Zeichenfolge sein, und ich sage, geben Sie mir alle Artikel, die dieses Tag haben. So kann ich mit einem Anruf die gesamte Sammlung wieder zurückbekommen. Also, es ist diese Art von Sachen, die Sie mit Tags machen können, die den Mangel an Joins im Cache ausgleichen.

Sie können also gruppieren. Das Gruppen und Untergruppen. Du kannst tun Tags. Sie können benannte Tags verwenden. Benannte Tags Im Wesentlichen haben Sie einen Schlüssel und dann einen Wert. Wenn Sie z. B. Text zwischenspeichern, Freiformtext. Es gibt keine Möglichkeit, diesen Text selbst zu indizieren, da es sich um Text handelt. Sie müssen sich also die Tags selbst zusammenstellen, und nur das Tag selbst reicht möglicherweise nicht aus. Sie möchten in der Lage sein, jedes Tag zu benennen.

Genauso wie ein Objekt Attributnamen hat. Das Namensschild ist also wie Attribute eines Objekts. Der Name könnte also „city“ und der Wert in diesem Text „New York“ oder „Las Vegas“ sein. Sie können also all diese Dinge tun und diese Dinge später abrufen und im Falle von NCache zumindest können Sie verwenden, wenn Sie dies alles entweder über die API oder über die angeben SQL-Abfrage. Wenn Sie also etwas basierend auf SQL abrufen …

Erste Frage, super! Können wir hierarchische Taxonomien verwenden? Was Sie tatsächlich tun können, ist … die Gruppen und Untergruppen geben Ihnen nur eine Hierarchieebene. Innerhalb einer Gruppe können Sie also mehrere Untergruppen haben, aber Sie können nicht darüber hinausgehen.

Sie können verschiedene Arten von Tags zur Darstellung verwenden, da Sie einem Element mehrere Tags zuweisen können. Wenn Sie beispielsweise mehrere Hierarchien hatten, können Sie für jede Ebene, die Sie nach unten gehen, alle obersten Ebenen als separate Tags zuweisen.

Noch eine Frage. Können wir die interne Darstellung des Caches kontrollieren? Die Indizes werden basierend auf einer Kombination von Hash-Tabellen erstellt, falls vorhanden NCache, und rote schwarze Bäume. Sie können die Indizes auswählen, aber Sie wählen nicht, welche Datenstruktur intern verwendet wird. Die Indizes werden jedoch basierend auf der Art der Verwendung erstellt. Hash-Tabellen eignen sich beispielsweise gut für bestimmte Zugriffsarten, und wenn Sie die Bereichssuche durchführen, sind rote schwarze Bäume viel besser. Also, die NCache macht es. Ich weiß nicht, was andere Produkte tun, aber NCache Indizes Zeug ziemlich viel.

Durchlesen und Durchschreiben

Lassen Sie mich das schnell durchgehen durchlesen, durchschreiben. Also, warum wollen Sie Read-Through und Write-Through? Lesen Sie durch, wir haben ein Beispiel dafür gesehen, dass Sie Dinge automatisch neu laden können.

Ein weiterer Vorteil des Durchlesens besteht natürlich darin, dass Sie einen möglichst großen Teil Ihres Datenzugriffs im Cache selbst konsolidieren. Je mehr Sie darauf zugreifen … desto mehr davon geht in den Cache oder die Caching-Schicht, desto weniger ist es in Ihrer Anwendung und die Anwendung wird einfacher. Die Anwendung tut nur a Cache.Get und natürlich war der andere Vorteil davon, dass Sie Sachen automatisch laden können.

Das Durchschreiben erfolgt auf die gleiche Weise. Ein Vorteil besteht darin, dass Sie alle Schreibvorgänge konsolidieren müssen. Der zweite Vorteil ist, dass Sie Ihre Schreibvorgänge tatsächlich beschleunigen können. Write-Behind ist beispielsweise eine Funktion, bei der Sie den Cache synchron aktualisieren und der Cache die Datenbank asynchron aktualisiert. Wenn also die Datenbankaktualisierungen nicht so schnell sind wie der Cache, was wahr ist, verbessert sich Ihre Anwendungsleistung plötzlich, da Sie nur den Cache aktualisieren und die Cache-Datenbank aktualisiert wird.

Read-Through, Write-Through und Write-Behind sind also wirklich sehr leistungsstarke Funktionen, die Sie nutzen sollten. Dies ist auch serverseitiger Code, den Sie schreiben, der auf dem Cache-Cluster ausgeführt wird und Ihr Leben vereinfacht. Damit Ihre Anwendung mehr Daten im Cache haben und auch über den Cache aktualisieren kann.

Lassen Sie es mich schnell durchgehen und über etwas sprechen. Ich werde nicht ins Detail gehen Zwischenspeichern des ASP.NET-Sitzungsstatus. Wisse nur, dass du es einfach ohne Codeänderung anschließen und einfach Änderungen an web.config vornehmen kannst und es sich automatisch darum kümmert und das Gleiche gilt Sichtzustand und Ausgabe-Caching.

Hohe Verfügbarkeit (100 % Betriebszeit)

Ich werde schnell ein paar Dinge durchgehen. Zuerst wollte ich über … jeden Cache sprechen, den Sie verwenden, denn es ist wie eine Datenbank, es ist eine In-Memory-Datenbank in der Produktion. Ein Cache muss also hochverfügbar sein. Sie müssen über einen hochverfügbaren Cache verfügen.

Dynamischer Cache-Cluster

NCache ist durch ein paar Dinge, die es tut, hochverfügbar. Zuerst hat es eine dynamischer Cache-Cluster. Sie können zur Laufzeit Server hinzufügen oder entfernen und den Cluster automatisch neu anpassen. Sie müssen die Servernamen nicht in der Konfiguration fest codieren, die Clients automatisch. Sobald ein Client mit einem beliebigen Cache-Server kommuniziert, erhält er Informationen zur Cluster-Mitgliedschaft. Wenn sich die Mitgliedschaft zur Laufzeit ändert, sagen wir, Sie fügen einen neuen Knoten hinzu oder löschen einen Knoten, wird die aktualisierte Mitgliedschaft an den Client weitergegeben.

Dynamischer Cache-Cluster

Das ist also der erste Teil, der da sein muss. Es ist wirklich wichtig, dass Sie es so sehen.

Caching-Topologien

Die zweite ist die Caching-Topologie. Es gibt also verschiedene Möglichkeiten NCache, gibt Ihnen beispielsweise vier Caching-Topologien. Der erste heißt a Gespiegelter Cache. Es ist ein 2-Knoten aktiv/passiv.

Gespiegelter Cache

Die Sekunde wird aufgerufen Replizierter Cache, wobei jeder Server im Cache eine Kopie des gesamten Caches hat. Je mehr Server Sie also haben, desto mehr Cache-Kopien haben Sie. Es ist zum Lesen skalierbar, nicht für Updates. Aber es hat seine eigene Verwendung mit Fällen.

Replizierter Cache

Die dritte Topologie wird aufgerufen Partitionierter Cache, wo der gesamte Cache in Partitionen aufgeteilt wird. Jeder Server ist eine Partition. Und diese Partitionen werden automatisch erstellt.

Partitionierter Cache

Also z.B. bei NCache Jede Partition enthält eine Reihe von Buckets. Der gesamte Cluster hat also 1,000 Buckets. Wenn Sie also drei Partitionen haben, haben sie ein Drittel, ein Drittel der Buckets.

Partitioniertes Replikat Dasselbe gilt für die Partition, aber jede Partition wird auf einem anderen Server gesichert, und all das wird automatisch für Sie erledigt. Wenn Sie also einen Zwei-Knoten-Cluster erstellen, haben Sie zwei Partitionen, die zwei Replikate. Wenn Sie einen dritten Server hinzufügen, wird automatisch eine dritte Partition erstellt, und wenn eine dritte Partition erstellt wird, müssen einige der Buckets von der vorhandenen Partition verschoben werden.

Partitioniertes Replikat

Das alles wird also automatisch für Sie erledigt. Es wird automatisch ein neues Replikat erstellt. In der Tat, wenn Sie es hier sehen, lassen Sie mich Ihnen das hier zeigen. Nehmen wir an, Sie hätten eine Partition mit zwei Servern … aber sagen wir, wenn Sie nur ein Clustering mit zwei Servern haben, haben Sie zwei Partitionen. Partition 1 war hier und Replica 1. Partition 2, Replica 2. Jetzt, da Sie einen dritten Server hinzugefügt haben, müssen Sie plötzlich eine dritte Partition haben, und diese wird einige der Buckets von hier bekommen, einige andere von hier, das ist eine Sache. Zweitens wird das Replikat 2 nicht mehr hier sein, es wird hierher ziehen, weil jetzt das Replikat für Partition 3 hier sein muss.

All diese Anpassungen werden also automatisch für Sie erledigt NCache. Also, das ist eine Sache. Zweitens gibt es eine Funktion namens Client-Cache Manche Leute nennen es Near Cache, was wirklich mächtig ist, das Sie verwenden müssen. Im Grunde ist es ein lokaler Cache innerhalb Ihrer Client-Anwendung. Das Besondere daran ist jedoch, dass dieser lokale Cache nicht vom Cache-Cluster getrennt wird. Es ist mit dem Cache-Cluster verbunden. Es hält sich selbst synchron.

Client-Cache

Also, im Falle von NCache, beispielsweise fügt sich der Client-Cache hinter den Kulissen automatisch in eine Konfiguration ein. Was auch immer Sie von jeder dieser Anwendungen abrufen, Server ist das, was automatisch im Client-Cache gespeichert wird. Wenn Sie es also das nächste Mal brauchen, finden Sie es im Client-Cache. Und der Cache-Cluster weiß, welche Daten sich in welchem ​​Client-Cache befinden. Wenn sich diese Daten beispielsweise durch einen anderen Client ändern, benachrichtigt der Cluster alle Client-Caches, die über diese Daten verfügen, und aktualisieren sich selbst. Der Client-Cache bleibt also verbunden, ist aber ein lokaler Cache. Es kann sogar In-Proc sein. In-Proc bedeutet innerhalb Ihres Bewerbungsprozesses. Das beschleunigt also Ihre Leistung wirklich, aber gleichzeitig sind Sie Teil des gesamten verbundenen verteilten Caches.

WAN-Replikation

Ich werde eine Menge Zeug überspringen, wir haben keine Zeit. Also, es gibt auch WAN-Replikation. Wenn Sie über mehrere Rechenzentren verfügen, sollten Sie in der Lage sein, den Cache selbst über das WAN zu replizieren, und Sie können keinen Cluster über das WAN erstellen. Das wird einfach sterben, weil diese Steckdosen kaputt gehen, die Latenz ist einfach sehr hoch. Es muss also eine Möglichkeit geben, Caches über zwei Rechenzentren hinweg zu verbinden.

Im Falle von NCache Wir haben dieses Ding namens Bridge-Topologie, das mehrere Rechenzentren verbindet. Sie können jetzt Aktiv-Aktiv-, Aktiv-Passiv- oder sogar mehr als zwei Rechenzentren haben. All dies geschieht asynchron, und es wird auch eine Konfliktlösung für Sie erledigt. Wie Sie also sehen können, ist ein Cache nicht nur ein einfacher Schlüsselwertspeicher. Hinter den Kulissen gibt es also einiges zu beachten.

NCache vs Redis

Eine Sache, die ich schnell abdecken wollte, war NCache vs Redis, nur ein hohes Niveau, ich wollte darüber sprechen. NCache ist der native .NET-Cache. Es läuft unter Windows und Sie können sowohl das clientseitige als auch das serverseitige Caching durchführen, das ist ein Vorteil. Wohingegen, Redis ist hauptsächlich Linux-basierter Cache. Bevor Microsoft eine Partnerschaft mit ihnen einging, wussten Sie, dass die meisten Leute auf der .NET-Seite nicht einmal wussten, dass sie existieren, obwohl sie ein sehr beliebter Cache unter Unix und PHP und anderen Umgebungen waren.

Zweitens die Linux-Version von NCache ist auf Azure verfügbar, als Cache as a Service. Der Grund für Cache as a Service liegt also darin, dass Sie für .NET-Anwendungen serverseitigen Code nicht wirklich auf einem Linux-basierten Cache ausführen können. Sie müssen einen .NET-basierten Cache haben, damit Sie ihn ausführen können. Das ist also eine große Einschränkung, die Sie bekommen werden.

Drittens, wenn Sie etwas außerhalb von Azure tun möchten, Redis ist nur als Linux-basierter Cache verfügbar. Die Windows-Unterstützung, die Microsoft bietet, ist etwas, das sie selbst nicht verwenden. Selbst auf Azure entscheiden sie sich nicht dafür, es für die Fenster zu verwenden. Es ist nicht sehr stabil. Es gibt auch mehr Details, wenn Sie eine detailliertere sehen möchten Vergleich zwischen NCache und Redis, Sie können hierher kommen und dann Vergleiche sehen. Also, wir haben Vergleiche mit allen, weil wir von uns so überzeugt sind.

Wie Sie sehen können, ist dies also ein vollständiger Vergleich. Gehen Sie es einfach durch. Wenn Sie darüber nachdenken, einen verteilten Cache zu verwenden, was Sie tun sollten, haben Sie all diese Skalierbarkeitsanforderungen. Machen Sie Ihre Hausaufgaben, stellen Sie sicher, dass alles, was Sie verwenden, Ihren Bedürfnissen entspricht. Und soweit NCache interessiert, machen wir Ihnen den Vergleich leicht NCache mit anderen. Sie können auf unsere Website kommen und herunterladen NCache. Es ist Open-Source. Sie können also entweder die Enterprise Edition oder die Open Source Edition hier herunterladen oder zu gehen GitHub und du wirst haben NCache .

Das ist das Ende meiner Präsentation. Irgendwelche Fragen? Sie können einen Aufruf einer gespeicherten Prozedur übergeben. Es muss alles SQL sein, wie das Transact-SQL-Zeug, das innerhalb des SQL-Servers selbst ausgeführt wird.

Ja. Der Cache kann sich also auf demselben Server wie die Anwendung befinden. Wir empfehlen es nicht. Es ist keine gute Bereitstellungsstrategie, aber wenn Sie eine kleine Konfiguration haben, ja, natürlich.

Wenn Sie partitionieren, wird die gesamte Partitionierung für Sie erledigt. Die ganze Idee ist also, dass jede Partition in Bezug auf Datengröße und Transaktionen gleich gewichtet sein sollte.

Sie kontrollieren die Partitionen nicht, Sie wissen nur, dass sie existieren.

Wenn Sie die Elementtabelle aktualisieren, können Sie den Cache aus der Datenbank selbst aktualisieren, wenn Sie über eine CLR-Prozedur verfügen, die direkt von der Datenbank zum Cache aufrufen kann. Sie können auch separaten Code schreiben, der den Cache aktualisieren kann, und das alles hängt davon ab, wie viel Sie davon im Cache behalten und behalten.

Also weißt du, ich kann offline über mehr reden, wenn du willst. Aber ich meine, es gibt mehrere Möglichkeiten, wie Sie sicherstellen können, dass alle Daten, auf die Sie zugreifen müssen, im Cache aktuell gehalten werden.

Ja, eigentlich werde ich die Folien zur Verfügung stellen. Aus diesem Grund haben wir alle E-Mails gescannt. Wir können das also tun und wir werden auch das Video aufnehmen und hochladen. Sie können also zuschauen und auch Ihre Kollegen können es sich ansehen.

Eigentlich pro Anwendung oder … Eigentlich über mehrere Anwendungen hinweg. Es hängt also alles von der Transaktionslast ab. Sie können mindestens 2 Cache-Server haben, nur um den Cluster zu haben, und dann hängt die Anzahl der Server davon ab, wie viele Anwendungsserver Sie haben oder wie viel, wie viel Aktivität Sie im Grunde haben? Wie viele Daten werden zwischengespeichert? Wie viel liest und schreibt ihr?

Es spielt keine Rolle, ja. Ja, alles wird weiter funktionieren. Danke Jungs.

Was macht man als nächstes?

 

Melden Sie sich für den monatlichen E-Mail-Newsletter an, um die neuesten Updates zu erhalten.

© Copyright Alachisoft 2002 - Alle Rechte vorbehalten NCache ist eine eingetragene Marke der Diyatech Corp.