Twin Cities Code Camp

Skalierung von .NET-Anwendungen mit verteiltem Caching

Von Iqbal Khan
Präsident & Technologie-Evangelist

Sehen Sie sich diese praktische Demo eines verteilten Caches an und lernen Sie Best Practices für die Verwendung eines .NET-Caches in verschiedenen Umgebungen kennen. Dieser Vortrag behandelt:

  • 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

Vielen Dank an alle fürs Kommen. Mein Name ist Iqbal Khan. Es ist ein wunderschöner Tag draußen. Ich komme aus Tampa. Also viel angenehmere Temperaturen hier. Ich hatte viel kühleres Wetter erwartet als das, was wir hier haben. Vielen Dank, dass Sie drinnen geblieben sind. Ich bin ein Technologie-Evangelist bei dieser Firma namens Alachisoft. Wir sind die Macher von NCache. Nur die nächsten ein oder zwei Minuten werden eine Marketingaussage sein. Wir haben also zwei Produkte für den .NET-Bereich. Eines ist unser wichtigstes Flaggschiffprodukt mit dem Namen NCache Das ist ein verteilter Cache für .NET. Das ist die Expertise, die wir haben. Wir sind also seit etwa zehn Jahren in diesem Bereich tätig und haben auf diese Weise Fachwissen zu diesem speziellen Thema aufgebaut.

Wir haben ein weiteres Produkt namens NosDB Das haben wir Ende letzten Jahres eingeführt. Es ist eine Open Source NoSQL database für .NET. Es ähnelt Funktionen auf MongoDB-Niveau, aber natives .NET und wiederum alles Open Source. NCache ist auch Open Source und das ist es auch NosDB. Bitte werfen Sie einen Blick auf unsere Produkte.

Daher würde ich eine interaktivere Diskussion vorziehen. Wir werden eine Kombination aus einer architektonischen konzeptionellen Diskussion und etwas Quellcode durchgehen. So können wir tatsächlich sehen, wie Sie einen Cache für Ihre Anwendung verwenden würden. Also lasst uns anfangen.

Skalierbarkeit

Lassen Sie uns ein paar Definitionen klären. Nummer eins ist; Was ist Skalierbarkeit? Skalierbarkeit bedeutet nicht Leistung. Wenn Ihre Anwendung also mit 5 Benutzern eine schnelle Leistung erbringt, ist sie nicht skalierbar, es sei denn, Sie können die gleiche gute Leistung unter 5000, 50,000 oder 500,000 Benutzern erzielen. Wenn Ihre Anwendung mit 5 Benutzern nicht schnell funktioniert, müssen Sie natürlich andere Aspekte berücksichtigen als die, über die wir sprechen werden.

Lineare Skalierbarkeit

Lineare Skalierbarkeit ist eher eine Terminologie der Bereitstellungsarchitektur. Wenn Ihre Anwendung so konzipiert ist, dass Sie weitere Server hinzufügen können, um Ihre Kapazität, Ihre Transaktionskapazität, zu erhöhen. Übrigens, wenn ich das Wort Skalierbarkeit verwende, spreche ich hauptsächlich von Transaktionskapazität, ich rede nicht über viel von Dateien. Im Hinblick auf die Skalierbarkeit sprechen wir also nicht von Terabytes an Daten. Wir sprechen darüber, wie Sie viele Transaktionen und viele Aktivitäten abwickeln können. Eine lineare Skalierbarkeit bedeutet also, dass Sie Ihre Transaktionskapazität einfach durch das Hinzufügen von Servern erhöhen können und es keine Engpässe gibt, und genau das wollen wir erreichen.

Lineare Skalierbarkeit

Nichtlineare Skalierbarkeit

Nichtlinearität ist natürlich nicht das, was wir erreichen wollen. Das bedeutet, dass es keine Rolle spielt, wie viele Server Sie hinzufügen, Ihre Leistung wird ab einem bestimmten Punkt sinken, da in Ihrer Anwendungsarchitektur in Ihrer Bereitstellung ein grundlegender Engpass vorliegt, der Sie daran hindert, zu skalieren.

Nichtlineare Skalierbarkeit

Welche Anwendungen benötigen Skalierbarkeit?

Welche Art von Anwendungen benötigen Skalierbarkeit? Dies sind in der Regel serverartige Anwendungen, ASP.NET, ASP.NET Core Jetzt gibt es Webdienste, bei denen es sich normalerweise um WCF handelt, und IoT-Backend, bei denen es sich normalerweise um Webdienste handelt, obwohl dies nicht unbedingt der Fall sein muss. Anwendungen zur Big-Data-Verarbeitung. Diese werden im Allgemeinen in Java ausgeführt, aber wenn Sie dies in .NET tun würden, stünden Sie vor dem gleichen Problem wie in Java und jeder anderen Serveranwendung, die viele Transaktionen verarbeiten muss. Sie könnten beispielsweise eine Bank oder ein Finanzdienstleistungsunternehmen mit Millionen von Kunden sein. Sie rufen Sie an, um Ihre Adresse zu ändern, vielleicht Geld zu überweisen, und nachts müssen Sie all dies aus Compliance- oder anderen SLA-Gründen bearbeiten. Auch wenn Sie also über mehr Stapelverarbeitung und Back-End-Verarbeitung verfügen, sind das Ihre anderen Server-Apps, die immer noch in der Lage sein müssen, so viele Informationen zu verarbeiten, und wenn sie dazu nicht in der Lage sind, dann Sie Wissen Sie, Sie stecken in großen Schwierigkeiten.

Das Skalierbarkeitsproblem

Wenn Sie über diese Anwendungen verfügen, benötigen sie höchstwahrscheinlich Skalierbarkeit. Lassen Sie uns nun darüber sprechen, wo dieses Problem liegt. Wo liegt das Skalierbarkeitsproblem, das wir angehen wollen? Das Skalierbarkeitsproblem liegt wirklich nicht auf der Anwendungsebene. Ihre Anwendung, über die ich gesprochen habe, ist im Allgemeinen so konzipiert, dass Sie problemlos weitere Server hinzufügen können. Das Problem liegt bei Ihrer Datenspeicherung. Damit meine ich den Ort, an dem sich Ihre Anwendungsdaten befinden, Ihre relationalen Datenbanken. Dies kann SQL Server, Oracle, MySQL sein. Es handelt sich nicht um einen bestimmten Anbieter. Das Konzept relationaler Datenbanken ist konstruktionsbedingt nicht skalierbar. Tatsächlich können sie auch hinsichtlich der Datenmenge nicht skaliert werden. Deshalb NoSQL databases sind so beliebt geworden, aber vor allem auf der Transaktionsseite und das Gleiche gilt, wenn Sie über alte Mainframe-Daten verfügen. Viele Anwendungen müssen auf Altdaten zugreifen. Hier tritt also der Engpass auf, und wenn Sie diesen haben, spielt es keine Rolle, ob diese Stufe skalierbar ist, Sie können nicht skalieren.

NoSQL databases sind genau aus diesem Grund populär geworden, weil sie Skalierbarkeit bieten. Und, wissen Sie, und wir haben auch eine NoSQL database Produkt, aber oft wird das Problem nicht behoben. Sie können das Problem nicht beheben, da Sie sie aus technischen und geschäftlichen Gründen nicht verwenden können. Um a zu verwenden NoSQL database Sie müssen Daten dort ablegen und nicht in Ihrer relationalen Datenbank. Einige Daten, die Sie machen können. Das kannst du auf jeden Fall reinstecken NoSQL database Aber viele Ihrer herkömmlichen Geschäftsdaten bleiben in relationalen Datenbanken. Wenn Sie Ihre Daten also nicht verschieben können NoSQL databases, sie sind nicht gut. Sie müssen dieses Problem also lösen und dabei bedenken, dass Sie weiterhin mit relationalen Datenbanken leben werden, auch wenn Sie eine setzen NoSQL database In der Mischung ist das nur eine Teilmenge der Daten. Normalerweise ist es kein Ersatz für relationale Datenbanken. Und als NoSQL database Wissen Sie, ich bin ganz ehrlich zu Ihnen: Wenn wir mit unseren Kunden sprechen, sagen wir nicht, dass wir aufhören sollen, relationale Beziehungen zu nutzen, das wird nie passieren. Wir sagen: Verwenden Sie es als Erweiterung des relationalen Ansatzes. Wenn Sie also bei der Beziehung bleiben müssen, müssen Sie dieses Problem damit lösen, wissen Sie, damit in der Mischung, und hier kommt ein verteilter Cache ins Spiel, deshalb führen wir dieses Gespräch.

