Skalierung .NET Core Apps für extreme Leistung

 

Einleitung

.NET Core und ASP.NET Core erfreuen sich aufgrund ihres einfachen Designs, ihres geringen Gewichts, ihrer Open Source-Qualität und ihrer Lauffähigkeit sowohl unter Windows als auch unter Linux zunehmender Beliebtheit. Dadurch werden auch viele bestehende Anwendungen verschoben .NET Core von dem .NET Framework. Fast alle neuen Anwendungen werden in entwickelt .NET Core.

Viele davon .NET Core Anwendungen sind von Natur aus stark frequentiert und bedienen Millionen von Benutzern und Transaktionen. Daher haben diese Anwendungen einen enormen Einfluss auf Ihr Unternehmen und sind daher sehr wichtig.

 

Wer braucht Skalierbarkeit?

Das .NET Core Anwendungen, die normalerweise Skalierbarkeit erfordern, sind Serveranwendungen, die viele Transaktionen sehr schnell und mit sehr kurzen Antwortzeiten verarbeiten müssen. Viele dieser Anwendungen sind kundenorientiert, das heißt, sie verarbeiten Kundenanfragen. Wenn sie Kundenanfragen nicht schnell erfüllen, sind die Kosten für das Unternehmen in Form von Umsatzeinbußen und dem Verlust zufriedener Kunden hoch.

folgende .NET Core Anwendungen erfordern Skalierbarkeit:

  1. Web-Apps (ASP.NET Core): Hierbei handelt es sich in der Regel um kundenorientierte Anwendungen, bei großen Unternehmen kann es sich jedoch auch um interne Anwendungen handeln.
  2. Webdienste (ASP.NET Core): Dabei kann es sich entweder um die direkte Bereitstellung von Web-APIs für Kunden handeln oder um Teil einer anderen Anwendung mit hohem Transaktionsaufwand, die Anwendungsebenenlogik in diesen Webdiensten enthält.
  3. Echtzeit-Web-Apps (ASP.NET Core SignalR): Hierbei handelt es sich um Echtzeitanwendungen, die ihren Benutzern mithilfe von ASP häufige Aktualisierungen ermöglichen müssen.NET CoreSignalR-Framework. Sie müssen außerdem schnell arbeiten, da sie in der Regel im Kundenkontakt stehen.
  4. Mikrodienste (.NET Core): Dabei handelt es sich um eine neue Anwendungsarchitektur für serverseitige Anwendungen. Und genau wie Webservices sind diese Microservices normalerweise Teil einer kundenorientierten Webanwendung oder einer kundenorientierten Webservices-Anwendung. Daher stellen sie auch bei hoher Transaktionslast hohe Leistungsanforderungen.
  5. Andere Server-Apps (.NET Core): Es gibt eine Vielzahl anderer Serveranwendungen, die eine große Menge an Transaktionen sehr schnell verarbeiten müssen. Dies können Stapelverarbeitungsanwendungen sein, die verschiedene Arten von Backend-Workflows verarbeiten, oder Stream-Verarbeitungsanwendungen, die große Datenmengen für die Verarbeitung nahezu in Echtzeit erfassen. Die Liste geht weiter.
 

Das Problem: Skalierbarkeitsengpässe

Interessanterweise verfügen alle oben genannten Anwendungen über sehr skalierbare Architekturen auf Anwendungsebene. Jeder von ihnen ermöglicht Ihnen eine lineare Skalierung, wenn Ihre Transaktionslast wächst, indem Sie weitere Server, VMs oder Containerinstanzen zusammen mit einem Load Balancer hinzufügen.

Doch trotz einer sehr skalierbaren Architektur auf der Anwendungsebene .NET Core Serveranwendungen sind heute mit großen Skalierbarkeitsengpässen konfrontiert. Diese Engpässe treten in verschiedenen Bereichen auf, wie zum Beispiel:

  1. Anwendungsdatenbanken (relationale Datenbanken): Das ist der größte Engpass überhaupt. Ich erkläre es weiter unten genauer.
  2. ASP.NET Core Sitzungsspeicher: Wenn Sitzungen in SQL Server gespeichert sind, dann Ihr ASP.NET Core Die Anwendung wird mit großen Engpässen konfrontiert sein.
  3. ASP.NET Core Wiederholte Seitenverarbeitung: Wenn dieselben Seiten wiederholt ausgeführt werden und ihre Ausgabe oder Antwort gleich bleibt, handelt es sich um eine Verschwendung von Ressourcen und einen Leistungsengpass.
  4. ASP.NET Core SignalR Backplane Provider: Wenn eine Live-Webanwendung, die SignalR verwendet, skaliert werden muss, kann der Backplane-Anbieter leicht zu einem Engpass werden.
  5. Pub/Sub-Nachrichten (nicht im Speicher): Wenn dein .NET Core Wenn die Anwendung Pub/Sub-Messaging verwendet, handelt es sich wahrscheinlich nicht um In-Memory und daher um einen Engpass.
