Een schema voor gegevenspartitionering ontwerpen en implementeren

Voltooid

Gegevenspartitionering is rechtstreeks van invloed op hoe efficiënt uw query's worden uitgevoerd en hoeveel rekenresources u verbruikt. Wanneer u een tabel partitioneert, verdeelt u gegevens in afzonderlijke segmenten op basis van kolomwaarden, zodat de query-engine alleen relevante delen van uw gegevensset kan lezen. Deze benadering, partition pruning genoemd, kan gegevensscans aanzienlijk verminderen wanneer filters overeenkomen met de partitiegrenzen.

Overweeg een retailbedrijf dat miljoenen dagelijkse verkooptransacties verwerkt. Analisten voeren regelmatig query's uit op gegevens op datumbereiken om wekelijkse rapporten te genereren, trends per maand te vergelijken en seizoensgebonden patronen te analyseren. Zonder partitionering scant elke query de volledige transactiegeschiedenis. Met de juiste partitionering op datum raken query's voor een specifieke week slechts een fractie van de opgeslagen bestanden aan.

Bepalen wanneer partitionering van toepassing is

Databricks raadt u aan tabellen met minder dan 1 TB aan gegevens niet te partitioneren. Voor kleinere tabellen weegt de overhead van het beheren van partitiemetagegevens en het potentieel voor het maken van veel kleine bestanden op tegen de voordelen van queryprestaties. Niet-gepartitioneerde Delta-tabellen in recente Databricks Runtime-versies profiteren automatisch van opnametijdclustering, wat vergelijkbare queryvoordelen biedt zonder expliciete configuratie.

Wanneer uw tabellen groter zijn dan 1 TB, wordt partitioneren een waardevolle optimalisatietechniek. Op deze schaal worden de voordelen van het lezen van alleen relevante gegevenssegmenten aanzienlijk gecompenseerd door de kosten van partitiebeheer. Partitionering maakt ook parallelle verwerking mogelijk, omdat Spark verschillende partities kan verdelen over clusterknooppunten voor gelijktijdige uitvoering.

Belangrijk

Elke partitie moet ten minste 1 GB aan gegevens bevatten. Deze richtlijn helpt u bij het vermijden van overpartitionering, waardoor overmatige kleine bestanden worden gemaakt en de queryprestaties afnemen.

Diagram waarmee u kunt bepalen wanneer partitionering van toepassing is.

Voor zeer grote tabellen in het honderden terabytes-bereik biedt partitionering nog meer voordelen. Op deze schaal vermindert partitioneren aanzienlijk de hoeveelheid gegevens die de query-engine moet verwerken, waardoor de prestaties en kostenefficiëntie worden verbeterd.

Effectieve partitiesleutels kiezen

Voor de selectie van partitiesleutels moet u inzicht hebben in uw gegevenskenmerken en querypatronen. Effectieve partitiesleutels delen veelvoorkomende eigenschappen die de prestatievoordelen maximaliseren terwijl veelvoorkomende valkuilen worden vermeden.

Kolommen met lage kardinaliteit werken het beste

Kies kolommen met een beperkt aantal afzonderlijke waarden. Datumkolommen, geografische regio's, productcategorieën en statusvelden maken uitstekende partitiesleutels omdat ze een beheerbaar aantal partities maken. Een kolom met duizenden of miljoenen unieke waarden, zoals klant-id of transactie-id, leidt tot overpartitionering en slechte prestaties.

Als u bijvoorbeeld een verkooptabel partitioneert op sale_date dagelijks niveau, kunnen er 365 partities per jaar worden gemaakt. Als elke dag voldoende gegevensvolume bevat, werkt deze granulariteit goed. Partitionering op sale_timestamp het tweede niveau zou echter miljoenen partities maken, elk met minimale gegevens.

Afstemmen op query-patronen

Uw partitiesleutel moet overeenkomen met de kolommen waarop gebruikers het vaakst filteren. Als analisten consistent query's uitvoeren op verkoopgegevens per datumbereik, maakt partitioneren op datum efficiënt snoeien mogelijk. Als query's voornamelijk filteren op regio, kunt u in plaats daarvan regio als uw partitiesleutel beschouwen.

Wanneer er meerdere filterpatronen bestaan, geeft u prioriteit aan de meest voorkomende of meest prestatiekritische query's. U kunt één partitioneringsschema per tabel definiëren, dus kies kolommen die het merendeel van uw workload ten goede komen. Voor aanzienlijk verschillende querypatronen kunt u afzonderlijke geoptimaliseerde gerealiseerde weergaven of overzichtstabellen maken voor specifieke gebruiksvoorbeelden.

Houd rekening met gegevensgroei in de loop van de tijd

Selecteer een partitieschema dat op de juiste manier wordt geschaald naarmate uw gegevens groeien. Partitionering per jaar werkt in eerste instantie goed, maar kan partities maken die na verloop van tijd te groot zijn. Partitionering per uur werkt daarentegen mogelijk voor gegevens met een groot volume, maar maakt te veel kleine partities voor gemiddelde volumes.

Evalueer de verwachte groeisnelheid van gegevens bij het kiezen van partitiegranulariteit. Een balans tussen de partitiegrootte en het aantal partities helpt consistente queryprestaties te behouden naarmate uw gegevensset uitbreidt.

Overweeg ook gegevensdistributie over partities. Ernstig ongelijke partitiegrootten kunnen verwerkingsknelpunten veroorzaken, omdat knooppunten die grotere partities verwerken meer tijd nodig hebben, terwijl anderen niets te doen hebben.

Partities implementeren in Azure Databricks