Verteilte Cache-Bereitstellung (NCache)

Ein verteilter Cache, lassen Sie mich das ein wenig definieren. Ein verteilter Cache wird verteilt. Es lebt hier auf zwei oder mehr Servern. Logischerweise handelt es sich um eine separate Caching-Ebene. Physisch kann es sich auf derselben Box wie die Anwendung befinden, aber logischerweise handelt es sich um eine separate Caching-Ebene. Zwei oder mehr Server und ein verteilter Cache bilden normalerweise einen Cluster. Daher handelt es sich in der Regel um einen Cluster davon, wobei TCP-basierte Cluster am häufigsten vorkommen. NCache Verwendet definitiv TCP für das Clustering. Und dieser Cluster bedeutet, dass alle Ressourcen, alle diese Server, die CPU, der Speicher und die Netzwerkkarten alle in einem Pool zusammengefasst sind. Und so wird es skalierbar. Denn Sie können bei Bedarf weitere Server hinzufügen, wenn Sie die Kapazität erhöhen müssen.

Verteilte Cache-Bereitstellung (NCache)

Auch das können Sie hier tun. Aber das können Sie hier nicht tun. Wie gesagt, Sie können dem Mix eine weitere SQL-Datenbank hinzufügen, aber Sie müssen diese im Bild haben. Sobald Sie dies im Bild haben, benötigen Sie so etwas in Ihrem Mix.

Ein verteilter Cache lebt auf kostengünstigen Servern. Dabei handelt es sich nicht um Konfigurationen, die für High-End-Datenbanken typische Webservertypen sind. Die meisten unserer Kunden haben eine 8-Kern-Box, also so, als wäre es früher eine Dual-CPU gewesen, jetzt verwenden wir nur noch das Wort 8 Kerne und 64 Bit mit einfach viel Speicher. Viele bedeuten, dass 16 bis 32 GB so ziemlich der Durchschnitt pro Server sind, den wir sehen. Wir empfehlen nicht einmal mehr als 64 GB pro Box. Denn wenn Sie über mehr als 64 GB Arbeitsspeicher verfügen, erfordert .NET eine Garbage Collection. Der GC selbst ist eine ziemlich zeitaufwändige Aufgabe und wird automatisch zu einem Engpass. Es ist also besser, mehr Server zu haben, als nur wenige wirklich High-End-Server. Denn obwohl der Cache absichtlich verteilt ist, wird der Engpass jetzt zu einer Speicherbereinigung. Und das haben wir im Laufe der Jahre durch viele schmerzhafte Erfahrungen gelernt. Wissen Sie, wir hatten Kunden, die auf 128 Gigabyte aufgestiegen sind, und plötzlich stand die CPU unter großem Druck. Sie mussten also ihre Rechenleistung erheblich erhöhen und es begann mehr wie eine Datenbank auszusehen. Also wissen Sie, wir haben empfohlen, es herunterzufahren.

Sie speichern Daten, die sich in der Datenbank befinden, zwischen. Und in 80 % der Fälle werden Sie im Wesentlichen auf die Caching-Ebene wechseln, in 20 % der Zeit auf die Datenbank. Der Cache ist superschnell im Arbeitsspeicher, viel schneller als jede andere Datenbank NoSQL database, auch schneller als unsere eigenen NoSQL database. NCache ist mindestens eine Größenordnung schneller als jede Datenbank. Denn wie Sie wissen, müssen Datenbanken auf der Festplatte gespeichert werden. Aber alle Aktualisierungen müssen natürlich in die eigentliche Datenbank erfolgen. Da kommen also die 20 % hinzu, plus natürlich einige der Lesevorgänge.

Wenn Sie das tun, wird die Datenbank plötzlich vollständig entlastet. Jetzt funktioniert es. Ihre Lesevorgänge sind viel schneller und auch die Aktualisierungen sind viel schneller. Sie können also diese Skalierbarkeit erreichen, aber Sie können auch, dass die Anwendung jetzt nicht nur skalierbar ist, sondern plötzlich auch schneller. Obwohl der Hauptgrund für die Verwendung eines Caches nicht darin besteht, die Leistung zu verbessern, was wiederum im Widerspruch zu dem steht, was die Leute traditionell denken, wissen Sie, dass Cache dazu da ist, die Leistung zu verbessern. Das ist, in einer eigenständigen Situation, ja, das ist der Fall. Sogar die Datenbanken verwenden In-Memory-Caching. Unser NosDB Verwendet auch integriertes Caching, aber es dient eigentlich der Skalierbarkeit, wozu Sie in der Lage sein müssen, denn das ist ein Problem, aus dem Sie sich nicht loskaufen können. Sie können keine teurere Hardware kaufen, um Skalierbarkeit zu erreichen. Sie müssen die Anwendung entwerfen und die richtige Infrastruktur oder die richtigen Komponenten als Teil Ihrer Architektur verwenden, wenn Sie eine skalierbare Anwendung haben möchten.

Auf der Java-Seite wird dies als In-Memory-Data-Grid bezeichnet. Auf der .NET-Seite spricht man von einem verteilten Cache. Ein anderes Wort dafür ist In-Memory NoSQL Schlüsselwertspeicher. Ich meine, es gibt drei verschiedene Sichtweisen. Das ist kein NoSQL database es ist ein NoSQL Schlüsselwert im Speicher. Da es keine Persistenz bietet, verfügt es nicht über einen permanenten Speicher.

Wenn Sie also ein Bild wie dieses haben, möchte ich, dass Sie aus architektonischer Sicht davon überzeugt sind, dass Sie jetzt eine Anwendung haben, bei der es nie zu Engpässen kommen wird. Wenn Sie Ihre Anwendung so gestalten, dass sie diese für Ihre Infrastruktur verwendet. Noch Fragen, bevor ich näher darauf eingehe.

Ich denke, es hängt von den Details ab. Woher wissen Sie, ob der Cache veraltet ist oder ob Sie etwas außerhalb des Gehäuses aktualisieren? Lassen Sie mich dazu kommen. Gute Frage.

Allgemeine Verwendung von verteiltem Cache

Nehmen wir an, wir sind davon überzeugt, dass wir einen verteilten Cache als Teil unserer Anwendungsarchitektur benötigen. Die nächste Frage, die uns in den Sinn kommt, ist, wie verwenden Sie ihn? Wo verwenden Sie den Cache und welche Probleme sind mit den einzelnen Verwendungsarten verbunden? Als .NET-Entwickler liegt mein Fokus wieder auf .NET, aber die gleichen Konzepte gelten auch für andere Anwendungen.

Zwischenspeichern von Anwendungsdaten

Der häufigste Anwendungsfall ist das Caching von Anwendungsdaten, worüber ich bisher gesprochen habe, bei dem man eine Datenbank hat und die Daten hier einfach zwischenspeichert. Das Ziel besteht also darin, die Datenbank nicht so häufig aufzurufen. Und Sie erhalten alle Vorteile, über die ich gesprochen habe. Sobald Sie das tun, tritt ein Problem auf, über das Sie gerade gesprochen haben. Die Daten liegen nun an zwei Stellen vor. Einer davon ist der permanente Master-Speicher, also Ihre Datenbank, in dem Sie sich immer befinden müssen, und der zweite ist der Cache. Und tatsächlich existiert es innerhalb des Caches an mehr als einer Stelle und ich werde auch darüber sprechen.

Was kann also schief gehen, wenn die Daten an mehr als einem Ort vorhanden sind? Wissen Sie, es könnte aus dem Takt geraten. Wenn also ein verteilter Cache diese Situation nicht bewältigen kann, sind Sie gezwungen, schreibgeschützte Daten zwischenzuspeichern. Tatsächlich ist es so, dass die meisten Menschen, wenn sie an Cache denken, reflexartig denken, dass es sich nur um schreibgeschützte Daten handelt. Denn wenn ich Daten zwischenspeichere, die sich ändern, nenne ich das Transaktionsdaten. Dann wird es nicht mehr synchron sein. Und wenn Sie wissen, dass das klassische Problem, zweimal eine Million Dollar vom selben Bankkonto abzuheben, hier auftritt. Wenn ein Cache dieses Problem also nicht löst, sind Sie auf eine sehr kleine Teilmenge beschränkt. Etwa 10 bis 15 % der Daten sind alles, was Sie zwischenspeichern können, und das reicht nicht aus. Ein guter verteilter Cache muss sich also mit diesem Problem befassen, und darüber werde ich sprechen.

ASP.NET-spezifisches Caching