ASP.NET Core Leistungsengpässe
Abbildung 1: ASP.NET Core App mit Skalierbarkeitsengpässen konfrontiert
 

Engpass bei relationalen Datenbanken

Der größte Engpass für alle mit hohem Verkehrsaufkommen .NET Core Anwendungen ist ihre Anwendungsdatenbank. Die meisten Anwendungen nutzen heute noch eine relationale Datenbank wie SQL Server oder Oracle. Diese Datenbanken werden schnell zu Skalierbarkeitsengpässen, wenn Sie die Transaktionslast dieser Anwendungen erhöhen. Dies gilt unabhängig davon, ob Sie SQL Server auf einer VM oder einer Azure SQL-Datenbank verwenden.

Dies liegt daran, dass eine relationale Datenbank nicht wie eine logisch partitioniert werden kann NoSQL database und bleibt stattdessen an einem physischen Ort; Selbst eine gewisse Partitionierung auf Spaltenebene ist nichts anderes als eine echte NoSQL Stilpartition. Daher können Sie die Transaktionskapazität der Datenbankebene nicht durch das Hinzufügen weiterer Datenbankserver erhöhen, wie dies bei einem der Fall ist NoSQL database.

Während Ihre Anwendungsschicht beispielsweise problemlos 10, 20, 30 oder mehr Anwendungsserver umfassen kann, wenn Ihre Transaktionslast zunimmt, kann Ihre Datenbankschicht überhaupt nicht in der gleichen Weise wachsen.

Aus all diesen Gründen wird Ihre relationale Datenbank zu einem Leistungsengpass für alle darin gespeicherten Daten (Anwendungsdaten oder andere Daten).

 

Die In-Memory-Optimierungen des Datenbankservers reichen nicht aus

SQL Server hat In-Memory-Optimierungen eingeführt, um die Anzahl der Transaktionen pro Sekunde zu erhöhen. Oracle hat auch eine eigene Version von In-Memory-Tabellen bereitgestellt.

Während In-Memory-Optimierungen zu Leistungsverbesserungen führen, lösen sie nicht das Kernproblem der linearen Skalierbarkeit. In-Memory-Tabellen werden im Allgemeinen für schreibgeschützte Daten verwendet. Um eine schreibgeschützte Transaktionskapazität zu skalieren, müssen Sie auf High-End-Computern weitere Instanzen von SQL Server hinzufügen.

Auch für In-Memory-Tabellen gelten Einschränkungen hinsichtlich der Datengröße. Sie können keine großen Tabellen im Speicher ablegen, da die gesamte Tabelle im Speicher abgelegt werden muss. Und ihre Replikation auf andere SQL Server-Instanzen kann nur auf andere In-Memory-Tabellen und nicht auf eine richtige Datenbank erfolgen.

Zusammenfassend lässt sich sagen, dass diese In-Memory-Optimierungen in SQL Server- und Oracle-Datenbanken nicht in der Lage sind, Ihre Probleme vollständig zu lösen .NET Core Skalierbarkeitsanforderungen der Anwendung.

 

NoSQL Database Nicht die Antwort

Einer der Gründe NoSQL databases sind populär geworden, weil sie eine ordnungsgemäße Partitionierung von Daten basierend auf Hash-basierten und anderen Algorithmen ermöglichen. Dies löst viele der Probleme der Skalierbarkeit der Transaktionskapazität, mit denen relationale Datenbanken wie SQL Server und Oracle konfrontiert sind.

Aber es gibt Gründe NoSQL databases sind nicht die ideale Lösung für diese Datenbankengpässe.

  1. Kein In-Memory-Store: NoSQL databases speichern ihre Daten auf der Festplatte, genau wie eine relationale Datenbank. Dies bedeutet, dass die langsame Leistung der Festplatte letztendlich zu einem Leistungsengpass wird, egal was Sie tun.
  2. Kann die meiste Zeit nicht verwendet werden: NoSQL databases erfordern, dass Sie auf die Verwendung relationaler Datenbanken wie SQL Server und Oracle verzichten und diese durch eine ersetzen NoSQL database. Dies ist in den meisten Fällen sowohl aus technischen als auch nichttechnischen Gründen nicht möglich. Im Wesentlichen ist Ihr Unternehmen von Ihrer relationalen Datenbank abhängig und kann nicht einfach darauf verzichten. Infolgedessen können Sie a nicht in vollem Umfang nutzen NoSQL database.
 

