Die Erwartungen der Kunden und die entsprechenden Anforderungen an Anwendungen waren noch nie so hoch. Benutzer erwarten, dass Anwendungen schnell, zuverlässig und verfügbar sind. Darüber hinaus sind Daten das A und O, und Benutzer möchten in der Lage sein, aggregierte Daten nach Bedarf aufzuteilen, um Erkenntnisse zu gewinnen. Benutzer möchten nicht darauf warten, dass Dateningenieure neue Indizes bereitstellen oder neue ETL-Ketten erstellen. Sie möchten uneingeschränkten Zugriff auf die aktuellsten verfügbaren Daten. Aber die Bewältigung aller Ihrer Anwendungsanforderungen ist für jede einzelne Datenbank eine große Aufgabe. Für die Datenbank unterscheidet sich die Optimierung für häufige Vorgänge mit geringer Latenz an einzelnen Datensätzen von der Optimierung für weniger häufige Aggregationen oder starke Filterung über viele Datensätze hinweg. Oft versuchen wir, beide Muster mit derselben Datenbank zu verarbeiten und mit der inkonsistenten Leistung bei der Skalierung unserer Anwendung umzugehen. Wir denken, wir optimieren mit minimalem Aufwand oder minimalen Kosten, obwohl wir in Wirklichkeit das Gegenteil tun. Die Ausführung von Analysen auf einer OLTP-Datenbank erfordert in der Regel eine Überbereitstellung einer Datenbank, um Datenverkehrsspitzen zu berücksichtigen. Dies kostet letztendlich viel Geld und sorgt in der Regel nicht für ein angenehmes Endbenutzererlebnis. In dieser exemplarischen Vorgehensweise erfahren Sie, wie Sie den hohen Anforderungen der Benutzer mit diesen beiden Zugriffsmustern gerecht werden. Wir werden eine Finanzanwendung erstellen, in der Benutzer Transaktionen aufzeichnen und aktuelle Transaktionen anzeigen und gleichzeitig komplexe Filterung oder Aggregationen für ihre vergangenen Transaktionen wünschen. Ein hybrider Ansatz Um unsere Anwendungsanforderungen zu erfüllen, verwenden wir mit . DynamoDB kümmert sich um unsere Kerntransaktionszugriffsmuster – die Aufzeichnung von Transaktionen sowie die Bereitstellung eines Feeds der letzten Transaktionen für Benutzer zum Durchsuchen. Rockset wird DynamoDB ergänzen, um unsere datenintensiven, „reizvollen“ Zugriffsmuster zu bewältigen. Wir ermöglichen unseren Benutzern, nach Zeit, Händler, Kategorie oder anderen Feldern zu filtern, um die relevanten Transaktionen zu finden, oder um leistungsstarke Aggregationen durchzuführen, um Ausgabentrends im Zeitverlauf anzuzeigen. Amazon DynamoDB Rockset Während wir diese Muster durcharbeiten, werden wir sehen, wie jedes dieser Systeme für die jeweilige Aufgabe geeignet ist. DynamoDB zeichnet sich durch zentrale OLTP-Operationen aus – das Lesen oder Schreiben eines einzelnen Elements oder das Abrufen einer Reihe sequenzieller Elemente basierend auf bekannten Filtern. Aufgrund der Art und Weise, wie die Daten auf der Grundlage des Primärschlüssels partitioniert werden, ist DynamoDB in der Lage, für diese Art von Abfragen in jeder Größenordnung eine konsistente Leistung bereitzustellen. Umgekehrt zeichnet sich Rockset durch die kontinuierliche Aufnahme großer Datenmengen und den Einsatz mehrerer Indizierungsstrategien für diese Daten aus, um hochselektive Filterung, Echtzeit- oder Abfragezeit-Aggregationen und andere Muster bereitzustellen, mit denen DynamoDB nicht einfach umgehen kann. Während wir dieses Beispiel durcharbeiten, lernen wir sowohl die grundlegenden Konzepte, die den beiden Systemen zugrunde liegen, als auch praktische Schritte zum Erreichen unserer Ziele kennen. Sie können der Anwendung über das folgen. GitHub-Repo Kernfunktionen mit DynamoDB implementieren Wir beginnen diese exemplarische Vorgehensweise mit der Implementierung der Kernfunktionen unserer Anwendung. Dies ist ein allgemeiner Ausgangspunkt für jede Anwendung, da Sie die standardmäßigen „CRUDL“-Operationen erstellen, um die Möglichkeit zu bieten, einzelne Datensätze zu bearbeiten und eine Reihe verwandter Datensätze aufzulisten. Für eine E-Commerce-Anwendung wäre dies die Funktionalität, eine Bestellung aufzugeben und frühere Bestellungen anzuzeigen. Bei einer Social-Media-Anwendung wäre das das Erstellen von Beiträgen, das Hinzufügen von Freunden oder das Anzeigen der Personen, denen Sie folgen. Diese Funktionalität wird in der Regel von Datenbanken implementiert, die auf spezialisiert sind, bei denen viele gleichzeitige Vorgänge für eine kleine Anzahl von Zeilen im Vordergrund stehen. OLTP-Workflows (Online Transactional Processing) In diesem Beispiel erstellen wir eine Geschäftsfinanzanwendung, mit der ein Benutzer Zahlungen tätigen und empfangen sowie den Verlauf seiner Transaktionen anzeigen kann. Das Beispiel wird für diese exemplarische Vorgehensweise absichtlich vereinfacht, Sie können sich jedoch drei grundlegende Zugriffsmuster für unsere Anwendung vorstellen: , in der eine Aufzeichnung einer vom Unternehmen getätigten oder erhaltenen Zahlung gespeichert wird; Transaktion aufzeichnen , sodass Benutzer die letzten von einem Unternehmen getätigten und empfangenen Zahlungen sehen können. Und Zeigen Sie Transaktionen nach Datumsbereich an , die es einem Benutzer ermöglichen, die Einzelheiten einer einzelnen Transaktion genauer zu untersuchen. Zeigen Sie einzelne Transaktionen an Bei jedem dieser Zugriffsmuster handelt es sich um ein kritisches Zugriffsmuster mit hohem Volumen. Wir werden ständig Transaktionen für Benutzer aufzeichnen und der Transaktions-Feed wird die erste Ansicht sein, wenn sie die Anwendung öffnen. Darüber hinaus verwendet jedes dieser Zugriffsmuster bekannte, konsistente Parameter, um die relevanten Datensätze abzurufen. Wir verwenden DynamoDB, um diese Zugriffsmuster zu verarbeiten. DynamoDB ist eine von AWS bereitgestellte NoSQL-Datenbank. Es handelt sich um eine vollständig verwaltete Datenbank, die sich sowohl bei hochskalierten als auch bei serverlosen Anwendungen wachsender Beliebtheit erfreut. Eine der einzigartigsten Funktionen von DynamoDB ist die Bereitstellung konsistenter Leistung in jeder Größenordnung. Unabhängig davon, ob Ihre Tabelle 1 Megabyte oder 1 Petabyte groß ist, sollten Sie für Ihre Vorgänge die gleiche Reaktionszeit sehen. Dies ist eine wünschenswerte Qualität für zentrale OLTP-Anwendungsfälle wie die, die wir hier implementieren. Dies ist eine großartige und wertvolle technische Errungenschaft, aber es ist wichtig zu verstehen, dass sie durch eine gezielte Auswahl der Abfragearten erreicht wurde, die eine gute Leistung erbringen. DynamoDB ist in der Lage, diese konsistente Leistung durch zwei zentrale Designentscheidungen bereitzustellen. Zunächst muss jeder Datensatz in Ihrer DynamoDB-Tabelle einen Primärschlüssel enthalten. Dieser Primärschlüssel besteht aus einem Partitionsschlüssel und einem optionalen Sortierschlüssel. Die zweite wichtige Designentscheidung für DynamoDB besteht darin, dass die API die Verwendung des Primärschlüssels stark erzwingt – dazu später mehr. Im Bild unten sehen wir einige Beispieltransaktionsdaten in unserer FinTech-Anwendung. Unsere Tabelle verwendet einen Partitionsschlüssel des Organisationsnamens in unserer Anwendung sowie einen -basierten Sortierschlüssel, der die Eindeutigkeitsmerkmale einer UUID sowie Sortierbarkeit nach Erstellungszeit bietet, die es uns ermöglicht, zeitbasierte Abfragen durchzuführen. ULID Die Datensätze in unserer Tabelle enthalten andere Attribute wie Händlername, Kategorie und Menge, die in unserer Anwendung nützlich sind, aber für die zugrunde liegende Architektur von DynamoDB nicht so wichtig sind. Der wichtige Teil liegt im Primärschlüssel und insbesondere im Partitionsschlüssel. Unter der Haube teilt DynamoDB Ihre Daten in mehrere Speicherpartitionen auf, von denen jede eine Teilmenge der Daten in Ihrer Tabelle enthält. DynamoDB verwendet das Partitionsschlüsselelement des Primärschlüssels, um einen bestimmten Datensatz einer bestimmten Speicherpartition zuzuweisen. Wenn die Datenmenge in Ihrer Tabelle oder der Datenverkehr in Ihrer Tabelle zunimmt, fügt DynamoDB Partitionen hinzu, um Ihre Datenbank horizontal zu skalieren. Wie oben erwähnt, besteht die zweite wichtige Designentscheidung für DynamoDB darin, dass die API die Verwendung des Primärschlüssels stark erzwingt. Fast alle API-Aktionen in DynamoDB erfordern mindestens den Partitionsschlüssel Ihres Primärschlüssels. Aus diesem Grund ist DynamoDB in der Lage, jede Anfrage schnell an die richtige Speicherpartition weiterzuleiten, unabhängig von der Anzahl der Partitionen und der Gesamtgröße der Tabelle. Aufgrund dieser beiden Kompromisse gibt es zwangsläufig Einschränkungen bei der Verwendung von DynamoDB. Sie müssen Ihre Zugriffsmuster im Voraus sorgfältig planen und entwerfen, da Ihr Primärschlüssel in Ihre Zugriffsmuster einbezogen werden muss. Das spätere Ändern Ihrer Zugriffsmuster kann schwierig sein und erfordert möglicherweise einige manuelle Migrationsschritte. Wenn Ihre Anwendungsfälle in die Kernkompetenzen von DynamoDB fallen, werden Sie von den Vorteilen profitieren. Sie erhalten unabhängig von der Größenordnung eine konsistente, vorhersehbare Leistung und werden im Laufe der Zeit keine langfristige Verschlechterung Ihrer Anwendung feststellen. Darüber hinaus erhalten Sie eine vollständig verwaltete Erfahrung mit geringer betrieblicher Belastung, sodass Sie sich auf das konzentrieren können, was für das Unternehmen wichtig ist. Die Kernoperationen in unserem Beispiel passen perfekt zu diesem Modell. Wenn wir einen Transaktions-Feed für eine Organisation abrufen, verfügen wir über die Organisations-ID in unserer Anwendung, die es uns ermöglicht, mithilfe der DynamoDB- einen zusammenhängenden Satz von Datensätzen mit demselben Partitionsschlüssel abzurufen. Um zusätzliche Details zu einer bestimmten Transaktion abzurufen, stehen uns sowohl die Organisations-ID als auch die Transaktions-ID zur Verfügung, um eine DynamoDB- Anfrage zum Abrufen des gewünschten Elements zu stellen. Abfrageoperation GetItem- Mit der können Sie diese Vorgänge in Aktion sehen. Befolgen Sie die Anweisungen, um die Anwendung bereitzustellen und sie mit Beispieldaten zu füllen. Stellen Sie dann HTTP-Anfragen an den bereitgestellten Dienst, um den Transaktions-Feed für einzelne Benutzer abzurufen. Bei diesen Vorgängen handelt es sich um schnelle und effiziente Vorgänge, unabhängig von der Anzahl gleichzeitiger Anforderungen oder der Größe Ihrer DynamoDB-Tabelle. Beispielanwendung DynamoDB mit Rockset ergänzen Bisher haben wir DynamoDB verwendet, um unsere Kernzugriffsmuster zu verwalten. DynamoDB eignet sich hervorragend für diese Muster, da seine schlüsselbasierte Partitionierung in jeder Größenordnung eine konsistente Leistung bietet. Allerdings beherrscht DynamoDB andere Zugriffsmuster nicht besonders gut. DynamoDB ermöglicht keine effiziente Abfrage nach anderen Attributen als dem Primärschlüssel. Sie können verwenden, um Ihre Daten anhand zusätzlicher Attribute neu zu indizieren. Dies kann jedoch dennoch problematisch sein, wenn Sie über viele verschiedene Attribute verfügen, die zur Indizierung Ihrer Daten verwendet werden können. die Sekundärindizes von DynamoDB Darüber hinaus bietet DynamoDB standardmäßig keine Aggregationsfunktionalität. Sie können Ihre eigenen Aggregate mit DynamoDB berechnen, allerdings mit eingeschränkter Flexibilität oder nicht optimiertem Leseverbrauch im Vergleich zu einer Lösung, die die Aggregation im Voraus plant. Um diese Muster zu verarbeiten, werden wir . DynamoDB mit Rockset ergänzen Rockset kann man sich am besten als einen sekundären Satz von Indizes für Ihre Daten vorstellen. Rockset verwendet zur Abfragezeit nur diese Indizes und projiziert während eines Lesevorgangs keine Last zurück in DynamoDB. Anstelle einzelner, transaktionaler Updates von Ihren Anwendungsclients ist Rockset für die kontinuierliche Streaming-Aufnahme aus Ihrem primären Datenspeicher konzipiert. Es verfügt über direkte Konnektoren für eine Reihe primärer Datenspeicher, darunter DynamoDB, MongoDB, Kafka und viele relationale Datenbanken. Während Rockset Daten aus Ihrer Primärdatenbank aufnimmt, indiziert es Ihre Daten dann in einem , der Konzepte von einem Zeilenindex, einem invertierten Index und einem Spaltenindex übernimmt. Zusätzliche Indizes wie Bereich, Typ und Geodaten werden automatisch basierend auf den erfassten Datentypen erstellt. Wir werden die Besonderheiten dieser Indizes weiter unten besprechen, aber dieser konvergierte Index ermöglicht flexiblere Zugriffsmuster auf Ihre Daten. konvergenten Index Dies ist das Kernkonzept von Rockset – es handelt sich um einen sekundären Index Ihrer Daten mithilfe einer vollständig verwalteten Aufnahmepipeline nahezu in Echtzeit aus Ihrem primären Datenspeicher. Teams extrahieren seit langem Daten aus DynamoDB, um sie in ein anderes System einzufügen, um zusätzliche Anwendungsfälle abzuwickeln. Bevor wir näher auf die Art und Weise eingehen, wie Rockset Daten aus Ihrer Tabelle aufnimmt, wollen wir kurz besprechen, wie sich Rockset von anderen Optionen in diesem Bereich unterscheidet. Es gibt einige wesentliche Unterschiede zwischen Rockset und anderen Ansätzen. Erstens ist Rockset vollständig verwaltet. Sie müssen nicht nur die Datenbankinfrastruktur nicht verwalten, sondern auch die Pipeline zum Extrahieren, Transformieren und Laden von Daten in Rockset nicht warten. Bei vielen anderen Lösungen sind Sie für den „Klebstoff“-Code zwischen Ihren Systemen verantwortlich. Diese Systeme sind kritisch und dennoch fehleranfällig, da Sie sich vor Änderungen in der Datenstruktur schützen müssen. Upstream-Änderungen können für diejenigen, die diese Systeme warten, zu Downstream-Problemen führen. Zweitens kann Rockset Echtzeitdaten auf veränderliche Weise verarbeiten. Bei vielen anderen Systemen bekommt man das eine oder andere. Sie können Ihre Daten regelmäßig exportieren und in großen Mengen laden, dies führt jedoch dazu, dass die Daten zwischen den Ladevorgängen veraltet sind. Alternativ können Sie Daten rein anhängend in Ihr Data Warehouse streamen, Sie können jedoch keine direkten Aktualisierungen für sich ändernde Daten durchführen. Rockset ist in der Lage, Aktualisierungen vorhandener Artikel ebenso schnell und effizient durchzuführen wie neue Daten einzufügen und Ihnen so einen Echtzeitüberblick über Ihre sich ändernden Daten zu ermöglichen. Drittens generiert Rockset seine Indizes automatisch. Bei anderen „vollständig verwalteten“ Lösungen müssen Sie die Indizes immer noch so konfigurieren, wie Sie sie zur Unterstützung neuer Abfragen benötigen. Die Abfrage-Engine von Rockset ist so konzipiert, dass sie einen Satz von Indizes verwendet, um alle Abfragen zu unterstützen. Wenn Sie immer mehr Abfragen zu Ihrem System hinzufügen, müssen Sie keine zusätzlichen Indizes hinzufügen, was immer mehr Platz und Rechenressourcen beansprucht. Dies bedeutet auch, dass auch Ad-hoc-Abfragen die Indizes vollständig nutzen können, sodass sie schnell ausgeführt werden können, ohne darauf warten zu müssen, dass ein Administrator einen maßgeschneiderten Index zur Unterstützung hinzufügt. Wie Rockset Daten von DynamoDB aufnimmt Nachdem wir nun die Grundlagen von Rockset kennen und wissen, wie es uns hilft, verbinden wir unsere DynamoDB-Tabelle mit Rockset. Dabei erfahren wir, wie der Rockset-Ingestion-Prozess funktioniert und wie er sich von anderen Optionen unterscheidet. Rockset verfügt über speziell entwickelte Konnektoren für eine Reihe von Datenquellen, und die spezifische Konnektorimplementierung hängt von den Besonderheiten der Upstream-Datenquelle ab. Für die Verbindung mit DynamoDB verlässt sich Rockset auf . DynamoDB Streams ist eine Änderungsdatenerfassungsfunktion von DynamoDB, bei der Details zu jedem Schreibvorgang für eine DynamoDB-Tabelle im Stream aufgezeichnet werden. Verbraucher des Streams können diese Änderungen in derselben Reihenfolge verarbeiten, in der sie an der Tabelle vorgenommen wurden, um nachgelagerte Systeme zu aktualisieren. DynamoDB Streams Ein DynamoDB-Stream ist für Rockset großartig, um mit einer DynamoDB-Tabelle nahezu in Echtzeit auf dem Laufenden zu bleiben, aber das ist nicht die ganze Geschichte. Ein DynamoDB-Stream enthält nur Datensätze von Schreibvorgängen, die nach der Aktivierung des Streams für die Tabelle erfolgten. Darüber hinaus . Vorgänge, die vor der Aktivierung des Streams oder vor mehr als 24 Stunden ausgeführt wurden, sind im Stream nicht vorhanden. speichert ein DynamoDB-Stream Datensätze nur 24 Stunden lang Aber Rockset benötigt nicht nur die aktuellsten Daten, sondern alle Daten in Ihrer Datenbank, um Ihre Anfragen richtig zu beantworten. Um dies zu bewältigen, führt es einen ersten Massenexport durch (entweder mithilfe eines DynamoDB-Scans oder , abhängig von Ihrer Tabellengröße), um den Anfangszustand Ihrer Tabelle abzurufen. eines Exports nach S3 Daher besteht der DynamoDB-Verbindungsprozess von Rockset aus zwei Teilen: Ein erster Prozess zum Exportieren Ihrer vollständigen Tabelle zur Aufnahme in Rockset; Bootstrapping- Ein anschließender, Prozess, um Aktualisierungen aus Ihrem DynamoDB-Stream zu nutzen und die Daten in Rockset zu aktualisieren. kontinuierlicher Beachten Sie, dass beide Prozesse vollständig von Rockset verwaltet werden und für Sie als Benutzer transparent sind. Sie sind nicht für die Wartung dieser Pipelines und die Reaktion auf Warnungen verantwortlich, wenn ein Fehler auftritt. Wenn Sie außerdem die S3-Exportmethode für den ersten Aufnahmeprozess wählen, verbraucht keiner der Rockset-Aufnahmeprozesse Lesekapazitätseinheiten aus Ihrer Haupttabelle. Somit nimmt Rockset den Verbrauch Ihrer Anwendungsfälle nicht in Anspruch und beeinträchtigt auch nicht die Produktionsverfügbarkeit. Anwendung: DynamoDB mit Rockset verbinden Bevor wir Rockset in unserer Anwendung verwenden, verbinden wir Rockset mit unserer DynamoDB-Tabelle. Zuerst müssen wir eine neue Integration zwischen Rockset und unserem Tisch erstellen. Wir gehen die allgemeinen Schritte weiter unten durch, bei Bedarf finden Sie jedoch . detailliertere Schritt-für-Schritt-Anleitungen im Anwendungs-Repository Navigieren Sie in der Rockset-Konsole zum , um diesen Vorgang zu starten. neuen Integrationsassistenten Wählen Sie im Integrationsassistenten als Integrationstyp aus. Klicken Sie dann auf , um mit dem nächsten Schritt fortzufahren. Amazon DynamoDB Start Der DynamoDB-Integrationsassistent enthält schrittweise Anweisungen zum Autorisieren von Rockset für den Zugriff auf Ihre DynamoDB-Tabelle. Dazu müssen Sie eine IAM-Richtlinie, eine IAM-Rolle und einen S3-Bucket für Ihren Tabellenexport erstellen. Wenn Sie möchten, können Sie diesen Anweisungen folgen, um die Ressourcen manuell zu erstellen. In der serverlosen Welt bevorzugen wir es, Dinge so weit wie möglich über zu erstellen, und dazu gehören auch diese unterstützenden Ressourcen. Infrastructure-as-Code Das Beispiel-Repository enthält die Infrastruktur als Code, die zum Erstellen der Rockset-Integrationsressourcen erforderlich ist. Um diese zu verwenden, suchen Sie zunächst unten im Rockset-Integrationsassistenten nach den Werten für die Rockset-Konto-ID und die externe ID. Kopieren Sie diese Werte und fügen Sie sie in die Blocks der Datei serverless.yml ein. um diese Ressourcen zu erstellen. entsprechenden Abschnitte des custom Entfernen Sie dann die Kommentarzeichen für die Ressourcen in den Zeilen 71 bis 122 der serverless.yml, Stellen Sie Ihre Anwendung erneut bereit, um diese neuen Ressourcen zu erstellen. Kopieren Sie in den Ausgaben der Bereitstellung den S3-Bucket-Namen und den IAM-Rollen-ARN und fügen Sie sie an den entsprechenden Stellen in der Rockset-Konsole ein. Klicken Sie dann auf die Schaltfläche „Integration speichern“, um Ihre Integration zu speichern. Nachdem Sie Ihre Integration erstellt haben, müssen Sie aus der Integration eine erstellen. Navigieren Sie zum in der Rockset-Konsole und befolgen Sie die Schritte, um Ihre Integration zum Erstellen einer Sammlung zu verwenden. Außerdem finden Sie im Anwendungs-Repository. Rockset-Sammlung Sammlungserstellungsassistenten Schritt-für-Schritt-Anleitungen zum Erstellen einer Sammlung Sobald Sie diese Verbindung hergestellt haben, werden Einfügungen, Aktualisierungen oder Löschungen von Daten in DynamoDB im Allgemeinen auf einem Satz von Instanzen mit der richtigen Größe in weniger als 2 Sekunden im Rockset-Index widergespiegelt und stehen für Abfragen zur Verfügung. Verwendung von Rockset für komplexe Filterung Nachdem wir Rockset nun mit unserer DynamoDB-Tabelle verbunden haben, wollen wir sehen, wie Rockset neue Zugriffsmuster auf unsere vorhandenen Daten ermöglichen kann. Erinnern Sie sich aus unserem Abschnitt über die Kernfunktionen daran, dass sich DynamoDB stark auf Ihre Primärschlüssel konzentriert. Sie müssen Ihren Primärschlüssel verwenden, um effizient auf Ihre Daten zugreifen zu können. Dementsprechend haben wir unsere Tabelle so strukturiert, dass sie den Organisationsnamen und die Transaktionszeit in unseren Primärschlüsseln verwendet. Diese Struktur funktioniert für unsere Kernzugriffsmuster, wir möchten den Benutzern jedoch möglicherweise eine flexiblere Möglichkeit bieten, ihre Transaktionen zu durchsuchen. Es gibt eine Reihe nützlicher Attribute – Kategorie, Händlername, Menge usw. – die beim Filtern hilfreich sein können. Wir könnten die Sekundärindizes von DynamoDB verwenden, um die Filterung nach mehr Attributen zu ermöglichen, aber das passt hier immer noch nicht so gut. Die Primärschlüsselstruktur von DynamoDB ermöglicht nicht ohne weiteres flexible Abfragen, die Kombinationen vieler optionaler Attribute beinhalten. Sie könnten einen sekundären Index zum Filtern nach Händlername und -datum haben, aber Sie würden einen weiteren sekundären Index benötigen, wenn Sie das Filtern nach Händlername, -datum und -betrag zulassen möchten. Ein Zugriffsmuster, das nach Kategorien filtert, würde einen dritten Sekundärindex erfordern. Anstatt uns mit dieser Komplexität auseinanderzusetzen, stützen wir uns hier auf Rockset. Wir haben bereits gesehen, dass Rockset einen konvergenten Index verwendet, um Ihre Daten auf verschiedene Weise zu indizieren. Eine dieser Möglichkeiten ist ein invertierter Index. Mit einem invertierten Index indiziert Rockset jedes Attribut direkt. Beachten Sie, wie dieser Index organisiert ist. Jeder Attributname und -wert wird als Schlüssel des Index verwendet, und der Wert ist eine Liste von Dokument-IDs, die den entsprechenden Attributnamen und -wert enthalten. Die Schlüssel sind so konstruiert, dass ihre natürliche Sortierreihenfolge Bereichsabfragen effizient unterstützen kann. Ein invertierter Index eignet sich hervorragend für Abfragen mit selektiven Filterbedingungen. Stellen Sie sich vor, wir möchten unseren Benutzern ermöglichen, ihre Transaktionen zu filtern, um diejenigen zu finden, die bestimmten Kriterien entsprechen. Jemand in der Vandelay Industries-Organisation möchte wissen, wie oft er in letzter Zeit Chipotle bestellt hat. Sie könnten dies mit einer Abfrage wie folgt finden: SELECT * FROM transactions WHERE organization = 'Vandelay Industries' AND merchant_name = 'Chipotle' Da wir selektiv nach Kunden- und Händlernamen filtern, können wir den invertierten Index verwenden, um die passenden Dokumente schnell zu finden. Rockset sucht im invertierten Index nach Attributnamen- und Wertepaaren, um die Listen übereinstimmender Dokumente zu finden. Sobald diese beiden Listen vorhanden sind, können sie zusammengeführt werden, um die Datensätze zu finden, die beiden Bedingungssätzen entsprechen, und die Ergebnisse an den Client zurückzugeben. So wie die partitionsbasierte Indizierung von DynamoDB effizient für Vorgänge ist, die den Partitionsschlüssel verwenden, ermöglicht Ihnen der invertierte Index von Rockset effiziente Suchvorgänge für jedes Feld in Ihrem Datensatz, sogar für Attribute eingebetteter Objekte oder Werte innerhalb eingebetteter Arrays. Anwendung: Verwendung der Rockset-API in Ihrer Anwendung Nachdem wir nun wissen, wie Rockset selektive Abfragen für unseren Datensatz effizient ausführen kann, gehen wir nun die praktischen Aspekte der Integration von Rockset-Abfragen in unsere Anwendung durch. Rockset stellt RESTful-Dienste bereit, die durch ein Autorisierungstoken geschützt sind. SDKs sind auch für gängige Programmiersprachen verfügbar. Dadurch eignet es sich hervorragend für die Integration in serverlose Anwendungen, da Sie für den Zugriff auf Ihre Datenbank keine komplizierte private Netzwerkkonfiguration einrichten müssen. Um mit der Rockset-API in unserer Anwendung interagieren zu können, benötigen wir einen Rockset-API-Schlüssel. Sie können einen im der Rockset-Konsole erstellen. Kopieren Sie anschließend den Wert in Ihre serverless.yml-Datei und stellen Sie ihn erneut bereit, um ihn Ihrer Anwendung zur Verfügung zu stellen. Abschnitt „API-Schlüssel“ Randbemerkung: Der Einfachheit halber verwenden wir diesen API-Schlüssel als Umgebungsvariable. In einer realen Anwendung sollten Sie etwas wie oder verwenden, um Ihr Geheimnis zu speichern und Umgebungsvariablen zu vermeiden. Parameter Store AWS Secrets Manager Schauen Sie sich unsere an, um zu sehen, wie wir mit der Rockset-API interagieren. Die Klasseninitialisierung nimmt ein Rockset-Clientobjekt auf, das für Aufrufe an Rockset verwendet wird. TransactionService-Klasse In der haben wir die folgende Abfrage zur Interaktion mit Rockset: filterTransactions-Methode in unserer Serviceklasse const response = await this._rocksetClient.queries.query({ sql: { query: ` SELECT * FROM Transactions WHERE organization = :organization AND category = :category AND amount BETWEEN :minAmount AND :maxAmount ORDER BY transactionTime DESC LIMIT 20`, parameters: [ { name: "organization", type: "string", value: organization, }, { name: "category", type: "string", value: category, }, { name: "minAmount", type: "float", value: minAmount, }, { name: "maxAmount", type: "float", value: maxAmount, }, ], }, }); Bei dieser Interaktion sind zwei Dinge zu beachten. Erstens verwenden wir benannte Parameter in unserer Abfrage, wenn wir Eingaben von Benutzern verarbeiten. Dies ist eine gängige Praxis bei SQL-Datenbanken, um SQL-Injection-Angriffe zu vermeiden. Zweitens ist der SQL-Code mit unserem Anwendungscode vermischt und es kann schwierig sein, ihn im Laufe der Zeit zu verfolgen. Das kann zwar funktionieren, aber es gibt einen besseren Weg. Während wir unseren nächsten Anwendungsfall anwenden, schauen wir uns an, wie wir Rockset Query Lambdas in unserer Anwendung verwenden. Verwendung von Rockset für die Aggregation Bisher haben wir die Indizierungsstrategien von DynamoDB und Rockset überprüft und erläutert, wie die Datenbank einen einzelnen Datensatz oder eine Reihe von Datensätzen finden kann, die einem bestimmten Filterprädikat entsprechen. Wir haben beispielsweise gesehen, dass DynamoDB Sie dazu drängt, einen Primärschlüssel zum Suchen eines Datensatzes zu verwenden, während der invertierte Index von Rockset Datensätze mithilfe hochselektiver Filterbedingungen effizient finden kann. In diesem letzten Abschnitt schalten wir ein wenig um und konzentrieren uns auf das Datenlayout und nicht auf die direkte Indizierung. Beim Nachdenken über das Datenlayout werden wir zwei Ansätze gegenüberstellen: zeilenbasiert vs. spaltenbasiert. Wie der Name schon sagt, ordnen zeilenbasierte Datenbanken ihre Daten auf der Festplatte in Zeilen an. Die meisten relationalen Datenbanken wie PostgreSQL und MySQL sind zeilenbasierte Datenbanken. Dies gilt auch für viele NoSQL-Datenbanken wie DynamoDB, auch wenn ihre Datensätze technisch gesehen keine „Zeilen“ im Sinne einer relationalen Datenbank sind. Zeilenbasierte Datenbanken eignen sich hervorragend für die Zugriffsmuster, die wir bisher untersucht haben. Beim Abrufen einer einzelnen Transaktion anhand ihrer ID oder einer Reihe von Transaktionen gemäß bestimmten Filterbedingungen möchten wir im Allgemeinen, dass alle Felder für jede Transaktion zurückgegeben werden. Da alle Felder des Datensatzes zusammen gespeichert werden, ist im Allgemeinen ein einziger Lesevorgang erforderlich, um den Datensatz zurückzugeben. (Hinweis: Einige Nuancen hierzu folgen in Kürze). Aggregation ist eine ganz andere Geschichte. Mit Aggregationsabfragen möchten wir ein Aggregat berechnen – eine Anzahl aller Transaktionen, eine Summe der Transaktionssummen oder die durchschnittlichen Ausgaben pro Monat für eine Reihe von Transaktionen. Kehren wir zum Benutzer der Vandelay Industries-Organisation zurück: Stellen Sie sich vor, er möchte sich die letzten drei Monate ansehen und die Gesamtausgaben nach Kategorie für jeden Monat ermitteln. Eine vereinfachte Version dieser Abfrage würde wie folgt aussehen: SELECT category, EXTRACT(month FROM transactionTime) AS month, sum(amount) AS amount FROM transactions WHERE organization = 'Vandelay Industries' AND transactionTime > CURRENT_TIMESTAMP() - INTERVAL 3 MONTH GROUP BY category, month ORDER BY category, month DESC Für diese Abfrage kann es sein, dass eine große Anzahl von Datensätzen gelesen werden muss, um das Ergebnis zu berechnen. Beachten Sie jedoch, dass wir nicht viele Felder für jeden unserer Datensätze benötigen. Wir benötigen nur vier – Kategorie, Transaktionszeit, Organisation und Betrag –, um dieses Ergebnis zu ermitteln. Daher müssen wir nicht nur viel mehr Datensätze lesen, um diese Abfrage zu erfüllen, sondern unser zeilenbasiertes Layout liest auch eine Reihe von Feldern, die für unser Ergebnis unnötig sind. Im Gegensatz dazu speichert ein spaltenbasiertes Layout Daten auf der Festplatte in Spalten. Der Converged Index von Rockset verwendet einen Spaltenindex, um Daten in einem spaltenbasierten Layout zu speichern. In einem spaltenbasierten Layout werden Daten nach Spalten zusammen gespeichert. Ein einzelner Datensatz wird zur Indizierung in seine einzelnen Spalten zerlegt. Wenn meine Abfrage eine Aggregation durchführen muss, um das „Betrag“-Attribut für eine große Anzahl von Datensätzen zu summieren, kann Rockset dies tun, indem es einfach den „Betrag“-Teil des Spaltenindex scannt. Dadurch wird die Menge der gelesenen und verarbeiteten Daten im Vergleich zu zeilenbasierten Layouts erheblich reduziert. Beachten Sie, dass der Spaltenindex von Rockset die Attribute innerhalb einer Spalte standardmäßig nicht anordnet. Da wir benutzerorientierte Anwendungsfälle haben, die mit den Daten eines bestimmten Kunden arbeiten, möchten wir unseren Spaltenindex lieber nach Kunden organisieren, um die Menge der zu scannenden Daten bei Verwendung des Spaltenindex zu reduzieren. Rockset bietet um dabei zu helfen. Mit Clustering können wir angeben, dass unser Spaltenindex durch das Attribut „Organisation“ geclustert werden soll. Dadurch werden alle Spaltenwerte nach der Organisation innerhalb der Spaltenindizes gruppiert. Wenn Vandelay Industries also eine Aggregation seiner Daten durchführt, kann der Abfrageprozessor von Rockset die Teile des Spaltenindex für andere Kunden überspringen. Daten-Clustering für Ihren Spaltenindex, Wie der zeilenbasierte Index von Rockset die Verarbeitung unterstützt Bevor wir uns der Verwendung des Spaltenindex in unserer Anwendung zuwenden, möchte ich über einen weiteren Aspekt des konvergenten Index von Rockset sprechen. Zuvor habe ich erwähnt, dass beim Abrufen vollständiger Datensätze zeilenbasierte Layouts verwendet wurden, und darauf hingewiesen, dass sowohl DynamoDB als auch unsere Rockset-Abfragen mit invertierten Indizes diese Layouts verwendeten. Das stimmt nur teilweise. Der invertierte Index weist einige Ähnlichkeiten mit einem spaltenbasierten Index auf, da er Spaltennamen und -werte zusammen speichert, um eine effiziente Suche nach beliebigen Attributen zu ermöglichen. Jeder Indexeintrag enthält einen Zeiger auf die IDs der Datensätze, die die angegebene Kombination aus Spaltenname und Wert enthalten. Sobald die relevante(n) ID(s) aus dem invertierten Index ermittelt wurden, kann Rockset den vollständigen Datensatz mithilfe des Zeilenindex abrufen. Rockset verwendet Wörterbuchkodierung und andere fortschrittliche Komprimierungstechniken, um die Datenspeichergröße zu minimieren. Somit haben wir nun gesehen, wie der Converged Index von Rockset zusammenpasst: Der wird verwendet, um schnell eine große Anzahl von Werten in einer bestimmten Spalte nach Aggregationen zu durchsuchen. spaltenbasierte Index Der wird für selektive Filter für beliebige Spaltennamen und -werte verwendet; invertierte Index Der wird verwendet, um alle zusätzlichen Attribute abzurufen, auf die in der Projektionsklausel verwiesen werden kann. zeilenbasierte Index Unter der Haube verfolgt die leistungsstarke Indexierungs- und Abfrage-Engine von Rockset Statistiken zu Ihren Daten und generiert optimale Pläne zur effizienten Ausführung Ihrer Abfrage. Anwendung: Verwendung von Rockset Query Lambdas in Ihrer Anwendung Lassen Sie uns unsere Rockset-Aggregationsabfrage implementieren, die den Spaltenindex verwendet. Für unsere vorherige Abfrage haben wir unsere SQL-Abfrage direkt an die Rockset-API geschrieben. Während dies bei einigen hochgradig anpassbaren Benutzeroberflächen die richtige Vorgehensweise ist, gibt es eine bessere Option, wenn der SQL-Code statischer ist. Wir möchten vermeiden, unseren chaotischen SQL-Code mitten in unserer Anwendungslogik zu verwalten. Um dabei zu helfen, verfügt Rockset über eine Funktion namens Query Lambdas. Abfrage-Lambdas sind benannte, versionierte und parametrisierte Abfragen, die in der Rockset-Konsole registriert werden. Nachdem Sie ein Query Lambda in Rockset konfiguriert haben, erhalten Sie einen vollständig verwalteten, skalierbaren Endpunkt für das Query Lambda, den Sie mit Ihren von Rockset auszuführenden Parametern aufrufen können. Darüber hinaus erhalten Sie sogar Überwachungsstatistiken für jedes Query-Lambda, sodass Sie die Leistung Ihres Query-Lambda verfolgen können, während Sie Änderungen vornehmen. . Richten wir jedoch unser erstes Query-Lambda für die Verarbeitung unserer Aggregationsabfrage ein. Eine . Weitere Informationen zu Query-Lambdas finden Sie hier vollständige Anleitung finden Sie im Anwendungs-Repository Navigieren Sie zum der Rockset-Konsole. Fügen Sie die folgende Abfrage in den Editor ein: Abschnitt „Abfrageeditor“ SELECT category, EXTRACT( month FROM transactionTime ) as month, EXTRACT( year FROM transactionTime ) as year, TRUNCATE(sum(amount), 2) AS amount FROM Transactions WHERE organization = :organization AND transactionTime > CURRENT_TIMESTAMP() - INTERVAL 3 MONTH GROUP BY category, month, year ORDER BY category, month, year DESC Diese Abfrage gruppiert Transaktionen der letzten drei Monate für eine bestimmte Organisation basierend auf der angegebenen Kategorie und dem Monat der Transaktion in Buckets. Anschließend werden die Werte für eine Kategorie nach Monat summiert, um den Gesamtbetrag zu ermitteln, der in jedem Monat ausgegeben wurde. Beachten Sie, dass es einen Parameter für das Attribut „organization“ enthält, wie durch die „:organization“-Syntax in der Abfrage angegeben. Dies weist darauf hin, dass ein Organisationswert übergeben werden muss, um die Abfrage auszuführen. Speichern Sie die Abfrage als Query Lambda in der Rockset-Konsole. Schauen Sie sich dann den an. Es ruft das Abfrage-Lambda namentlich auf und übergibt die von einem Benutzer angegebene Eigenschaft „Organisation“. fetchTransactionsByCategoryAndMonth-Code in unserer TransactionService-Klasse Dies ist ein viel einfacher zu handhabender Code in unserer Anwendung. Darüber hinaus bietet Rockset Versionskontrolle und abfragespezifische Überwachung für jedes Abfrage-Lambda. Dies macht es einfacher, Ihre Abfragen im Laufe der Zeit zu verwalten und zu verstehen, wie sich Änderungen in der Abfragesyntax auf die Leistung auswirken. Abschluss In diesem Beitrag haben wir gesehen, wie wir DynamoDB und Rockset gemeinsam nutzen können, um unseren Benutzern ein schnelles und angenehmes Anwendungserlebnis zu bieten. Dabei lernten wir sowohl die konzeptionellen Grundlagen als auch die praktischen Schritte zur Umsetzung unserer Anwendung kennen. Zuerst haben wir DynamoDB verwendet, um die Kernfunktionalität unserer Anwendung zu verwalten. Dazu gehören Zugriffsmuster wie das Abrufen eines Transaktions-Feeds für einen bestimmten Kunden oder das Anzeigen einer einzelnen Transaktion. Aufgrund der primärschlüsselbasierten Partitionierungsstrategie von DynamoDB ist es in der Lage, in jeder Größenordnung eine konsistente Leistung bereitzustellen. Das Design von DynamoDB schränkt jedoch auch seine Flexibilität ein. Es kann keine selektiven Abfragen für beliebige Felder oder Aggregationen über eine große Anzahl von Datensätzen hinweg verarbeiten. Um diese Muster zu verarbeiten, haben wir Rockset verwendet. Rockset bietet einen vollständig verwalteten Sekundärindex zur Unterstützung datenintensiver Anwendungen. Wir haben gesehen, wie Rockset eine kontinuierliche Aufnahmepipeline von Ihrem primären Datenspeicher aus verwaltet, die Ihre Daten in einem konvergenten Index indiziert, der invertierte, spaltenbasierte und Zeilenindizierung kombiniert. Als wir unsere Muster durchgingen, sahen wir, wie jede der Indexierungstechniken von Rockset zusammenwirkt, um ein angenehmes Benutzererlebnis zu ermöglichen. Schließlich haben wir die praktischen Schritte durchlaufen, um Rockset mit unserer DynamoDB-Tabelle zu verbinden und mit Rockset in unserer Anwendung zu interagieren. Erscheint auch . hier