Der zweite Anwendungsfall besteht darin, dass Sie bei einer ASP.NET-Anwendung drei verschiedene Dinge darin speichern können. Natürlich ändert sich dies, da neue Frameworks auf den Markt kommen. Am gebräuchlichsten ist also der ASP.NET-Sitzungsstatus, der sowohl im ASP als auch im ASP vorhanden ist.NET core und das traditionelle ASP-Framework. Sitzungen werden standardmäßig entweder In-Proc oder im SQL Server gespeichert. Beide haben Skalierbarkeitsprobleme. SQL hat auch Leistungsprobleme. Und weil relationale Datenbanken nicht für die Speicherung von Blobs konzipiert sind und Sitzungen als Blobs gespeichert werden. Und zweitens, wissen Sie, aus demselben Grund, aus dem Sie Anwendungsdaten zwischenspeichern und nicht auf die Datenbank zugreifen möchten, möchten Sie auch keine Sitzungen in der Datenbank behalten. Dies ist also ein sehr, sehr idealer Anwendungsfall für ASP.NET-Anwendungen. Und wissen Sie, das ist das Erste, was die meisten unserer Kunden nutzen. Wenn Sie über eine bestehende Anwendung verfügen und einen verteilten Cache integrieren möchten, ist der geringste Aufwand für die Integration von Sitzungen erforderlich. Weil, ASP.NET framework Ermöglicht das Einbinden eines Caches eines Drittanbieters. Es ist keine Programmierung erforderlich. Sie nehmen einfach eine Änderung an der web.config vor. Lassen Sie mich Ihnen das schnell zeigen. Ich werde einfach hin und her springen.

So habe ich zum Beispiel diese kleine ASP.NET-Anwendung und hier eine web.config, die ich natürlich verwenden werde NCache als Beispiel, sondern, sagen wir mal, zu verwenden NCache Als Sitzungsstatusanbieter müssen Sie diese Assemblys einfügen. Also Tag „Assembly hinzufügen“. Also, diese Versammlung von NCache hat die ASP.NET-Sitzungsstatus-Provider-Schnittstelle implementiert.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <machineKey validationKey="A01D6E0D1A5D2A22E0854CA612FE5C5EC4AECF24" decryptionKey="ACD8EBF87C4C8937" validation="SHA1" />
        <compilation defaultLanguage="c#" debug="true" targetFramework="4.0">
            <compilers>
                <compiler language="c#" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" extension=".cs" compilerOptions="/d:DEBUG;TRACE" />
            </compilers>
            <assemblies>
                <add assembly="Alachisoft.NCache.SessionStoreProvider, Version=4.6.0.0, Culture=neutral, PublicKeyToken=CFF5926ED6A53769" />
            </assemblies>
        </compilation>
        
        <customErrors mode="RemoteOnly" />
        <authentication mode="None" />
        <authorization>
            <allow users="*" />
        </authorization>
        <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
        <!-- For NCache Developer Edition replace 'myPartitionedCache' with 'myCache' or any other local-cache-->
        <sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="NCacheSessionProvider" timeout="1">
            <providers>
                <add name="NCacheSessionProvider" type="Alachisoft.NCache.Web.SessionState.NSessionStoreProvider" exceptionsEnabled="true" enableSessionLocking="true" emptySessionWhenLocked="false" sessionLockingRetry="-1" sessionAppId="NCacheTest" useInProc="false" enableLogs="false" cacheName="myPartitionedCache" writeExceptionsToEventLog="false" AsyncSession="false" />
            </providers>
        </sessionState>
        <!--  GLOBALIZATION
        This section sets the globalization settings of the application. 
		-->
        <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
        <xhtmlConformance mode="Legacy" />
        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
    </system.web>
    <system.webServer>
        <directoryBrowse enabled="true" showFlags="Date, Time, Size, Extension, LongDate" />
    </system.webServer>
</configuration>

Auf diese Weise entspricht es dem ASP.NET framework spec soll ein Drittanbieter-Cache sein. Das ist also das Erste, was Sie tun, und als Zweites ändern Sie den Namensraum. Eigentlich verwenden Sie einfach dieses Tag. Stellen Sie also sicher, dass der Modus benutzerdefiniert ist und die Zeitüberschreitung auf keinen Fall eine Minute beträgt. Es sollte 20 sein. Und ich werde darauf zurückkommen. Das ist der Cache-Name.

Im Falle von NCache, alle Caches werden benannt. Ich werde darauf zurückkommen. Das ist alles, was Sie tun, und Ihre Anwendung beginnt, die Sitzungen in einem Cache zu speichern. Und Sie werden sofort eine Leistungssteigerung feststellen, da es im Speicher läuft und viel schneller als SQL ist. Nicht schneller als In-Proc, aber schneller als SQL, aber in beiden Fällen skalierbarer.

Der zweite Anwendungsfall für ASP.NET ist der Ansichtsstatus. Wenn Sie das MVC-Framework nicht verwenden und es sich noch im alten ASP.NET befindet, haben Sie einen Ansichtsstatus, den Sie möglicherweise kennen oder nicht. Ein Ansichtsstatus, für diejenigen unter Ihnen, die es nicht wissen: Es handelt sich um eine verschlüsselte Zeichenfolge, die vom Webserver an den Browser gesendet wird und nur dann zurückkommt, wenn ein Beitrag zurückkommt. Dies könnte also eine Größe von Hunderten von Kilobyte erreichen. Multiplizieren Sie das mit Millionen von Anfragen, die Ihre Anwendung verarbeiten muss, und es passieren zwei schlimme Dinge: Zum einen verbraucht es viel Bandbreite und zum anderen ist die Bandbreite nicht frei. Wenn Sie Ihre Anwendung hosten, müssen Sie für die Bandbreite bezahlen. Zweitens ist die Reaktionszeit langsamer, da es sich um eine viel schwerere Nutzlast handelt. Wenn Sie das also auf der Serverseite zwischenspeichern könnten, würde das alles einfach wegfallen und die Anwendung schneller machen.

Der Ausgabecache ist ein ASP.NET framework Dadurch können Sie die Seitenausgabe zwischenspeichern, sodass die Seitenausgabe, wenn sie sich nicht ändert, einfach von der letzten Ausführung übernommen wird. Auch hier ist es besser, einen verteilten Cache in eine Webfarm einzubinden, als separate Kopien dieses Ausgabecaches auf jedem Webserver zu behalten. Was Sie eigentlich tun möchten, ist, diese Webserver aus Sicht der Anwendungsverwaltung völlig zustandslos zu machen. Wenn sie zustandslos sind, können Sie alle Patches durchführen, Sie können, wissen Sie, alle Fehlerbehebungen, alle Upgrades Ihrer Anwendung, im Hinblick auf Software-Upgrades sind sie viel häufiger als alle Upgrades des Caches. Wenn hier also kein Status verwaltet wird, können Sie diese Box auch aus der Webfarm löschen, der Benutzer wird es nicht einmal bemerken. Denn der gesamte Status wird hier oder in der Datenbank verwaltet und auch diese berühren Sie nicht so häufig, also speichern Sie sie erneut im Cache.

Was nun das ASP.NET-spezifische Caching betrifft, ist es gut, dass all dies keine Programmierung erfordert. Sie können sie also ohne großen Aufwand sofort anschließen. Das Einzige, was Sie natürlich tun, ist ein Gesundheitstest. Wenn Sie beispielsweise den ASP.NET-Sitzungsstatus anschließen und In-Proc-Sitzungen verwenden, stellen Sie möglicherweise fest, dass nicht alle Ihre Objekte serialisierbar sind. Und Sie wussten es nicht und plötzlich wird Ihre Anwendung Ausnahmen auslösen. Also, ich meine, wissen Sie, das Maß an Tests, das Sie durchführen müssen. Aber jetzt gibt es noch ein weiteres eigenartiges Problem: Im Gegensatz zu diesem Problem, bei dem Sie zwei Kopien der Daten haben, sind die Daten jetzt nur noch im Cache vorhanden.

Was kann also schiefgehen, wenn ein In-Memory-Store Ihr Master-Store ist? Maschine fällt aus. Ja, wissen Sie, wenn ein Server ausfällt, gehen Daten verloren, und Sie möchten keine dieser Daten verlieren, insbesondere nicht die Sitzungen. Ein guter verteilter Cache muss sich also mit diesem Problem befassen, und dies geschieht normalerweise durch Replikation, sodass dieselben Daten an mindestens zwei Orten vorhanden sind. Wenn dies nicht der Fall ist, legen Sie bitte keine Sitzungen in diesem Cache ab, es sei denn, Sie tun dies nicht. Es ist nicht wirklich... es spielt keine Rolle, ob Ihre Benutzer diese Sitzung verwenden, was in den meisten Situationen nicht der Fall ist.