Die Lösung: Verteilter In-Memory-Cache (NCache)

Die Lösung für alle oben genannten Probleme ist die Verwendung eines In-Memory Distributed Cache wie NCache in Ihrem .NET Core Anwendungsbereitstellung. NCache ist ein verteilter Open-Source-Cache für .NET und .NET Core Das ist extrem schnell und linear skalierbar. Stellen Sie sich das als einen In-Memory-Datenspeicher vor, der ebenfalls verteilt ist. Durch die In-Memory-Speicherung ist es extrem schnell und durch die Verteilung linear skalierbar.

NCache ist linear skalierbar, da es einen TCP-Cluster kostengünstiger Cache-Server aufbaut (gleiche Konfiguration wie Ihre Web-App-Server, aber mit mehr Speicher) und die Speicher- und CPU-Ressourcen aller dieser Server in einer logischen Kapazität zusammenfasst. NCache Anschließend können Sie diesem Cluster zur Laufzeit Cache-Server hinzufügen, wenn Ihre Transaktionslast zunimmt. Und da NCache ist vollständig speicherintern, superschnell und bietet Reaktionszeiten von weniger als einer Millisekunde, die Sie von Ihren relationalen Datenbanken oder gar nicht erwarten können NoSQL databases.

Zusätzlich zur Bereitstellung linearer Skalierbarkeit bietet ein verteilter Cache z NCache repliziert Daten intelligent, sodass Ihre Leistung nicht beeinträchtigt wird und gleichzeitig Datenzuverlässigkeit gewährleistet wird, falls ein Cache-Server ausfällt.

NCache Im Unternehmen bereitgestellt für .NET Core
Abbildung 2: NCache Im Unternehmen bereitgestellt für .NET Core

NCache ermöglicht Ihnen die Skalierung Ihrer .NET Core Bewerbungen über Folgendes:

  • Zwischenspeichern von Anwendungsdaten
  • ASP.NET Core Sitzungsspeicher
  • ASP.NET Core Antwort-Cache-Middleware
  • ASP.NET Core SignalR Backplane
  • Pub/Sub-Messaging und CQ-Ereignisse (In-Memory)
  • Kontinuierliche Abfrageereignisse (In-Memory)
 

Zwischenspeichern von Anwendungsdaten

Der größte Engpass, mit dem wir konfrontiert sind .NET Core Anwendungen ist die „Anwendungsdatenbank“. Das Schöne daran NCache ist das anders? NoSQL databases, NCache fordert Sie nicht auf, die Nutzung Ihrer vorhandenen relationalen Datenbank einzustellen. Sie können weiterhin SQL Server, Azure SQL-Datenbank, Oracle usw. als Datenbank verwenden und dennoch eine lineare Skalierbarkeit erreichen NCache zusätzlich zu Ihrer relationalen Datenbank. Das ist weil NCache beseitigt alle Engpässe bei der Skalierbarkeit relationaler Datenbanken, da im Gegensatz zu Ihrer Datenbank NCache ist tatsächlich linear skalierbar.

Mit Application Data Caching können Sie Ihre Datenbankengpässe beseitigen. NCache ermöglicht es Ihnen, Anwendungsdaten zwischenzuspeichern und teure Datenbankfahrten zu reduzieren. Sie können davon ausgehen, dass 80–90 % des Datenbankdatenverkehrs dorthin umgeleitet werden NCache. Dies verringert den Druck auf Ihre Datenbank und ermöglicht eine schnellere Leistung sowie die Bewältigung größerer Transaktionslasten ohne Verlangsamung.

Anwendungsdaten-Caching bedeutet, dass Sie alle Anwendungsdaten zwischenspeichern, die Sie aus Ihrer relationalen Datenbank erhalten. Dies geschieht normalerweise in Form von Domänenobjekten (auch Entitäten genannt). Hier ist ein Beispiel für die Verwendung eines verteilten Caches NCache für das Zwischenspeichern von Anwendungsdaten.

Customer Load(string custId)
{
   ICache cache = CacheManager.GetCache("myCache");
   string key = "Customer:CustomerID:" + custId;
   Customer cust = cache.Get<Customer>(key);
   
   if (cust == null) {
   // Item not in cache so load from db
   LoadCustomerFromDb(cust);
   // Add item to cache for future reference
   cache.Add(key, cust);
   }
   return cust;
}

Abbildung 3: Verwendung des verteilten In-Memory-Cache für das App-Daten-Caching

 

