PostgreSQL ist eine der beliebtesten relationalen Datenbanken – leistungsstark, zuverlässig und mit einer großen Community. Doch sobald die Datenmenge wächst und Anforderungen an horizontale Skalierung bestehen, stößt eine einzelne PostgreSQL-Instanz oder ein replizierter Cluster schnell an Grenzen. Hier schafft Citus Abhilfe.
Citus erweitert PostgreSQL um verteilte Datenverarbeitung. Es verwandelt eine einzelne Instanz in einen skalierbaren Cluster, der große Datenmengen effizient über mehrere Knoten hinweg verarbeiten kann. In diesem Beitrag werfen wir einen Blick auf die Funktionsweise von Citus, zeigen Code-Beispiele und erklären, wie Citus euch dabei helfen kann, große Datenmengen zu meistern, zum Beispiel in Kombination mit Patroni für Hochverfügbarkeit.
Wie funktioniert Citus?
Citus arbeitet als PostgreSQL-Erweiterung und nutzt ein verteiltes Architekturmodell mit einem Koordinator und mehreren Worker-Knoten:
- Koordinator: Nimmt SQL-Anfragen entgegen, analysiert sie und plant die Ausführung über die Worker
- Worker: Speichert Daten in Shards (Teilbereiche einer Tabelle) und führt Anfragen parallel aus. Applikationen kommunizieren mit dem Koordinator, der die Abfragen, je nach angefragten Tabellen, an einen der Worker weiterleitet.
Konfiguration
Citus bietet eine Vielzahl an Konfigurationsmöglichkeiten für eure Datenbanksysteme. Besonders hervorzuheben sind dabei die folgenden Funktionen:
Verteilte Tabellen
Verteilte Tabellen sind ein zentrales Konzept in Citus. Sie ermöglichen es, große Tabellen horizontal zu partitionieren, also in kleinere Einheiten aufzuteilen, die auf den Workern gespeichert werden. Hierfür existieren zwei Arten der Partitionierung:
Zeilenbasierte Partitionierung (Row-based Sharding): Hierbei wird eine Tabelle anhand einer Distributionsspalte (z. B. tenant_id) aufgeteilt. Die einzelnen Zeilen werden abhängig vom Wert dieser Spalte auf verschiedene Knoten im Cluster verteilt. Alle Mandanten (Tenants) befinden sich dabei in derselben Tabelle, unterscheiden sich aber durch den Wert der Distributionsspalte. Diese Methode bietet die beste Performance und Speicherausnutzung, erfordert jedoch, dass alle Tabellen diese Spalte enthalten.
Wenn wir beispielsweise drei Nodes und eine Tabelle „Users“ in der folgenden Form haben, können wir z. B. nach dem Attribut „country
“ sharden. Dies geschieht durch den Aufruf der Citus-Utility-Function create_distributed_table
, der der Tabellenname und der Name der Spalte übergeben wird, nach der gesharded werden soll. Citus generiert daraufhin eigenständig eine Hashing-Funktion, nach der die Daten auf die unterschiedlichen Nodes aufgeteilt werden. In diesem Beispiel werden konkret alle Nutzenden aus unterschiedlichen Ländern auf unterschiedlichen Nodes abgelegt.
Die Sharding-Spalte muss darüber hinaus nicht domänenbeschränkt sein. Genauso sind id's oder sonstige Attribute zulässig.
Schemabasierte Partitionierung (Schema-based Sharding): Bei dieser Methode erhält jeder Mandant ein eigenes Schema, das logisch als Shard behandelt wird. Die Anwendung muss nur sicherstellen, dass beim Zugriff auf Daten der richtige „search_path“ gesetzt ist. Diese Variante ist besonders geeignet für Anwendungen mit unterschiedlichen Mandantenanforderungen, etwa wenn die Datenmodelle variieren oder keine tiefgreifenden Änderungen an Abfragen und Tabellen möglich sind. Sie ist einfacher zu integrieren, skaliert aber nicht ganz so effizient wie die zeilenbasierte Variante.
Die Tabellen tenant_a.invoices
und tenant_b.invoices
können so auf unterschiedliche Nodes verteilt werden.
Referenztabellen
Neben Sharding unterstützt Citus auch Replikation durch Referenztabellen. Diese sind meist kleine Tabellen, die nur in einem Shard angelegt werden und an alle anderen Worker repliziert werden. Somit hat jeder Worker effizienten Zugriff auf die Daten in der Referenztabelle. Diese eignen sich besonders gut für statische oder sich selten ändernde Daten, die von vielen verteilten Tabellen gemeinsam genutzt werden, wie z. B. Ländercodes, Währungen, Produkttypen oder Konfigurationstabellen. Da sie vollständig auf jedem Knoten vorhanden sind, ermöglichen sie schnelle Joins mit verteilten Tabellen, ohne dass zusätzliche Netzwerkkommunikation notwendig ist.
Lokale Tabellen
Diese Tabellen sind die Standardtabellen, die in jeder Node erstellt werden können. Sie werden (ohne spezielle Konfiguration) weder gesharded noch repliziert. Somit existiert eine lokale Tabelle nur auf einem Node. In der Regel werden solche Tabellen für Metadaten verwendet.
Citus + Patroni = HA Sharding
Wie wir bereits gesehen haben, bietet Citus horizontale Skalierung. Wie sieht es aber mit Ausfallsicherheit aus? Ein bewährtes Tool für High Availability mit automatischem Failover unter PostgreSQL ist Patroni. Nähere Informationen zu Patroni findet ihr unter diesem Link.
Bei einer geshardeten Datenbankarchitektur kann Patroni nicht wie bei normalen PostgreSQL-Clustern verwendet werden. Stattdessen muss für jeden Node, der repliziert werden soll, ein eigenes Patroni-Cluster aufgebaut werden. Folgendes Architekturbild soll dies veranschaulichen:
In dieser Architektur ist jede Rolle – sowohl der Koordinator als auch die Worker – als eigenständiger Hochverfügbarkeits-Cluster ausgelegt. Jeder Cluster besteht aus einer Primary-Instanz und einer oder mehreren Replikas, die durch Patroni orchestriert werden. Die übergreifende Koordination erfolgt über einen zentralen Distributed Configuration Store, etwa etcd oder Consul, der als gemeinsame Grundlage für Leader-Election und Cluster-Metatdaten dient.
Fazit
Citus macht PostgreSQL fit für große Datenmengen und parallele Verarbeitung, ohne dass man sich von der vertrauten PostgreSQL-Umgebung verabschieden muss. In Kombination mit Patroni lässt sich nicht nur Skalierbarkeit, sondern auch Hochverfügbarkeit erreichen – ideal für produktive Anwendungen mit wachsender Last.
Allerdings muss beachtet werden, dass Datenbank-Sharding immer höhere Latenzen bei Datenbankabfragen mit sich bringt, weswegen bei jedem Use Case abgewogen werden muss, ob die Vorteile überwiegen.
Bei Fragen zur Installation oder Konfiguration stehen wir euch jederzeit gerne zur Verfügung.
Wenn ihr tiefer in die Welt von PostgreSQL eintauchen möchtet, laden wir euch herzlich ein, an unseren Seminaren teilzunehmen. Sprecht uns dafür gerne an oder informiert euch auf unserer Seminar-Website.
Seminarempfehlung
POSTGRESQL ADMINISTRATION DB-PG-01
Mehr erfahren