Gemeinsame Nutzung von Laufzeitdaten

Der dritte Anwendungsfall ist gemeinsame Nutzung von Laufzeitdaten durch Ereignisse. Das ist etwas, was man normalerweise mit Nachrichtenwarteschlangen macht, die, wie Sie wissen, ihren eigenen Platz haben und ein verteilter Cache nicht dazu da ist, sie zu ersetzen, aber ein verteilter Cache ist viel schneller, skalierbarer und wenn die Nachrichten oder die Datenfreigabe vorhanden sind Wenn dies am selben Ort und im selben Rechenzentrum erfolgt, können Sie einen verteilten Cache in einem verwenden Pub / Sub Art und Weise, das können Sie tun. Es gibt auch andere Arten von Veranstaltungen, bei denen Sie Interesse an bestimmten Artikeln zeigen können. Wenn sich dieser Artikel ändert, benachrichtigen Sie mich bitte. Oder im Falle von NCache Es gibt eine Funktion namens kontinuierliche Abfrage wo Sie auch eine SQL-Anweisung ausführen und sagen könnten: „WÄHLEN SIE KUNDEN AUS, WO KUNDE.STADT = NEW YORK'. Sollte dieser Datensatz jemals aktualisiert, gelöscht oder ein neues Objekt hinzugefügt, aktualisiert oder gelöscht werden, benachrichtigen Sie mich bitte. Wenn also die Anwendung diese Art der Überwachung ermöglicht, können die Verbraucher viel intelligenter darüber entscheiden, worüber sie benachrichtigt werden möchten. Und die Produzenten können den Cache ständig aktualisieren.

Das ist also der dritte Anwendungsfall, den viele Leute nicht kennen, aber jetzt wird immer offensichtlicher, dass der Cache ein sehr guter Ort dafür ist. Denn aus diesen beiden Gründen verwenden Sie den Cache bereits. Warum also nicht dies einfügen, es lässt sich ganz einfach in Ihre Bewerbung integrieren. Haben Sie noch Fragen, bevor ich näher darauf eingehe?

Demo

Daher zeige ich Ihnen zunächst, wie ein Cache aussieht. Damit wir das dann in den Kontext von allem, worüber wir sprechen, einordnen können. ich werde benützen NCache als Beispiel. Ich habe also eine Reihe von VMs in Azure. Ich habe also eine Demo1, eine Demo2 und einen Demo-Client. Demo1 und Demo2 sind meine Cache-Server-VMs. Der Demo-Client ist die Anwendungsserver-Box. Das ist also der Cache-Client. Also ich habe das alles.

Azure-VMs

Ich gehe und bin angemeldet, sagen wir, ich bin beim Demo-Client angemeldet. Ich werde fortfahren und einen Cache erstellen. Also werde ich es verwenden NCache Manager, das grafische Werkzeug. Ich werde fortfahren und sagen: „Neuen Cluster-Cache erstellen“.

Cache erstellen

Im Falle von NCache, alle Caches werden benannt. Ich werde nicht alle Einzelheiten erklären. Ich gebe einfach jedem Cache einen Namen.

Geben Sie den Cache-Namen an

Ich werde eine Topologie des Caches auswählen. Topologie ist eigentlich eine Speicher- und Replikationsstrategie. Also eine Topologie, falls NCacheNehmen wir an, es gibt eine Topologie namens Partitionsreplikat. Bei diesen beiden handelt es sich hier also um Cache-Server, und jeder Server verfügt über eine Partition. Sagen wir also im Falle von NCache, NCache erstellt eine Partition für jeden Server und jeder Server enthält eine Replik der Partition eines anderen Servers. Jede Partition enthält ein Ntel der Gesamtzahl der Buckets. Im Falle von NCache Es gibt 1000 Buckets pro Cache.

Caching-Topologien

Nehmen wir also an, wenn es sich um einen Cluster mit zwei Knoten handelt, sind es jeweils 500 Buckets, wenn es sich um einen Cluster mit drei Knoten handelt, sind es ein Drittel, ein Drittel, ein Drittel.

Partitionsreplikat, die Partitionen sind aktiv, die Replikate sind nicht aktiv, sie sind passiv. Der Client kommuniziert also nur mit den Partitionen. Nehmen wir an, wenn ein Client hier ein Element aktualisiert, repliziert die Partition es auf das Replikat und die Replikation erfolgt standardmäßig asynchron. Denn um echte Skalierbarkeit zu erreichen, müssen Sie zu diesem Eventual-Consistency-Modell wechseln. In manchen Fällen sind Ihre Daten jedoch sehr sensibel. Wissen Sie, es gibt viele Finanzdienstleistungsunternehmen wie Banken, die das nutzen NCache und ihre Daten sind tatsächlich Geld. In diesem Fall können sie also keine endgültige Konsistenz erreichen. Dort müssen Sie also eine synchrone Replikation durchführen, was bedeutet, dass die Anwendung wartet, bis die Daten an beiden Stellen aktualisiert werden. Wenn ein Server ausfällt, sagen wir, wenn Sie einen Cluster mit drei Knoten hatten und Server 3 ausgefallen ist, ist Partition 3 ausgefallen, Replikat 3 wird sofort aktiv.

Datenausgleich beim Hinzufügen eines Servers

Auf diese Weise erhält man also die Hochverfügbarkeit, und sobald sie aktiv ist, erkennt sie, dass es nur zwei Server und dann drei Partitionen gibt, was nicht so sein sollte. Es wird also mit Partition 1 und 2 zusammengeführt und sobald dies erledigt ist, wird hier eine Replik für Partition 2 erstellt.

All das im Falle von NCache erfolgt zur Laufzeit, ohne dass Ihre Anwendung überhaupt merkt, dass dies geschieht. Ebenso könnten Sie einen 2-Knoten-Cluster haben und einen dritten Server hinzufügen, und auch hier ändert sich die gesamte Karte automatisch von hier nach hier. Das bedeutete also diese Wahl.

Also werde ich einfach auswählen Partitionsreplik als Topologie.

Replikationsstrategie

Ich werde die asynchrone Replikation beibehalten.

Replikationsstrategie

Ich wähle meinen ersten Server aus, der Demo 1 ist, und den zweiten Server, der Demo 2 ist.

Wählen Sie „Cluster-Cache-Mitgliedsknoten“ aus

Ich übernehme alle Standardeinstellungen. Ich werde angeben, ich sage, es ist nur 1 GB, ich werde die Partitionsgröße angeben.

Geben Sie die Speichergröße an

In Ihrem Fall, wenn Sie einen 16-GB-Rechner haben, sollten Sie etwa 2 bis 2.5 GB für das Betriebssystem und andere Prozesse übrig lassen und alles andere für den Cache und den verbleibenden Speicher verbrauchen, die Hälfte davon sollte eine aktive Partition sein, die andere Hälfte davon ist für die Replik.

Wenn Sie Ihre Kapazitätsplanung durchführen, ist es wirklich wichtig, dass Sie genügend Speicher zuweisen, damit die Sitzungen im Falle von Sitzungen über genügend Speicher verfügen. Andernfalls wird der Cache als voll betrachtet, wenn der Cache den gesamten Speicher aufgebraucht hat. Dann passiert nur eines von zwei Dingen: Entweder lehnt der Cache alle neuen Einträge ab oder er entfernt einige der vorhandenen Einträge. NCache bietet Ihnen drei Algorithmen. Wissen Sie, das am häufigsten verwendete wird am wenigsten verwendet.

Geben Sie die Räumungsrichtlinie an

Damit NCache löscht sofort 5 % des Caches, wenn der Cache als voll gilt. Nachdem ich dies nun erstellt habe, füge ich einen Client-Knoten hinzu, in diesem Fall einen Demo-Client, und sage dann: „Cache starten“.

Client-Knoten hinzufügen

Wenn ich also den Cache starte, passiert viel hinter den Kulissen. Es entsteht ein neuer Cluster. Die Clustermitgliedschaft wird gebildet und an den Client weitergegeben. Damit der Kunde weiß, wie hoch die Clustermitgliedschaft ist? Was ist die Verbreitungskarte? Sobald das alles erledigt ist, ist alles in Ordnung. Jetzt spreche ich von Statistik. Ich möchte etwas PerfMon sehen. Und ich möchte schnell dieses Tool namens Stresstest-Tool ausführen, das schnell ausgeführt wird. Es testet schnell den Cache in Ihrer Umgebung.