ASP.NET Core Sitzungsspeicher

Ein weiterer möglicher Engpass entsteht, wenn Sie Ihr ASP speichern.NET Core Sitzungen in SQL Server oder eigenständigem MemoryCache. Bei beiden Optionen bestehen große Einschränkungen hinsichtlich Leistung und Skalierbarkeit. SQL Server-Speicher ist für ASP nicht geeignet.NET Core Sitzungen und wird schnell zu einem Engpass, genau wie bei Anwendungsdaten.

NCache ist ein großartiger Ort, um Ihr ASP zu speichern.NET Core Sitzungen, weil es viel schneller und skalierbarer ist als andere Speicheroptionen. NCache ist schneller, da es sich im Arbeitsspeicher befindet und eine Schlüsselwertschnittstelle bereitstellt, wobei der Wert ein „Objekt“ ist, das ein ASP ist.NET Core Sitzung ist. Und es ist skalierbar, da es sich um einen verteilten Cache handelt.

Und, NCache repliziert auch ASP intelligent.NET Core Sitzungen über seine umfangreichen Caching-Topologien, sodass selbst bei einem Ausfall eines Cache-Servers kein Sitzungsdatenverlust auftritt. Diese Replikation ist erforderlich, weil NCache Stellt einen In-Memory-Speicher bereit und der Speicher verletzt den Speicher.

NCache beschleunigt auch Ihre Serialisierung des ASP.NET Core Sitzung, die erforderlich ist, bevor sie außerhalb des Prozesses gespeichert werden kann. NCache Dies geschieht durch die Verwendung der Dynamic Compact Serialization-Funktion, die zehnmal schneller ist als normales .NET und .NET Core Serialisierung. Sie können diese Funktion verwenden, ohne Codeänderungen vorzunehmen.

Sie können verwenden NCache als Ihr ASP.NET Core Sitzungsspeicher auf zwei Arten.

  1. IDistributedCache für ASP.NET Core Session: NCache hat die IDistributedCache-Schnittstelle implementiert, die Ihnen ein automatisches Plug-in ermöglicht NCache als Ihr ASP.NET Core Sitzungsspeicheranbieter. Diese verfügt jedoch über weniger Funktionen als die andere Option.
  2. NCache Anbieter für ASP.NET Core Session: NCache hat außerdem einen eigenen, funktionsreicheren ASP implementiert.NET Core Sitzungsspeicheranbieter, den Sie verwenden können. Es verfügt über mehr Funktionen in Bezug auf zusätzliche Sperren, Zeitüberschreitungen usw.

Nachfolgend finden Sie ein Beispiel dafür, wie Sie Ihren ASP konfigurieren können.NET Core Anwendung zu verwenden NCache Sitzungsanbieter:

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
      // Specify NCache as the session provider
      services.AddNCacheSession(Configuration.GetSection("NCacheSettings"));
	  ...
   }
   
   public void Configure(IApplicationBuilder app, ...)
   {   
      // select NCache session provider for ASP.NET Core
      app.UseNCacheSession();
      ...
   }
}

Abbildung 4: Plug-in NCache als ASP.NET Core Sessions

 

ASP.NET Core Antwort-Cache-Middleware

ASP.NET Core Anwendungen, die ansonsten einen recht dynamischen Inhalt haben, sind mit Situationen konfrontiert, in denen sich der Inhalt oder die Antwort einiger ihrer Seiten über mehrere Anfragen hinweg nicht ändert. Diese Seiten müssen jedoch immer noch bei jeder Anforderung ausgeführt werden. Dies führt zu einer unnötigen Belastung der Webserver-Ressourcen und aller Ebenen dieser Anwendung. Dadurch kommt es auch zu Leistungsengpässen und die Skalierbarkeit der Anwendung wird eingeschränkt.

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
      // Turn on ASP.NET Core Response Cache with IDistributedCache
      services.AddResponseCaching();
	  
      // Select NCache as IDistributedCache provider
      services.AddNCacheDistributedCache(Configuration.GetSection("NCacheSettings"));
      ...
   }
}

Abbildung 5: Plug-in NCache als ASP.NET Core Antwort-Cache-Middleware

ASP.NET Core hat einen Seitenantwort-Caching-Mechanismus namens ASP.NET Response Cache Middleware bereitgestellt. Und, NCache hat die IDistributedCache-Schnittstelle in ASP implementiert.NET Core Dadurch können Sie nahtlos einstecken NCache als Ihr ASP.NET Core Antwort-Cache-Middleware.

