Entwerfen und Implementieren eines Datenpartitionierungsschemas
Die Datenpartitionierung wirkt sich direkt darauf aus, wie effizient Ihre Abfragen ausgeführt werden und wie viel Rechenressourcen Sie verbrauchen. Wenn Sie eine Tabelle partitionieren, teilen Sie Daten basierend auf Spaltenwerten in einzelne Segmente auf, sodass das Abfragemodul nur relevante Teile Ihres Datasets lesen kann. Dieser Ansatz, der als Partitionskürzung bezeichnet wird, kann die Datenüberprüfung erheblich reduzieren, wenn Filter an Partitionsgrenzen ausgerichtet sind.
Betrachten Sie ein Einzelhandelsunternehmen, das Millionen täglicher Verkaufstransaktionen verarbeitet. Analysten fragen häufig Daten nach Datumsbereichen ab, um wöchentliche Berichte zu generieren, Monats-über-Monat-Trends zu vergleichen und saisonale Muster zu analysieren. Ohne Partitionierung durchsucht jede Abfrage den gesamten Transaktionsverlauf. Bei ordnungsgemäßer Partitionierung nach Datum berühren Abfragen für eine bestimmte Woche nur einen Bruchteil der gespeicherten Dateien.
Bestimmen, wann die Partitionierung gilt
Databricks empfiehlt, Tabellen mit weniger als 1 TB Daten nicht zu partitionieren. Bei kleineren Tabellen übersteigen der Aufwand bei der Verwaltung von Partitionsmetadaten und das Potenzial zur Erstellung vieler kleiner Dateien alle potenziellen Leistungsvorteile von Abfragen. Nicht partitionierte Delta-Tabellen in den neuesten Databricks-Runtime-Versionen profitieren automatisch vom Aufnahmezeit-Clustering, das ähnliche Abfragevorteile ohne explizite Konfiguration bietet.
Wenn Ihre Tabellen 1 TB überschreiten, wird die Partitionierung zu einer wertvollen Optimierungsmethode. In diesem Maßstab wiegen die Vorteile des Lesens von nur relevanten Datensegmenten die Kosten für die Partitionsverwaltung erheblich auf. Die Partitionierung ermöglicht auch die parallele Verarbeitung, da Spark unterschiedliche Partitionen für die gleichzeitige Ausführung über Clusterknoten verteilen kann.
Von Bedeutung
Jede Partition sollte mindestens 1 GB Daten enthalten. Diese Richtlinie hilft Ihnen, eine übermäßige Partitionierung zu vermeiden, wodurch übermäßige kleine Dateien erstellt und die Abfrageleistung beeinträchtigt wird.
Für sehr große Tabellen im Hunderten von Terabyte-Bereich bietet Partitionierung noch größere Vorteile. In diesem Maßstab reduziert die Partitionskürzung erheblich die Menge der Daten, die das Abfragemodul verarbeiten muss, und verbessert sowohl die Leistung als auch die Kosteneffizienz.
Auswählen effektiver Partitionsschlüssel
Die Partitionsschlüsselauswahl erfordert, dass Sie Ihre Datenmerkmale und Abfragemuster verstehen. Effektive Partitionsschlüssel teilen gemeinsame Merkmale, die Leistungsvorteile maximieren und gleichzeitig häufige Fallstricke vermeiden.
Spalten mit niedriger Kardinalität funktionieren am besten
Wählen Sie Spalten mit einer begrenzten Anzahl unterschiedlicher Werte aus. Datumsspalten, geografische Regionen, Produktkategorien und Statusfelder machen hervorragende Partitionsschlüssel, da sie eine verwaltbare Anzahl von Partitionen erstellen. Eine Spalte mit Tausenden oder Millionen eindeutiger Werte, z. B. Kunden-ID oder Transaktions-ID, führt zu einer Überpartitionierung und schlechter Leistung.
Wenn Sie z.B. eine Verkaufstabelle nach sale_date auf täglicher Ebene partitionieren, können Sie 365 Partitionen pro Jahr erstellen. Wenn jeder Tag genügend Datenvolumen enthält, funktioniert diese Granularität gut. Die Partitionierung auf sale_timestamp der zweiten Ebene würde jedoch Millionen von Partitionen erstellen, die jeweils minimale Daten enthalten.
An Abfragemuster anpassen
Ihr Partitionsschlüssel sollte mit den Spalten übereinstimmen, nach denen Benutzer am häufigsten filtern. Wenn Analysten Umsatzdaten konsistent nach Datumsbereichen abfragen, ermöglicht die Partitionierung nach Datum eine effiziente Beschnittung. Wenn Abfragen in erster Linie nach Region gefiltert werden, sollten Sie stattdessen "Region" als Partitionsschlüssel betrachten.
Wenn mehrere Filtermuster vorhanden sind, priorisieren Sie die am häufigsten verwendeten oder leistungskritischen Abfragen. Sie können ein Partitionierungsschema pro Tabelle definieren. Wählen Sie daher Spalten aus, die den Großteil Ihrer Workload nutzen. Bei erheblich unterschiedlichen Abfragemustern sollten Sie separate optimierte materialisierte Ansichten oder Zusammenfassungstabellen für bestimmte Anwendungsfälle erstellen.
Berücksichtigen des Datenwachstums im Laufe der Zeit
Wählen Sie ein Partitionsschema aus, das entsprechend skaliert wird, wenn Ihre Daten wachsen. Die Partitionierung nach Jahr funktioniert anfangs gut, kann aber Partitionen erstellen, die im Laufe der Zeit zu groß sind. Umgekehrt kann die Partitionierung nach Stunden für Daten mit hohem Volumen funktionieren, erzeugt jedoch zu viele kleine Partitionen bei moderatem Volumen.
Bewerten Sie die erwartete Datenwachstumsrate bei der Auswahl der Partitionsgranularität. Ein Gleichgewicht zwischen Partitionsgröße und der Anzahl der Partitionen trägt dazu bei, die konsistente Abfrageleistung aufrechtzuerhalten, wenn das Dataset erweitert wird.
Berücksichtigen Sie auch die Datenverteilung über Partitionen hinweg. Stark ungleiche Partitionsgrößen können Verarbeitungsengpässe erzeugen, da Knoten, die größere Partitionen verarbeiten, mehr Zeit benötigen, während andere untätig bleiben.
Implementieren von Partitionen in Azure Databricks
Sie definieren Partitionen beim Erstellen einer Tabelle mithilfe der PARTITIONED BY Klausel in SQL oder der partitionBy Methode in PySpark. Nachdem Sie Partitionen festgelegt haben, leitet Azure Databricks eingehende Daten automatisch basierend auf Spaltenwerten an die entsprechenden Partitionsverzeichnisse weiter.
Erstellen einer partitionierten Tabelle mit SQL
Im folgenden Beispiel wird eine Verkaufsbuchungstabelle erstellt, die nach dem Transaktionsdatum partitioniert wird:
CREATE TABLE sales.transactions (
transaction_id STRING,
customer_id STRING,
product_id STRING,
quantity INT,
unit_price DECIMAL(10,2),
total_amount DECIMAL(12,2),
transaction_date DATE
)
PARTITIONED BY (transaction_date);
Wenn Sie diese Tabelle mit einem Datumsfilter abfragen, liest das Abfragemodul nur die Partitionen, die Ihren Filterkriterien entsprechen:
SELECT product_id, SUM(total_amount) AS revenue
FROM sales.transactions
WHERE transaction_date BETWEEN '2024-01-01' AND '2024-01-31'
GROUP BY product_id;
Erstellen einer partitionierten Tabelle mit PySpark
Geben Sie bei Verwendung von PySpark die Partitionierung während des Schreibvorgangs an:
df.write.format("delta") \
.partitionBy("transaction_date") \
.saveAsTable("sales.transactions")
Behalten Sie bei nachfolgenden Schreibvorgängen die Konsistenz bei, indem Sie dieselbe Partitionsspezifikation einschließen:
new_transactions_df.write.format("delta") \
.mode("append") \
.partitionBy("transaction_date") \
.saveAsTable("sales.transactions")
Verwenden von generierten Spalten zur Partitionsflexibilität
Generierte Spalten bieten eine Möglichkeit, Partitionswerte von vorhandenen Spalten abzuleiten, ohne redundante Daten zu speichern. Dieser Ansatz ist nützlich, wenn Ihre Quelldaten Zeitstempel enthalten, sie jedoch nach Datum partitionieren möchten:
CREATE TABLE sales.transactions (
transaction_id STRING,
customer_id STRING,
product_id STRING,
quantity INT,
unit_price DECIMAL(10,2),
total_amount DECIMAL(12,2),
transaction_timestamp TIMESTAMP,
transaction_date DATE GENERATED ALWAYS AS (CAST(transaction_timestamp AS DATE))
)
PARTITIONED BY (transaction_date);
Tipp
Mit dieser Konfiguration generiert Delta Lake automatisch Partitionsfilter, wenn Sie bei Abfragen mit der Basistime-Stamp-Spalte arbeiten. Eine Abfragefilterung bei transaction_timestamp profitiert von Partitions-Pruning, ohne dass explizite Datumsfilter erforderlich sind.
Vermeiden häufiger Partitionierungsfehler
Das Verstehen, was vermieden werden soll, ist ebenso wichtig wie das Wissen darüber, was zu tun ist. Mehrere häufige Fehler können die Leistung erheblich beeinträchtigen und die Datenverwaltung erschweren.
Die Überpartitionierung verursacht kleine Dateiprobleme.
Das Erstellen zu vieler Partitionen, die jeweils unzureichende Daten enthalten, führt zu kleinen Dateiproblemen. Wenn Partitionen Dateien enthalten, die kleiner als die Zieldateigröße sind, leidet die Abfrageleistung unter übermäßigen Metadatenvorgängen und verringerter Leseeffizienz. Zielen Sie auf Partitionen mit mindestens 1 GB Daten ab.
Anzeichen einer Überpartitionierung umfassen eine langsame Abfrageleistung trotz Partitionslöschung, eine große Anzahl kleiner Dateien in Partitionsverzeichnissen und lange Tabellenoptimierungszeiten. Wenn Sie diese Symptome beobachten, sollten Sie eine gröbere Partitionsgranularität auswählen.
Partitionierung auf Spalten mit hoher Kardinalität schlägt fehl
Spalten mit vielen eindeutigen Werten sind schlecht als Partitionsschlüssel geeignet. Durch die Partitionierung nach Kunden-ID, Transaktions-ID oder anderen Spalten mit hoher Kardinalität werden Millionen von Partitionen erstellt, die die Leistung beeinträchtigen, anstatt die Leistung zu verbessern. Reservieren Sie die Optimierung von Spalten mit hoher Kardinalität für andere Techniken, die für diesen Zweck entwickelt wurden.
Das Ändern von Partitionen erfordert das Umschreiben von Daten.
Partitionsspalten sind Teil der Tabellenstruktur. Wenn Sie Ihre Partitionierungsstrategie ändern, müssen Sie die gesamte Tabelle an einen neuen Speicherort mit unterschiedlichen Partitionsgrenzen umschreiben. Dieser Vorgang verbraucht erhebliche Rechenressourcen und -zeit für große Tabellen.
Planen Sie Ihre Partitionierungsstrategie sorgfältig, bevor Sie Daten in großem Umfang laden. Berücksichtigen Sie zukünftige Abfragemuster und Datenwachstum, um kostspielige Umstrukturierungen später zu vermeiden.
Entscheidungen zur Dokumentpartitionierung
Notieren Sie Ihre Partitionsschlüsselauswahl und die zugrundeliegenden Gründe. Diese Dokumentation hilft Teammitgliedern, Abfrageoptimierungsmöglichkeiten zu verstehen und versehentliche Änderungen zu verhindern, die sich auf die Leistung auswirken könnten. Enthalten Sie Informationen zu erwarteten Partitionsgrößen, Abfragemustern, die vom Schema profitieren, und alle Einschränkungen, die Ihre Entscheidungen beeinflusst haben.
Erwägen Sie das Flüssigclustering als Alternative
Bei Partitionierungsproblemen – insbesondere bei Spalten mit hoher Kardinalität wie Zeitstempeln oder unsicheren Abfragemustern – bietet flüssige Clustering eine moderne Alternative. Im Gegensatz zur herkömmlichen Partitionierung bietet das Flüssigclustering Folgendes:
- Flexibilität beim Anpassen von Optimierungsstrategien ohne Umschreiben von Daten
- Automatische Wartung, wenn Tabellen wachsen
- Reduzierter Partitionsverwaltungsaufwand
Flüssiges Clustering ist der empfohlene Ansatz für neue Tabellen, bei denen Partitionierungseinschränkungen die Leistung einschränken oder übermäßige Wartungslasten verursachen würden. Es ist besonders effektiv für Tabellen, die 1 TB überschreiten, und erfordert das Filtern nach Spalten, die zu viele Partitionen mit herkömmlichen Ansätzen erstellen würden.
Hinweis
Flüssiges Clustering ist nicht mit partitionierten Tabellen kompatibel. Wählen Sie einen Ansatz basierend auf Ihren Anforderungen beim Entwerfen neuer Tabellen aus.
Informationen zu Implementierungsdetails, Syntax und Optimierungsstrategien finden Sie im Design und Implementieren einer Clusteringstrategieeinheit weiter unten in diesem Modul.