Führen Sie das Stresstest-Tool aus

Auf diese Weise müssen Sie hierfür keine Programmierung vornehmen. So sieht der Cache aus. Sie werden so etwas installieren. Nehmen wir an, Sie installieren NCache. Es dauert nur so lange, einen 2-Knoten-Cluster mit konfiguriertem Anwendungsserver zu erhalten. In Ihrem Fall haben Sie natürlich mehr als einen Kunden. Die häufigste Konfiguration besteht aus etwa 5 bis 8 Clients und einem Cache-Cluster mit 2 bis 3 Knoten. Und wenn Sie dann mehr Clients hinzufügen, fügen Sie auch mehr Server hinzu.

Cache-Statistiken

Nachdem Sie nun diesen Cache ausgeführt haben, kehren wir zu unseren eigentlichen Themen zurück. Nun müssen Sie bei allem, was wir tun, im Hinterkopf behalten, wie wir diesen benannten Cache erstellt haben. Und ich habe Ihnen bereits den ASP.NET-spezifischen Sitzungsstatus gezeigt.

Übersicht über das Zwischenspeichern von Anwendungsdaten (API)

Kommen wir nun zum Anwendungsdaten-Caching, das den Kern meines heutigen Vortrags ausmacht. Im Falle des Zwischenspeicherns von Anwendungsdaten gibt es also eine API, die Sie programmieren müssen. Weil, ASP.NET core verfügt jetzt über eine Schnittstelle namens IDistributed Cache, die Sie als API aufrufen und hinter den Kulissen einen Drittanbieter-Cache anschließen können. Auf der Java-Seite gibt es standardmäßig eine sehr leistungsstarke API namens JCache, auf der .NET-Seite gibt es jedoch nichts. In den meisten Fällen müssen Sie also tatsächlich die eigentliche Cache-API selbst programmieren. Die API ist jedoch sehr einfach.

  • Cache-Verbindung
    ICache cache = CacheManager.GetCache("myCache");
    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");

Im Falle von NCache Wie Sie bemerken, sieht dies dem ASP.NET-Cache-Objekt sehr ähnlich. Was Sie also im Grunde tun, ist, einen Cache zu erstellen. Get, Sie erhalten das Objekt, wissen Sie, Cache-Punkte hinzufügen, einfügen, entfernen oder und es gibt auch asynchrone Versionen davon. Asynchron bedeutet, dass Sie nicht darauf warten müssen, dass der Cache aktualisiert wird, sondern einfach die Kontrolle zurückgeben und in diesem Fall einen Rückruf angeben können.

Lassen Sie mich Ihnen kurz zeigen, wie eine Bewerbung aussieht. Ich habe also diese sehr einfache Konsolenanwendung, die Folgendes verwendet: NCache.

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");
            ...

Als Erstes müssen Sie also sicherstellen, dass Sie auf die Cache-Assemblys verweisen, die ggf. vorhanden sind NCache sind zwei. Es gibt NCache.Laufzeit, NCache.Netz und dann müssen Sie die Namensräume verwenden, die im Fall von wiederum zwei sind NCache. NCache.Laufzeit, NCache.Web.Caching. Und dann am Anfang Ihrer Anwendung, die im Falle einer Konsole direkt dort steht. Im Falle einer ASP.NET-Anwendung ist dies wahrscheinlich Ihre global.asax. Sie müssen eine Verbindung zum Cache herstellen und hier kommt Ihr Cache-Name ins Spiel, egal wie Sie Ihren Cache benannt haben. Das ist es, was hier reinkommt. Und da Sie nun über ein Cache-Handle verfügen, können Sie mit der Anwendung fortfahren, Ihre Objekte erstellen und loslegen cache.Hinzufügen. Sie geben einen stringbasierten Schlüssel an und der Schlüssel muss eindeutig sein. Das ist übrigens kein guter Schlüssel. Ihr Schlüssel muss viel spezifischer sein und hier ist Ihr Objekt. Und ich meine, so kann man es später machen Cache.Get und Sie können Ihr Objekt aus dem Cache holen.

Nun, dieser Anruf, den Sie getätigt haben, führte tatsächlich zu einem Fall NCache, also, als du es getan hast cache.Hinzufügen, es ging im Grunde genommen von hier aus zu Ihrer Partition, in die die Daten eigentlich gehen sollten. Es wurde also zwischengespeichert. Fügen Sie es dort hinzu und diese Partition replizierte dann diese Daten auf ihre Replik. Wenn es sich um eine asynchrone Anwendung handelte, wurde nur diese Partition aktualisiert und die Kontrolle kam zurück. Wenn Sie einen asynchronen Aufruf durchgeführt haben, dann sogar diese Partition und Sie haben nicht einmal darauf gewartet, dass die Partition aktualisiert wird. Aber genau das cache.Hinzufügen Der Anruf führte dazu, dass all diese Arbeiten erledigt wurden.

Caching-Topologien

Und das Gleiche gilt, wenn Sie a Cache.Get Der Client geht direkt dorthin, wo sich die Daten befinden. Es verwendet also die darunter liegende Verteilungskarte, um zu wissen, wo sich die Daten befinden, geht direkt dorthin und ruft sie ab. Nehmen wir an, wenn Sie Artikel Nummer 3 möchten, würden Sie ihn sofort dort besorgen.

Dieser Code steckt also hinter den Kulissen, das ist es, was wirklich passiert. Zur Datenbank. Was ist dein. Es ist nur der Cache. Eigentlich werde ich auch gleich darüber sprechen. Sie haben die Daten also automatisch serialisiert/de-serialisiert? Ja, tatsächlich sogar noch mehr. Bevor die Daten also von hier nach hier gesendet werden, muss das Objekt serialisiert werden. Im Falle von NCache, NCache speichert es in serialisierter Form im Cache. Und wenn Sie einen Cache erstellen, kommt dieser zurück und wird dann im Client selbst deserialisiert. Und wenn Sie es bekommen, ist alles de-serialisiert. Die API sieht für Sie also sehr einfach aus, aber es wird noch viel Arbeit geleistet.

App-Daten-Caching-Funktionen

Was das Caching von Anwendungsdaten betrifft, war die größte Sorge doch, dass die Daten an zwei Orten vorhanden sind, oder? Und wenn ein Cache dieses Problem nicht berücksichtigt, wird sein Nutzen wirklich eingeschränkt. Wie geht ein Cache also mit diesem Problem um?

Absolute Ablauffristen

Nummer eins wird aufgerufen Abläufe und da ist die Absoluter Ablauf Das bedeutet, dass dieses Objekt, sagen wir, in 10 Minuten abläuft. Sie erstellen also für jedes Objekt eine fundierte Schätzung darüber, wie lange es sicher ist, dieses Objekt im Cache aufzubewahren. Und am Ende dieser Zeit entfernt der Cache dieses Objekt automatisch.

Lassen Sie mich Ihnen zeigen, wie das im Code aussieht. Also, im Falle von NCache Wenn Sie sich den gleichen Aufruf „cache.Add“ ansehen, ist das dritte Argument ein Datum-Uhrzeit-Argument, das den Wert einer Minute in der Zukunft hat.

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");
        ...

Im Grunde bedeutet es also, dass der Cache dieses Objekt in einer Minute ablaufen lässt. Es spielt keine Rolle, ob Sie es benötigen oder nicht, nach einer Minute wird das Objekt aus dem Cache entfernt. Warum? Weil Sie sich nicht wohl dabei fühlen, es länger als eine Minute im Cache zu lassen. Und warum fühlst du dich nicht wohl? Weil Sie glauben, dass sich etwas in der Datenbank ändern wird. Es ist nicht sicher, es im Cache aufzubewahren.

Gleitende Ablauffristen

Es gibt eine andere Art von Ablauf, die als „Ablauf“ bezeichnet wird Gleitender Ablauf, was einem völlig anderen Zweck dient. Es dient nicht dazu, den Cache frisch zu halten, sondern eher zur Bereinigung. So können Sie z.B. bei Sitzungen NCache verwendet einen gleitenden Ablauf, der im Wesentlichen besagt, dass Sie ein Intervall angeben und beispielsweise 10 Minuten, 20 Minuten, 5 Minuten sagen. Also so lange, bis niemand das Objekt berührt NCache Entfernt das Element aus dem Cache.

Der gleitende Ablauf hat also zwar immer noch den Namen „Ablauf“, dient aber einem völlig anderen Zweck. Es handelt sich um den absoluten Ablauf, den Sie für das Zwischenspeichern von Anwendungsdaten benötigen, um den Cache aktuell zu halten. Fast jeder Cache hat das absolute Ablaufdatum. Einschließlich Redis, jeder hat es.