So können Sie verwenden NCache um ASP zwischenzuspeichern.NET Core Seitenantworten für einen bestimmten Zeitraum, sodass beim nächsten Aufruf derselben Seite mit denselben Parametern diese zwischengespeicherte Antwort neu abgestimmt werden kann, anstatt die gesamte Seite erneut auszuführen. Nachfolgend finden Sie das Codebeispiel zur Konfiguration NCache als Ihr ASP.NET Core Antwort-Cache-Middleware.

 

ASP.NET Core SignalR Backplane

Wenn Ihr ASP.NET Core Wenn es sich bei der Anwendung um eine Echtzeit-Webanwendung handelt, verwendet sie höchstwahrscheinlich ASP.NET Core SignalR für die Bereitstellung dieses Echtzeitverhaltens. Echtzeit-Webanwendungen stellen Hochfrequenzaktualisierungen vom Server zum Client bereit. Beispiele für solche Anwendungen sind Spiele, Auktionen, Abstimmungen, soziale Netzwerke usw.

Wenn Ihr ASP.NET Core Wenn die Anwendung in einer Umgebung mit mehreren Servern mit Lastausgleich ausgeführt wird, muss sie einen ASP verwenden.NET Core SignalR Backplane Anbieter, um Ereignisse über mehrere Webserver hinweg zu teilen. Und diese Backplane muss skalierbar sein. Ansonsten Ihr ASP.NET Core Bei der SignalR-Anwendung treten Leistungsengpässe auf.

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
   // Specify NCache as the ASP.NET Core SignalR Backplane
   services.AddSignalR().AddNCache(ncacheOptions =>
      { ncacheOptions.CacheName = "myPartitionedCache"; });
      ...
   }
   public void Configure(IApplicationBuilder app, ...)
   {
      // Use SignalR in ASP.NET Core
      app.UseSignalR(config => { config.MapHub<MessageHub>("/messages"); });
      ...
   }
}

Abbildung 6: Plug-in NCache als ASP.NET Core SignalR Backplane Provider

NCache hat einen ASP implementiert.NET Core SignalR Backplane Anbieter. NCacheist ASP.NET Core SignalR Backplane Der Anbieter nutzt Pub/Sub-Messaging-Funktionen von NCache die superschnell sind, da sie vollständig im Speicher gespeichert sind. Dies ermöglicht Ihrem ASP.NET Core SignalR-Anwendung zur Beschleunigung der SignalR-Ereignisweitergabe zwischen allen Webservern und damit an die Clients.

Und dadurch ist Ihre Echtzeit-Webanwendung reaktionsfähiger bei der Bereitstellung dieser häufigen Updates für die Clients. Und Sie können die Anzahl der Clients kontinuierlich erhöhen und auch weitere Webserver hinzufügen, ohne Leistungsengpässe befürchten zu müssen.

 

Pub/Sub-Messaging (In-Memory)

Wenn dein .NET Core Wenn die Anwendung Pub/Sub-Messaging oder -Ereignisse verwenden muss, verwendet sie höchstwahrscheinlich eine Pub/Sub-Messaging-Plattform, die nicht vollständig In-Memory ist und stattdessen alle Nachrichten auf der Festplatte speichert. Dies kann daher leicht zu einem Leistungsengpass führen, wenn Ihre Anwendung sehr transaktionsstark ist.

NCache Bietet außerdem ein Pub/Sub-Messaging, das superschnell ist, da es vollständig im Speicher läuft. Und es repliziert alle Nachrichten an andere NCache Server, um sicherzustellen, dass es beim Ausfall eines Servers nicht zu Datenverlusten kommt.

Deshalb, wenn Ihr .NET Core Anwendung nutzt NCache Als Pub/Sub-Messaging-Plattform wird es eine superschnelle Leistung und lineare Skalierbarkeit erleben NCache selbst ist linear skalierbar.

Nachfolgend finden Sie ein Beispiel dafür, wie Sie Pub/Sub Messaging verwenden können, das von bereitgestellt wird NCache in Ihrem .NET Core Anwendung.

private void PublishMessage (string topicName)
{
    ITopic topic = _cache.MessagingService.GetTopic(topicName);
     Order order = Order.GenerateOrder<Order>();
     // Publish message containing "order" with expiry
     Message message = new Message(order, new TimeSpan(0, 0, 15));
     topic.Publish(message, DeliveryOption.All, true);
}

private ITopicSubscription SubscribeMessage (string topicName)
{
    ITopic topic = _cache.MessagingService.GetTopic(topicName);
    // Subscribes to the topic. Message delivered to MessageReceivedCallback
    return topic.CreateSubscription(MessageReceivedCallback);
}

