Paginierung mit progressivem Caching

Dec 08 2022
Was ist Cache? Caching ist die Technik zum Speichern von Kopien häufig verwendeter Anwendungsdaten in einer Schicht mit kleinerem, schnellerem Speicher, um die Datenabrufzeiten und den Durchsatz zu verbessern. Was ist Paginierung? Paginierung ist der Prozess der Trennung von Daten in Sätze, genau wie die Seiten eines Buches.
Sich nähern

Was ist Cache? Caching ist die Technik zum Speichern von Kopien häufig verwendeter Anwendungsdaten in einer Schicht mit kleinerem, schnellerem Speicher, um die Datenabrufzeiten und den Durchsatz zu verbessern.

Caching

Was ist Paginierung? Paginierung ist der Prozess der Trennung von Daten in Sätze, genau wie die Seiten eines Buches. Eine GET-API-Anfrage, um Informationen von einem Server über einen API-Endpunkt an große Datenbanken anzufordern, könnte Millionen, wenn nicht Milliarden von Ergebnissen liefern. Die API-Antwort, die uns Tausende von Einträgen auf einmal sendet, ist ein Ressourcenfresser. Paging hilft, unsere Anwendung zu skalieren, mehr Benutzer zu bedienen, Abfragen zu effizienten und ein gutes Kundenerlebnis zu schaffen.

Seitennummerierung

Betrachten wir ein Szenario: Sie erhalten die Aufgabe, einen Service zu entwickeln. Das wird Endpunkte haben, die Datensätze aus verschiedenen Datenbanktabellen bedienen. Nehmen wir zunächst einmal an, Sie beginnen mit einem Endpunkt, der aus der Produkttabelle Ihrer Datenbank bedient wird. Die API unterstützt einige Filterparameter. Sagen wir Preisspanne, Hersteller usw. Wenn man bedenkt, dass sich mehr als 5 Millionen Produkte in Ihrer Datenbank befinden. Und Ihre Lieferanten fügen der Datenbank ständig weitere Produkte hinzu.

Anfängliche Gedanken: Man könnte daran denken, eine Datenbankabfrage für die API-Ressource und den Filterparameter zu erstellen und sie im Pushdown in der Datenbank auszuführen, alle gefilterten Datensätze zu lesen, sie in einem Cache zu speichern und paginierte Antworten aus dem Cache für nachfolgende Anforderungen bereitzustellen.

Stellen Sie sich vor, das Abfrageergebnis würde 2 Millionen Datensätze zurückgeben. Werden (2 Millionen – pageSize) Datensätze zwischengespeichert? Außerdem wird die Reaktionszeit auf die erste Anfrage enorm sein. Da Sie alle 2 Millionen Datensätze auf einmal laden, unabhängig von der Seitengröße. Und wann der Cache ungültig gemacht werden soll. Es speichert bereits eine große Menge an Daten.

Wann soll der Cache ungültig gemacht werden?

Mein Ansatz mit progressivem Caching

Bob kauft Naan-Brot im nächsten Restaurant. Er beobachtet, dass sich zwei Personen in der Nähe eines Ofens befinden. Einer von ihnen formt den Boden zu Naan-Brot. Ein anderer legt bei Bedarf diese geformten Brote in den Ofen und serviert die Bestellung. Er beobachtet es, die Person auf dem Ofen wartet bei einem anderen Befehl ein paar Sekunden und lehnt sich ansonsten zurück.

Sie haben das Recht? Auf Abruf arbeiten, eine Weile pausieren, anderweitig disponieren. Genau so habe ich dieses Problem gelöst. Lassen Sie uns dies nun in unserem Szenario abbilden.

Progressiver Cache:

Unser Cache-Schlüssel ist GUID. Das wird hier als Cursorparameter für unsere Paginierung verwendet. Der Wert ist der angehaltene Reader. Wir können einen Cache mit dem LRU-Cache implementieren. Außerdem entsorgt ein zusätzlicher Timer, der alle 8 Sekunden tickt (kann vom Benutzer konfiguriert werden), den am längsten nicht verwendeten Leser. Wir halten Datenbankverbindungen also nicht lange offen.

public interface ICache
{
  void Add(Guid Key,IReader reader);
  IReader Get(Guid Key);
  void DisposeUnwanted();
}

Erste Anfrage

Example request: https://localhost:9261/Products?Price=100&Manufacturer=HP

//Converted Query for our example request.
SELECT * FROM products WHERE Price = 100 AND Manufacturer Like 'HP'

Schritt 3: Halten Sie den Reader an, generieren Sie eine GUID und speichern Sie sie im Cache.

Schritt 4: Fügen Sie die generierte GUID als Cursor für die nächste Seite in Ihrem JSON-Antworttext hinzu.

Nachfolgende Anfragen

Example request: https://localhost:9261/Products?Price=100&Manufacturer=HP&Cursor=GUID

Schritt 2: Setzen Sie das Lesegerät fort und lesen Sie die Aufzeichnung, bis Ihr Limit zählt.

Schritt 3 & 4: Wie bei der ersten Anfrage.

Zeitkomplexität: O(limit), wobei das Limit die Größe der Antwortseite ist.

Vorteile:

  1. Kein faules Laden.
  2. Effizienter Ressourceneinsatz.
  3. Konstante Reaktionszeit.
  4. Keine komplexen Abfragen. Was Sie verstehen müssten, wenn Sie den Cursor-Parameter drücken.
  1. Vorherige Aufzeichnungen können nicht gelesen werden. Aber das ist per Definition nicht möglich, wenn die Cursor-Paginierung verwendet wird.

Ja, das Leben ist einfach, wenn man es codieren kann.

Dieses progressive Caching-Modell kann mit anderen Datenquellen wie Dateien, Dokumenten passen. (Wir benötigen einen separaten Ausdrucksprozessor für die Where-Klausel, da wir Dateien nicht nach unten verschieben können). Es passt auch effizient auf Ihre verschiedenen Datenbanktabellenschemata, ohne sich viel um seine Struktur zu kümmern.
Das Modell hat bei mir perfekt funktioniert. Ich habe Leute gesehen, die in einer ähnlichen Situation bei Stack Overflow stecken geblieben sind und stattdessen Lazy Loading oder eine Drittanbieter-Implementierung mit zusätzlichem Overhead als einfache Lösung verwendet haben. Der geteilte Ansatz ist mein eigener. Es könnte also zu Ihrem Anwendungsfall passen. Bitte teilen Sie Ihre Ansätze in den Kommentaren.

Und wenn Ihnen dieser Artikel gefallen hat, klicken Sie unten auf die Klatschen-Schaltfläche . Es bedeutet mir sehr viel und es hilft anderen Menschen, die Geschichte zu sehen.

~Sooraj Kumar
Senior Software Engineer @ Astera Software