Cache mit Datenbank synchronisieren

Das Problem mit dem absoluten Ablauf besteht jedoch darin, dass Sie nur eine Vermutung anstellen. Was passiert, wenn diese Vermutung falsch ist und sich die Daten in der Datenbank tatsächlich ändern? Was passiert dann? Wir müssen einen Mechanismus finden. Also, wissen Sie, wenn Sie die Fähigkeit dazu haben Synchronisieren Sie den Cache mit der Datenbank Hier können Sie den Cache anweisen, die Datenbank auf Änderungen für diesen ganz bestimmten Datensatz zu überwachen, was auch immer das ist.

NCacheverwendet beispielsweise diese ADO.NET SQL-Cache-Abhängigkeitsfunktion. Wo, wenn Sie angeben, wenn Sie diese Funktion verwenden, möchte ich Ihnen zeigen, wie sie verwendet wird. Wenn Sie diese Funktion nutzen, dann NCache überwacht die Datenbank und bittet die Datenbank um eine Benachrichtigung NCache wenn sich diese Daten ändern. Nehmen wir also an, ich habe das SQL-Abhängigkeitsbeispiel. Also mache ich noch einmal den gleichen Cache.Add, hier. Also mache ich den gleichen Cache.Add. Ich habe einen Schlüssel. Anstelle des Objekts habe ich jetzt ein Cache-Element, eine Struktur, die das eigentliche Objekt und einige andere Dinge enthält. So enthält es beispielsweise eine SQL-Anweisung einer einzelnen Zeile in der Produkttabelle. Da ich ein Produkt in einer Northwind-Datenbank zwischenspeichere, ist diese SQL-Anweisung: NCache dann benutze es.

private static void AddProductToCacheWithDependency(Product product)
    {
        // Any change to the resultset 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.Id);

        // 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);
    }

Also gibt es eine SQLCacheDependency Klasse in NCache Das ist unsere eigene Klasse, aber hinter den Kulissen wird sie dann der ADO.NET SQL-Cache-Abhängigkeit zugeordnet. Wenn Sie diesen Anruf nun tatsächlich tätigen, müssen Sie, wenn Sie den Anruf tätigen, hier anrufen. Und dieser Aufruf geht an die Cache-Server und der Cache-Server führt nun den ADO.NET-Aufruf für Ihre SQL Server-Datenbank durch. Und jetzt wird der Cache-Server zum Client Ihrer Datenbank. Und es teilt der Datenbank mit, dass Sie mich bitte benachrichtigen sollten, wenn sich dieser Datensatz ändert.

Verteilte Cache-Bereitstellung (NCache)

Und der SQL Server verfügt über eine Art Oracle-Datenbankbenachrichtigungsmechanismus. Zumindest für diese beiden Datenbanken können Sie diese Funktion nutzen. Und mit der SQL-Cache-Abhängigkeit können Sie im Wesentlichen sicherstellen, dass Ihre Daten auch dann mit der Datenbank konsistent bleiben, wenn Sie es nicht erraten können.

Haben Sie Fragen dazu? Sie haben also alle Framework-Komponenten. Also, NCache hat auch ein Plugin für EF, EF6 und jetzt auch EF Core, bis hin zu EF Core. Vor EF Core verfügte EF nicht wirklich über eine steckbare Architektur. Daher mussten wir einen benutzerdefinierten ADO.NET-Anbieter implementieren und SQL-Abfragen zwischenspeichern.

SQL Core ist eine viel flexiblere Architektur. Jetzt sind wir in der Lage, einen L2-Cache bereitzustellen. NHibernate gibt es schon seit langer Zeit. NHibernate verfügt schon seit sehr langer Zeit über diese Architektur. NCache stellte den L2-Cache für NHibernate und auch für Hibernate für den Java-Client bereit. Aber jetzt verfügt EF Core über diese Architektur. Der Vorteil von EF Core besteht also darin, dass Sie diese Aufrufe nicht tätigen müssen. Der Nachteil ist natürlich, dass es sich im Hinblick auf die Funktionen nur um eine sehr kleine Teilmenge des Caches handelt, den Sie verwenden. Denn all diese anderen Dinge, zum Beispiel der SQL-Abhängigkeitsteil, sind etwas, das NCache bietet und Sie können dies über die Konfigurationsdateien konfigurieren, aber auch viele andere Funktionen, über die ich sprechen werde und die Sie verwenden müssen. Wenn Sie nur eine steckbare Architektur durchlaufen, müssen sie den Ansatz des kleinsten gemeinsamen Nenners durchgehen. Daher kann ihre API, unabhängig davon, welche sie verwenden, viele der anspruchsvollen Funktionen nicht nutzen, aber jetzt stellen sie alle Caches bereit. Sie müssen also für alle flexibel sein. Wenn Sie hingegen beispielsweise davon profitieren möchten, verfügen auf der Java-Seite fast alle Caches über alle diese Funktionen, über die ich spreche. Auf der .NET-Seite hat fast keiner von ihnen etwas anderes als NCache. Es ist also nicht wirklich ein NCacheDie Sache ist die Tatsache, dass .NET bei der Verwendung dieser Best Practices noch nicht so weit fortgeschritten oder ausgereift ist wie die Java-Community. Es werden also immer mehr. Die Tatsache, dass jetzt .NET Core eine so große Veränderung durchgemacht hat, ist ein ziemlich guter Hinweis darauf, wie sich die Dinge verbessern werden.

Wenn Sie den Cache jedoch mit den Datenbankabläufen synchron halten möchten, ist dies derzeit nicht ausreichend. Sie müssen über die Ablauffristen hinausgehen. Sie müssen den Cache mit der Datenbank synchronisieren. Und wenn die Datenbank keine Benachrichtigungen unterstützt, können Sie auf den Polling-Ansatz zurückgreifen, der etwas ist NCache umgesetzt hat.

Es gibt einen dritten Ansatz, bei dem Sie eine gespeicherte CLR-Prozedur verwenden können, um die Daten aus der Datenbank direkt zum Cache hinzuzufügen. So, als würden Sie das ganze Paradigma umkehren. Jetzt speist die Datenbank den Cache. Sie wissen also zum Beispiel, dass Sie einen Auslöser haben, der … Ich werde es beschleunigen, sonst schaffe ich es nicht, alle Themen zu Ende zu bringen. Dies ist also eine sehr wichtige Funktion, ohne die Sie wirklich keinen Nutzen haben und den Cache auch mit nicht relationalen Datenquellen synchronisieren können. Zum Beispiel im Falle von NCache Es gibt eine benutzerdefinierte Abhängigkeitsfunktion, bei der es sich um Ihren Code handelt, der Anrufe tätigen kann. Nehmen wir an, Ihre Datenquelle ist eine Cloud und es handelt sich um eine Webmethode, die jedes Mal aufgerufen wird, um tatsächlich zu wissen, um welche Daten es sich handelt. Dann funktioniert nichts davon und diese benutzerdefinierte Abhängigkeit funktioniert. Bei einer benutzerdefinierten Abhängigkeit handelt es sich also um Ihren Code, der im Cache gespeichert ist und vom Cache aufgerufen wird, um die Datenquelle zu überprüfen.