static void MessageReceivedCallback(object sender, MessageEventArgs args) { ... }

Abbildung 7: Verwenden von Pub/Sub-Nachrichten in .NET Core Apps

 

Zwischenspeichern von Anwendungsdaten

Der größte Skalierbarkeitsengpass, den Sie haben .NET Core Die Anwendung muss aus der Anwendungsdatenbank entfernt werden. In diesem Bereich können Ihre Anwendungen durch Anwendungsdaten-Caching eine hohe Leistung und lineare Skalierbarkeit erreichen. Der Grund dafür ist einfach. Am meisten .NET Core Anwendungen verarbeiten viele Daten hin und her aus der Datenbank.

 

Halten Sie den Cache frisch

Wenn es um das Zwischenspeichern von Anwendungsdaten geht, besteht die größte Angst der Menschen darin, dass der Cache veraltet ist, d. h. er enthält eine ältere Version der Daten, die bereits von einem anderen Benutzer oder einer anderen Anwendung in der Datenbank geändert wurde.

  1. Referenz vs. Transaktionsdaten

    Diese Angst, dass ein Cache veraltet, ist so groß, dass die meisten Menschen nur schreibgeschützte oder statische Daten (Referenzdaten) zwischenspeichern. Diese schreibgeschützten Daten machen jedoch nur 20 % der gesamten Daten in Form von Nachschlagetabellen und anderen Referenzdaten aus. Der Großteil der Daten in der Datenbank sind Transaktionsdaten, einschließlich Kunden, Konten, Aktivitäten usw. Und wenn Sie diese Transaktionsdaten nicht zwischenspeichern, profitieren Sie nicht vollständig vom Caching.

    Der wahre Vorteil des Caching liegt also darin, dass Sie alle Arten von Daten zwischenspeichern können, ohne befürchten zu müssen, dass das Caching veraltet ist. NCache bietet eine Vielzahl von Funktionen, um dieses Problem zu lösen.

  2. Cache mit Datenbank synchronisieren

    Der effektivste Weg, Ihren Cache auf dem neuesten Stand zu halten, besteht darin, ihn immer mit Ihrer Datenbank zu synchronisieren. NCache können Sie dies wie folgt für eine Vielzahl von Datenbanken tun:

    1. Cache mit SQL Server synchronisieren: Verwenden von SqlDependency- und DB-Ereignisbenachrichtigungen
    2. Cache mit Oracle synchronisieren: Verwendung von OracleDependency- und DB-Ereignisbenachrichtigungen
    3. Cache mit Cosmos DB synchronisieren: Verwenden der Cosmos DB-Änderungsfeedverarbeitung
    4. Cache mit beliebigen Datenbanken synchronisieren (abfragebasiert): Verwendung von NCache Bereitstellung einer abfragebasierten Datenbanksynchronisierung.

Wenn Sie Ihren Cache mit SQL Server synchronisieren, fragen Sie NCache um sich als Client von SQL Server zu registrieren und dann einen SqlDependency-Aufruf zusammen mit einem auf SQL-Abfragen basierenden Datensatz auszugeben. Wenn der SQL Server dann Änderungen in diesem Datensatz erkennt, benachrichtigt er ihn NCache darüber

private static void CreateSqlDependency (Product product)
{
 string connectionString = "Data Source=localhost;Database=northwind;...";
 // SQL stmt on which the SQL Dependency is created in SQL Server
 string sqlStmt = "SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice " +
 "FROM dbo.PRODUCTS WHERE ProductID = " + product.Id;
 CacheDependency sqlDependency = new SqlCacheDependency(connectionString, sqlStmt);
 CacheItem cacheItem = new CacheItem(product) { Dependency = sqlDependency };
 string key = "Product:ProductId:" + product.Id; ;
 cache.Add(key, cacheItem);
}

Abbildung 8: Verwenden von SqlDependency zum Synchronisieren des Caches mit SQL Server

Dann, NCache Entfernt dieses Element aus dem Cache, sodass die Anwendung das nächste Mal, wenn sie es benötigt, die neueste Kopie aus der Datenbank abrufen muss. Wenn Sie den Read-through-Handler verwenden (siehe unten), dann NCache kann die neueste Kopie auch automatisch für Sie aus der Datenbank laden. Unten finden Sie ein Beispiel dafür, wie Sie SqlDependency verwenden können, um Ihren Cache mit SQL Server zu synchronisieren.

 

Lese- und Schreib-Cache