U definieert partities bij het maken van een tabel met behulp van de PARTITIONED BY component in SQL of de partitionBy methode in PySpark. Zodra u partities hebt ingesteld, stuurt Azure Databricks binnenkomende gegevens automatisch naar de juiste partitiemappen op basis van kolomwaarden.

Een gepartitioneerde tabel maken met SQL

In het volgende voorbeeld wordt een tabel met verkooptransacties gemaakt die is gepartitioneerd op de transactiedatum:

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);

Wanneer u een query uitvoert op deze tabel met een datumfilter, leest de query-engine alleen de partities die voldoen aan uw filtercriteria:

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;

Een gepartitioneerde tabel maken met PySpark

Wanneer u PySpark gebruikt, geeft u partitionering op tijdens de schrijfbewerking:

df.write.format("delta") \
    .partitionBy("transaction_date") \
    .saveAsTable("sales.transactions")

Voor volgende schrijfbewerkingen houdt u consistentie bij door dezelfde partitiespecificatie op te volgen:

new_transactions_df.write.format("delta") \
    .mode("append") \
    .partitionBy("transaction_date") \
    .saveAsTable("sales.transactions")

Gegenereerde kolommen gebruiken voor flexibiliteit van partities

Gegenereerde kolommen bieden een manier om partitiewaarden af te leiden van bestaande kolommen zonder redundante gegevens op te slaan. Deze methode is handig wanneer uw brongegevens tijdstempels bevatten, maar u wilt partitioneren op datum:

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);

Aanbeveling

Met deze configuratie genereert Delta Lake automatisch partitiefilters wanneer u een query uitvoert op de basistijdstempelkolom. Een query die filtert op transaction_timestamp profiteert van partitie-inkorting zonder expliciete datumfilters.

Veelvoorkomende partitioneringsfouten voorkomen

Begrijpen wat u moet vermijden, is net zo belangrijk als weten wat u moet doen. Verschillende veelvoorkomende fouten kunnen de prestaties aanzienlijk verminderen en het beheer van gegevens bemoeilijken.

Diagram waarin veelvoorkomende partitioneringsfouten worden uitgelegd.

Bij overpartitionering ontstaan problemen met kleine bestanden

Het maken van te veel partities, elk met onvoldoende gegevens, leidt tot kleine bestandsproblemen. Wanneer partities bestanden bevatten die kleiner zijn dan de grootte van het doelbestand, lijden queryprestaties aan overmatige metagegevensbewerkingen en verminderde leesefficiëntie. Streven naar partities met ten minste 1 GB aan gegevens.

Tekenen van overpartitionering zijn trage queryprestaties, ondanks het verwijderen van partities, een groot aantal kleine bestanden in partitiemappen en lange tabeloptimalisatietijden. Als u deze symptomen ziet, kunt u overwegen een grovere partitiegranulariteit te kiezen.

Partitioneren op kolommen met hoge kardinaliteit mislukt

Kolommen met veel unieke waarden maken slechte partitiesleutels. Partitionering op klant-id, transactie-id of andere kolommen met hoge kardinaliteit maakt miljoenen partities die afnemen in plaats van de prestaties te verbeteren. Reserveer optimalisatie van kolommen met hoge kardinaliteit voor andere technieken die voor dit doel zijn ontworpen.

Voor het wijzigen van partities moeten gegevens opnieuw worden geschreven

Partitiekolommen maken deel uit van de tabelstructuur. Als u de partitioneringsstrategie wijzigt, moet u de hele tabel herschrijven naar een nieuwe locatie met verschillende partitiegrenzen. Deze bewerking verbruikt aanzienlijke rekenresources en tijd voor grote tabellen.

Plan uw partitioneringsstrategie zorgvuldig voordat u gegevens op schaal laadt. Overweeg toekomstige querypatronen en gegevensgroei om kostbare herstructurering later te voorkomen.

Beslissingen voor documentpartitionering

Noteer uw partitiesleutelkeuzen en de redenering erachter. Deze documentatie helpt teamleden inzicht te krijgen in mogelijkheden voor queryoptimalisatie en voorkomt onbedoelde wijzigingen die van invloed kunnen zijn op de prestaties. Neem informatie op over de verwachte partitiegrootten, querypatronen die profiteren van het schema en eventuele beperkingen die van invloed zijn op uw beslissingen.

Overweeg vloeistofclustering als alternatief

Wanneer u partitieproblemen ondervindt, met name bij kolommen met hoge kardinaliteit , zoals tijdstempels of wanneer querypatronen onzeker zijn, biedt liquide clustering een modern alternatief. In tegenstelling tot traditionele partitionering biedt liquid clustering:

  • Flexibiliteit om optimalisatiestrategieën aan te passen zonder gegevens te herschrijven
  • Automatisch onderhoud naarmate tabellen groeien
  • Minder overhead voor partitiebeheer

Liquid clustering is de aanbevolen benadering voor nieuwe tabellen waarbij partitioneringsbeperkingen de prestaties zouden beperken of overmatige onderhoudslast zouden creëren. Het is met name effectief voor tabellen die groter zijn dan 1 TB en waarvoor u moet filteren op kolommen die te veel partities zouden maken met behulp van traditionele benaderingen.

Opmerking

Liquid clustering is niet compatibel met gepartitioneerde tabellen. Kies één benadering op basis van uw vereisten bij het ontwerpen van nieuwe tabellen.

Raadpleeg voor implementatiedetails, syntaxis en optimalisatiestrategieën het ontwerp en implementeer een clusterstrategie-eenheid verderop in deze module.