Sobald Sie dieses Ziel erreicht haben, können Sie damit beginnen, immer mehr Daten zwischenzuspeichern und wirklich davon zu profitieren. DB-Abhängigkeit, da ich gerade mit dem Mainframe arbeite, funktionieren SQL-Abhängigkeit oder Oracle-Abhängigkeit nicht. Wie oft sollte eine Abfrage stattfinden, denn ich arbeite mit Produktionsdaten mit mehreren Millionen Datensatztransaktionen, die in einer Minute durchgeführt werden. Also, wie oft. Woher wissen Sie also, wie oft Sie Umfragen durchführen? Die Abfrage ist ein konfigurierbares Intervall und es ist Ihr Code, der aufgerufen wird. Sie legen also bei jeder Umfrage fest, wie viele Daten Sie sich ansehen möchten. Denn im Falle einer benutzerdefinierten Abhängigkeit prüfen Sie tatsächlich einen bestimmten Schlüssel und prüfen, ob dieser Schlüssel in Ihrem alten Mainframe aktualisiert wurde oder nicht. Es gilt also im Grunde für jeden Schlüssel, wenn es so aussieht: „Überprüfe diesen Schlüssel, überprüfe diesen Schlüssel“. Im Falle einer benutzerdefinierten Abhängigkeit. Im Falle einer DB-Abhängigkeit handelt es sich nicht um einen einzelnen Schlüssel, sondern um den gesamten Datensatz und wir haben eine weitere Funktion darin NCache namens Daten-Updater. Es gibt einen Cache-Loader, einen Cache-Updater, einen weiteren Dienst, in dem sich Ihr Code befindet. Es gibt also eine Funktion namens Cache Loader NCache, wobei ich hier nicht all diese Funktionen erwähnt habe, aber es gibt eine Funktion namens Cache Loader, bei der es sich um Ihren Code handelt, der beim Starten des Caches den Cache laden und den Cache von Ihrer Datenquelle vorladen kann. Das könnte also Ihr Mainframe sein. Es gibt aber auch eine Funktion namens Cache Updater, die Ihren Code automatisch in jedem konfigurierbaren Intervall aufruft. Dieser Code kann dann die gesamte Datenquelle überprüfen und nach Aktualisierungen suchen, die auf Ihrer benutzerdefinierten Logik und den geänderten Daten oder den neuen Daten basieren aufgetreten ist oder welche Daten auch immer gelöscht wurden, können Sie auch den Cache aktualisieren. Der Cache bleibt also mit Ihrer Datenquelle synchronisiert. Standardmäßig werden diese im Abstand von etwa 15 Sekunden aufgerufen. Aber es kann schneller gehen. Es kann häufiger oder weniger häufig vorkommen, je nach Ihren Bedürfnissen. Habe ich deine Frage beantwortet? Ich habe mehr, aber das überspringe ich. Darüber können wir später reden.

Durchlesen und Durchschreiben

Sobald Sie dieses Ziel erreicht haben, werden Sie beginnen, immer mehr Daten zwischenzuspeichern. Dann ist die nächste Frage: Okay, welche weiteren Vorteile können Sie jetzt erzielen? Das nächstwichtigste ist das durchlesen, durchschreiben. Was ist Durchlesen? Es ist wiederum Ihr Code, der auf dem Cache-Server liegt. Wenn Sie also einen Cache.Get ausführen, ist beispielsweise ein Durchlesen Ihr Code NCache Sie implementieren diese aufgerufene Schnittstelle IReadThruProvider. Es gibt drei Methoden.

...
// Perform tasks like allocating resources or acquiring connections
public void Init(IDictionary parameters, string cacheId)
{
    object connString = parameters["connstring"];
    sqlDatasource = new SqlDatasource();
    sqlDatasource.Connect(connString == null ? "" : connString.ToString());
}

// Perform tasks associated with freeing, releasing, or resetting resources.
public void Dispose()
{
    sqlDatasource.DisConnect();
}

// Responsible for loading an object from the external data source.
public ProviderCacheItem LoadFromSource (string key)
{
    ProviderCacheItem cacheItem = new ProviderCacheItem(sqlDatasource.LoadCustomer(key));
    cacheItem.ResyncOptions.ResyncOnExpiration = true;
    // Resync provider name will be picked from default provider.
    return cacheItem;
}
...

Es gibt einen Init, der aufgerufen wird, wenn der Cache gestartet wird, und verworfen wird, wenn der Cache stoppt, aber das Wichtigste ist dieser Ladevorgang. Die Last wird also als „durchgehen“ bezeichnet. Der Cache ruft Sie also diese Methode auf. NCache ruft diese Methode auf und übergibt Ihren Schlüssel. Und basierend auf diesem Schlüssel gehen Sie zu Ihrer Datenbank und rufen das Element ab. Wenn Sie das also jetzt tun, ist der Nettoeffekt für den Client, die Anwendung, jedes Mal, wenn Sie etwas tun Cache.Get, der Cache hat immer die Daten. Wenn Sie nicht möchten, dass die Read-Thru-Funktion aufgerufen wird, können Sie dies natürlich auch tun, indem Sie Einzelheiten festlegen. Der Cache enthält jedoch immer die Daten. Das ist also ein Vorteil. Sie konsolidieren also Ihre Persistenzschicht in einer Caching-Ebene. Wenn Sie also über mehrere Anwendungen verfügen, die dieselbe Caching-Ebene verwenden, werden die Anwendungen einfacher, da sie nicht denselben Persistenzcode beibehalten müssen. Sie machen einfach eine Cache.Get und sie erhalten das Domänenobjekt oder das Entitätsobjekt aus dem Cache. Der Cache sieht jetzt also viel mehr wie ein EF aus. Das Durchlesen selbst kann EF-basiert sein.

Das andere, was Sie mit dem Durchlesen machen können, ist, dass Sie es mit Abläufen und Datenbanksynchronisierung kombinieren können. Wenn also diese beiden Dinge passieren, sollten Sie die Daten nicht neu laden, anstatt sie aus dem Cache zu entfernen. Denn wenn Sie es entfernen, muss die Anwendung es beim nächsten Mal ohnehin neu laden. Und in vielen Fällen werden diese Daten sehr, sehr häufig verwendet. Sie möchten es also wirklich wieder in den Cache laden. Ein Durchlesen konsolidiert also nicht nur den Code, sondern verbessert auch Ihre Leistung, da Ihre Datenbank nicht beeinträchtigt wird. In vielen E-Commerce-Situationen wird möglicherweise so häufig auf dieselben Daten zugegriffen, dass, sobald Sie sie aus dem Cache entfernen, Tausende von Anfragen für dieselben Daten in die Datenbank gelangen, und wir haben gesehen, dass sich Kunden darüber beschwert haben. Das passiert so häufig, weil es Millionen von Datenelementen gibt, da jedes Datenelement abläuft und die Datenbank betroffen ist. Insgesamt sahen sie also, selbst nachdem sie den Cache hatten, viele Treffer in der Datenbank. Die Antwort darauf war also „Neu laden“ statt „Ablaufen“. Das Neuladen bedeutet also, dass die Daten den Cache nie verlassen, sondern nur aktualisiert werden. Die Datenbank wird also nie berührt, außer durch einen Datenbankaufruf, den der Cache durchführt. Daher ist das Durchlesen in dieser Hinsicht sehr wichtig.

Das andere ist das Durchschreiben, das genau wie das Durchlesen funktioniert, außer dass es das Schreiben übernimmt. Und das Schreiben bedeutet, dass es entweder hinzugefügt, aktualisiert oder gelöscht werden kann. Jetzt verfügt das Schreiben über eine weitere Funktion. Ein Vorteil des Durchschreibens ist derselbe wie beim Durchlesen, nämlich der Konsolidierung des Codes.

Hinterschreiben

Der zweite Vorteil heißt Write-Behind. Wissen Sie, Datenbankaktualisierungen sind ebenso wie Datenbanklesevorgänge nicht schnell. Datenbankaktualisierungen sind ebenfalls nicht schnell. Wenn Ihre Daten also nicht so vertraulich sind und Sie nicht auf die Aktualisierung der Datenbank warten müssen, können Sie einfach den Cache aktualisieren. Dadurch verfügen nun alle Anwendungsinstanzen über dieselben Daten und der Cache aktualisiert die Daten asynchron in der Datenbank. Und plötzlich verbessert sich die Leistung Ihrer Anwendung, da Sie nicht auf die Aktualisierung des Caches warten müssen. Write-behind hat also diesen zusätzlichen Vorteil. Es baut also die Warteschlange auf. Im Falle von NCache Diese Warteschlange wird auf mehrere Server repliziert, aber auch hier ist das Lesen durch Schreiben eine sehr wichtige Funktion. Und dabei handelt es sich auch um Ihren Code, der auf dem Cache-Server gespeichert ist.

Ich möchte, dass Sie dies im Hinterkopf behalten, all diesen Cache-Loader, den Updater, die benutzerdefinierten Abhängigkeiten, das Durchlesen, Durchschreiben, all den Servercode, der darauf lebt. Das ist etwas, das … wiederum diese Funktionen gibt es auch auf der Java-Seite. Es ist also nicht nur etwas NCache erfunden, aber Sie werden diese Funktionen in keinem der anderen .NET-Basiscaches erhalten.

Wenn Sie also erst einmal angefangen haben, sobald Sie das alles haben, sobald Sie dies getan haben, legen Sie jetzt eine Menge Daten in den Cache. Es fängt wirklich an, davon zu profitieren. Und wenn es sich bei einem Cache nur um einen Schlüsselwertzugriff handelt, ist das nicht sehr, sehr benutzerfreundlich. Daher muss ein Cache benutzerfreundliche Möglichkeiten zum Abrufen von Daten bieten.