Read-through-Cache ist ein Cache, der Daten aus Ihrer Datenbank lesen kann, indem er einen Readthrough-Handler aufruft, den Sie entwickelt und dem Cache bereitgestellt haben. Ebenso ist ein Write-through-Cache in der Lage, Datenänderungen in Ihre Datenbank zu schreiben, indem er einen Write-through-Handler aufruft, den Sie entwickelt und dem Cache bereitgestellt haben. Der Write-Behind-Cache ist dasselbe wie der Write-Through-Cache, mit der Ausnahme, dass die Datenbankaktualisierungen asynchron erfolgen.

Read-through, Write-through und Write-behind bieten Ihnen viele Vorteile .NET Core Anwendungen einschließlich:

  1. App-Code vereinfachen: Verschieben Sie Persistenzcode aus Ihrer Anwendung in die Caching-Ebene.
  2. Elemente automatisch aus der Datenbank neu laden: Verwenden Sie „Durchlesen bei Ablauf“ oder „DB-Synchronisierungszeit“.
  3. Schnelleres Schreiben: Verwenden Sie asynchrone Datenbankschreibvorgänge mit Write-Behind.

Nachfolgend finden Sie ein Beispiel dafür, wie Sie Read-through mit verwenden können NCache.

// Read through handler for SQL Server
public class SqlReadThruProvider : Runtime.DatasourceProviders.IReadThruProvider
{
 public void Init(IDictionary parameters, string cacheId) {}
 public void Dispose() {}
 // Get object from the database/data-source based on the key
 public ProviderCacheItem LoadFromSource(string key) {}
 // Bulk-Get objects from the database/data-source based on the keys
 public IDictionary<string, ProviderCacheItem> LoadFromSource(ICollection<string> keys)
 {}
}

Abbildung 9: Verwendung des Read-through-Handlers mit NCache

 

Durchsuchen Sie den Cache

Sobald Sie mit dem Zwischenspeichern aller Daten vertraut sind, können Sie damit beginnen, viele Daten in einem verteilten Cache abzulegen. Hier können Sie mit einem weiteren besonderen Problem konfrontiert werden: Wie Sie Ihre Daten schnell und einfach finden können. Da es sich bei den meisten verteilten Caches um Schlüsselwertspeicher handelt, wird es sehr schwierig, den Überblick über alle Ihre Daten allein über Schlüssel zu behalten.

Das ist wo NCache bietet Ihnen verschiedene Möglichkeiten, schnell Daten aus Ihrem Cache zu finden. Beispiele beinhalten:

  1. Gruppendaten im Cache (Gruppe/Untergruppe, Tags, benannte Tags): NCache bietet Ihnen mehrere Möglichkeiten, Ihre Daten logisch zu gruppieren und später die gesamte Gruppe in einem Aufruf abzurufen. Das vereinfacht Ihr Datenmanagement erheblich.
  2. Daten mit Abfragen durchsuchen (SQL/LINQ): Zusätzlich zum Suchen von Daten basierend auf Gruppen-API-Aufrufen, NCache bietet Ihnen außerdem die Möglichkeit, den Cache nach Daten zu durchsuchen, die auf Objektattributen, Gruppen, Tags und benannten Tags basieren.
  3. Parallele Suchen: Seit NCache ist von Natur aus verteilt. Wenn Ihre Anwendung eine Suchabfrage oder einen Such-API-Aufruf ausgibt, wird diese Abfrage parallel auf allen Cache-Servern ausgeführt. Anschließend werden die Ergebnisse aller Server an den Client-Computer (d. h. den Anwendungsserver) zurückgegeben, wo sie zusammengeführt werden, bevor die endgültigen Ergebnisse an Ihre Anwendung zurückgegeben werden. Dies beschleunigt Ihre Cache-Suchen erheblich.

Nachfolgend finden Sie ein Beispiel dafür, wie Sie LINQ-basierte Abfragen verwenden können NCache.

 // Search the cache based on object attributes by using LINQ
IQueryable>Product< products = new NCacheQuery<Product>(_cache);
var result = from product in products
where product.Id > 10
select product;
if (result != null)
   {
   foreach (Product p in result1)
      {
	     // Process each “product” fetched from the database
	     Console.WriteLine("ProductID : " + p.Id);
      }
   }

Abbildung 10: Verwenden von LINQ-Abfragen mit NCache

 

NCache Architektur für extreme Skalierbarkeit

Viel Verkehr .NET Core Anwendungen können es sich nicht leisten, auszufallen, insbesondere während der Spitzenzeiten. Für diese Art von Anwendungen gibt es drei wirklich wichtige Architekturziele, die einem guten InMemory Distributed Cache entsprechen NCache erfüllt.

  1. Client-Cache (InProc-Geschwindigkeit)
  2. Lineare Skalierbarkeit mit schneller Replikation
  3. Hohe Verfügbarkeit durch dynamisches Clustering