Datengruppierung

Also, im Falle von NCache Es gibt eine Menge Daten, die Sie nutzen können Gruppe und Untergruppe, Tags, Namensschilder. Sie können auch basierend auf SQL oder LINQ suchen. Sie können also etwas tun wie: „WÄHLEN SIE KUNDEN AUS, WO KUNDE.STADT = NEW YORK'. Und plötzlich können Sie viele Ihrer Datensätze, insbesondere die Referenzdaten, die Sie immer wieder auf gefilterte Weise lesen müssen, direkt aus dem Cache abrufen. Und jetzt haben Sie den Vorteil, dass die Daten, die Sie benötigen, verarbeitet werden.

Beachten Sie Folgendes: Bei jeder SQL-Suche muss der gesamte Datensatz im Cache vorhanden sein. Denn dies wird nicht in die Datenbank aufgenommen. Es wird also nur der Cache durchsucht. Nehmen wir an, wenn Sie sagen, geben Sie mir alle Kunden mit Sitz in New York. Wenn nicht alle Kunden im Cache sind, wenn nicht alle New Yorker Kunden im Cache sind NCache oder ein Cache gibt Ihnen nicht den richtigen Datensatz zurück. Das ist also eine wichtige Sache, die man im Hinterkopf behalten sollte, denn die Leute verwechseln das oft, wenn ich suche, wenn ich erwarte, wenn es nicht im Cache ist, holen wir es aus der Datenbank. Aber die SQL-Abfragen sind nicht die Datenbank-SQL-Abfragen. Dies sind Cache-eigene Abfragen.

Da es sich nun um viele Daten handelt, können Sie den gesamten Datensatz im Cache behalten, insbesondere Referenzdaten, und dort würden Sie diese verwenden. Aber zumindest innerhalb der Transaktionsdaten gibt es auch Teilmengen, die vollständig im Cache gehalten werden können. So wartet man also. Wenn Sie also all das im Hinterkopf behalten, beginnen Sie jetzt, vom Cache zu profitieren.

Client-Cache

Ich werde noch auf eine weitere Sache eingehen, nämlich den Namen dieser Funktion Client-Cache. Eines der Dinge, die die Leute wirklich schockieren, wenn sie beginnen, einen verteilten Cache zu verwenden, ist, dass ihre Leistung tatsächlich sinkt, insbesondere wenn sie vorher einen In-Proc-Cache verwendet haben, der Standalone ist. Viele Kunden rufen uns also an und sagen: Sie haben das gesagt, die Leistung wird steigen, die Skalierbarkeit wird sich verbessern, unsere Leistung ist tatsächlich gesunken. Der Grund dafür ist, dass es ursprünglich nur einen eigenständigen Cache gab. Die Größe war begrenzt, aber der Cache lag in Objektform vor, die Objekte wurden auf Ihrem Heap gespeichert und müssen jetzt in einen Cache-Cluster verschoben werden. Es gibt eine Serialisierung, eine Deserialisierung, es gab einen Netzwerkfehler, es ist viel langsamer.

Client-Cache

Um dieses Problem zu beheben, viele der Caches, verwende ich wiederum das Wort „viele“, weil alle Java-seitigen Caches es haben, die .NET-Seite NCache hat es. Sie verfügen über diese Funktion namens Client-Cache. Auf der Java-Seite heißt es Near Cache. Dies ist derselbe eigenständige Cache, den Sie zuvor hatten. Gleich bedeutet ähnlich, aber jetzt ist ihm bewusst, dass er Teil dieses Cluster-Cache ist. Welche Daten auch immer gespeichert werden, sie werden mit dem Cache-Cluster synchronisiert. Es lässt sich also einfach einstecken, ohne dass Sie etwas programmieren müssen.

Mit Hilfe eines Client-Cache können Sie also die In-Proc-Standalone-Cache-Leistung erreichen, und das ist wirklich gut für viele Daten, bei denen Sie viel mehr lesen als schreiben. Sie möchten dies nicht für so etwas wie Sitzungen verwenden. Denn in den Sitzungen lesen Sie einmal und schreiben einmal. Sie müssen also viel mehr lesen als schreiben, um davon zu profitieren.

Dynamischer Cache-Cluster

Aus architektonischer Sicht müssen Sie also sehen, dass der Cache jetzt wie die Datenbank ist. Es befindet sich in Ihrem Rechenzentrum, Ihrer Produktionsumgebung und wenn Ihre Anwendung einen hohen Verfügbarkeitsbedarf hat, muss auch der Cache hochverfügbar sein, sonst haben Sie ein Problem. Und das geht nur, wenn der Cache eine 100-prozentige Verfügbarkeit gewährleistet. Also ein guter Cache für den Fall NCache es hat ein dynamischer Cache-Cluster. Es handelt sich um eine Peer-to-Peer-Architektur. Sie können jeden Server hinzufügen oder entfernen und alles ist in Ordnung, nichts stoppt. Der Cache stoppt nicht, die Anwendung stoppt nicht.

Dynamischer Cache-Cluster

Lineare Skalierbarkeit mit Replikation

Also haben wir über die Partition gesprochen und dann Topologien bereits. Die Replikation muss intelligent erfolgen. Im Falle einer Partitionsreplikation wird also nur eine Kopie erstellt. Die Daten sind also nur an zwei Stellen und nicht an mehr als zwei vorhanden, da jedes Mal, wenn Sie Kopien erstellen, mehr Zeit und Mühe kostet. Es verlangsamt die Dinge.

Caching-Topologien

WAN-Replikation des verteilten Caches

Es gibt auch eine Funktion namens WAN-Replikation. Viele Menschen verfügen mittlerweile über mehrere Rechenzentren. Wenn Sie erwarten, dass Ihre Datenbank mehrere Rechenzentren verwalten kann, warum nicht der Cache? Dies ist eine Funktion, über die die meisten Java-Caches verfügen. NCache hat es auch, aber nur auf der .NET-Seite.

WAN-Replikation des verteilten Caches

NCache vs Redis

Noch kurz eine letzte Sache, denn auf der .NET-Seite gibt es, wie Sie wissen, eigentlich nur zwei Optionen. Einer ist NCacheist einer Redis. Redis Eigentlich handelt es sich eher um einen Linux-basierten Cache, aber seit Microsoft mit ihnen auf Azure zusammengearbeitet hat, sind sie, wie Sie wissen, sicherlich viel beliebter geworden. Deshalb wollte ich einen fairen Vergleich anstellen.

Übrigens, wenn Sie einfach auf unsere Website gehen und auf die gehen Vergleichsseite und geh zu detaillierter Feature-für-Feature-Vergleich Basierend auf ihrer Dokumentation und unserer Dokumentation und sehen Sie sich alles an. Und das ist kein, wissen Sie, wir reden überhaupt nicht darüber, und Sie können das selbst gut beurteilen. Es dient nur dazu, die Vorbereitung Ihrer Arbeit zu erleichtern.

Aber sie sind beide Open Source, aber NCache ist natives .NET für .NET-Leute, wissen Sie, Ihr gesamter Stack ist .NET. NCache ermöglicht es Ihnen, .NET-Code auf der Serverseite zu haben, mit dem Sie nicht umgehen können Redis. Und wissen Sie, wenn Sie Azure verwenden, Redis ist nur als Cache-as-a-Service verfügbar, wobei wir uns bewusst nicht für dieses Modell entschieden haben. Denn bei Cache as a Service ist der Cache eine Blackbox. Sie verfügen also nicht über die serverseitigen Funktionen, über die wir gerade gesprochen haben. Und mit dem VM-Modell haben Sie die volle Kontrolle.

Redis vs NCache - Vergleich der Funktionsebenen für .NET-Anwendungen

Die meisten unserer Kunden sind High-End-Unternehmen, die ihre Kontrolle wirklich nicht aus der Hand geben wollen. Es ist wie eine SQL-Datenbank im Vergleich zu einem SQL-Server. Also, mit NCacheWissen Sie, Sie kontrollieren Ihre gesamte Umgebung, und wie Sie gesehen haben, ist dies ziemlich einfach. Aber Sie erhalten alle diese serverseitigen Funktionen mit NCache, was Sie nicht tun, weil mit Redis weil du keinen Zugriff hast.

Redis vs NCache - Cloud-Unterstützung

Machen Sie sich also erneut eine eigene Meinung, verwenden Sie jedoch zumindest einen verteilten Cache in Ihrer Architektur. Stellen Sie sicher, dass es skalierbar ist. Das ist das ganze Ziel. Vielen Dank.

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.