Lassen Sie mich die einzelnen Punkte unten erklären.

 

Client-Cache (InProc-Geschwindigkeit)

NCache stellt einen Client-Cache bereit, bei dem es sich um einen lokalen Cache ganz in der Nähe Ihrer Anwendung handelt. Es kann sich entweder um InProc (d. h. es befindet sich in Ihrem Anwendungsprozess) oder um lokales OutProc handeln. In jedem Fall bietet es einen sehr schnellen Zugriff auf eine Teilmenge der zwischengespeicherten Daten, die Ihre Anwendung auf diesem App-Server zu diesem Zeitpunkt benötigt. Gleichzeitig bleibt der Client-Cache mit der Caching-Ebene synchronisiert, sodass alle Daten, die von anderen Benutzern oder Anwendungen in der Caching-Ebene geändert werden, sofort an den Client-Cache weitergegeben werden. Der Client ermöglicht Ihnen InProc-Geschwindigkeit und ist gleichzeitig Teil einer sehr skalierbaren Caching-Ebene.

Client-Cache-Architektur in NCache für InProc-Geschwindigkeit
Abbildung 11: Client-Cache-Architektur in NCache für InProc-Geschwindigkeit
 

Lineare Skalierbarkeit mit schneller Replikation

Eines der wichtigsten architektonischen Ziele von NCache besteht darin, durch seine Caching-Topologien eine lineare Skalierbarkeit mit Datenzuverlässigkeit zu erreichen. Hier sind einige NCache Caching-Topologien die dazu beitragen, diese beiden Ziele zu erreichen.

  1. Partitionierter Cache: NCache Partitioniert den Cache basierend auf der Anzahl der Cache-Server und weist jedem Cache-Server eine Partition zu. Außerdem wird die Anzahl der Partitionen angepasst, wenn Sie zur Laufzeit Cache-Server hinzufügen oder entfernen. Die Partitionierung ist die wichtigste Möglichkeit, lineare Skalierbarkeit sicherzustellen, denn wenn Sie weitere Server hinzufügen, erhöht diese Caching-Topologie die Gesamtspeichergröße und auch die CPU-Verarbeitungsleistung.
  2. Partitionierter Replikat-Cache: Zusätzlich zur Partitionierung NCache stellt außerdem Replikate für jede Partition bereit. Diese Replikate befinden sich auf anderen Cache-Servern als die Partition selbst, um sicherzustellen, dass die Replik sofort verfügbar ist, wenn ein Cache-Server zusammen mit seiner Partition ausfällt. Auf diese Weise wird Datenzuverlässigkeit gewährleistet. Indem jede Partition nur einmal auf einem anderen Cache-Server repliziert wird, NCache erreicht Datenzuverlässigkeit, ohne die lineare Skalierbarkeit zu beeinträchtigen.
Partition-Replica-Caching-Topologie von NCache
Abbildung 12: Partition-Replica-Caching-Topologie von NCache
 

Hohe Verfügbarkeit für 100 % Betriebszeit

Eines der wichtigsten architektonischen Ziele von NCache besteht darin, eine hohe Verfügbarkeit und Cache-Elastizität zu erreichen. Dies geschieht durch die folgenden architektonischen Fähigkeiten:

  1. Selbstheilender Peer-to-Peer-Cache-Cluster: NCache baut einen Cluster von Cache-Servern über TCP/IP auf. Dieser Cluster hat eine Peer-to-Peer-Architektur Das bedeutet, dass es keine Master/Slave-Knoten und kein Clustering nach Mehrheitsregeln gibt. Stattdessen ist jeder Knoten ein gleichberechtigter Peer. Das ermöglicht NCache um Situationen zu bewältigen, in denen ein Knoten ausfallen könnte und der Cluster sich automatisch anpasst und weiterläuft, ohne dass Ihre Anwendung unterbrochen wird.
  2. Dynamische Konfiguration: Das bedeutet, dass Sie keine Dinge in Konfigurationsdateien fest codieren müssen. NCache gibt Konfigurationsinformationen zur Laufzeit an alle Cache-Clients (d. h. Ihre Anwendungen) weiter.
  3. Unterstützung für Verbindungs-Failover: Fällt ein Cache-Server aus, können der gesamte Cache-Cluster und alle Cache-Clients unterbrechungsfrei weiterarbeiten. Die Cache-Clients arbeiten weiter, indem sie mit anderen Cache-Servern im Cluster interagieren.

Was macht man als nächstes?

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