Metodtips: Delta Lake

I den här artikeln beskrivs metodtips när du använder Delta Lake.

Databricks rekommenderar att du använder förutsägelseoptimering. Se Förutsägande optimering för Delta Lake.

När du tar bort och återskapar en tabell på samma plats bör du alltid använda en CREATE OR REPLACE TABLE instruktion. Se Släpp eller ersätt en Delta-tabell.

Använda flytande klustring för optimerad datahoppning

Databricks rekommenderar att du använder flytande klustring i stället för partitionering, Z-ordning eller andra strategier för dataorganisation för att optimera datalayouten för datahopp. Se Använda flytande klustring för Delta-tabeller.

Komprimera filer

Förutsägande optimering körs OPTIMIZE automatiskt och VACUUM kommandon i hanterade Unity Catalog-tabeller. Se Förutsägande optimering för Delta Lake.

Databricks rekommenderar att du ofta kör kommandot OPTIMIZE för att komprimera små filer.

Kommentar

Den här åtgärden tar inte bort de gamla filerna. Om du vill ta bort dem kör du kommandot VACUUM .

Ersätt innehållet eller schemat i en tabell

Ibland kanske du vill ersätta en Delta-tabell. Till exempel:

  • Du upptäcker att data i tabellen är felaktiga och vill ersätta innehållet.
  • Du vill skriva om hela tabellen för att göra inkompatibla schemaändringar (till exempel ändra kolumntyper).

Du kan ta bort hela katalogen i en Delta-tabell och skapa en ny tabell på samma sökväg, men det rekommenderas inte eftersom:

  • Det är inte effektivt att ta bort en katalog. En katalog som innehåller mycket stora filer kan ta timmar eller till och med dagar att ta bort.
  • Du förlorar allt innehåll i de borttagna filerna. det är svårt att återställa om du tar bort fel tabell.
  • Katalogborttagningen är inte atomisk. När du tar bort tabellen kan en samtidig fråga som läser tabellen misslyckas eller se en partiell tabell.

Om du inte behöver ändra tabellschemat kan du ta bort data från en Delta-tabell och infoga dina nya data, eller uppdatera tabellen för att åtgärda felaktiga värden.

Om du vill ändra tabellschemat kan du ersätta hela tabellen atomiskt. Till exempel:

Python

dataframe.write \
  .format("delta") \
  .mode("overwrite") \
  .option("overwriteSchema", "true") \
  .saveAsTable("<your-table>") # Managed table

dataframe.write \
  .format("delta") \
  .mode("overwrite") \
  .option("overwriteSchema", "true") \
  .option("path", "<your-table-path>") \
  .saveAsTable("<your-table>") # External table

SQL

REPLACE TABLE <your-table> USING DELTA AS SELECT ... -- Managed table
REPLACE TABLE <your-table> USING DELTA LOCATION "<your-table-path>" AS SELECT ... -- External table

Scala

dataframe.write
  .format("delta")
  .mode("overwrite")
  .option("overwriteSchema", "true")
  .saveAsTable("<your-table>") // Managed table

dataframe.write
  .format("delta")
  .mode("overwrite")
  .option("overwriteSchema", "true")
  .option("path", "<your-table-path>")
  .saveAsTable("<your-table>") // External table

Det finns flera fördelar med den här metoden:

  • Det går mycket snabbare att skriva över en tabell eftersom den inte behöver lista katalogen rekursivt eller ta bort några filer.
  • Den gamla versionen av tabellen finns fortfarande. Om du tar bort fel tabell kan du enkelt hämta gamla data med hjälp av tidsresor. Läs mer i Arbeta med Delta Lake-tabellhistorik.
  • Det är en atomisk operation. Samtidiga frågor kan fortfarande läsa tabellen medan du tar bort tabellen.
  • På grund av Delta Lake ACID-transaktionsgarantier är tabellen i sitt tidigare tillstånd om det inte går att skriva över tabellen.

Om du vill ta bort gamla filer för att spara lagringskostnader när du har skrivit över tabellen kan du dessutom använda VACUUM för att ta bort dem. Den är optimerad för borttagning av filer och är vanligtvis snabbare än att ta bort hela katalogen.

Spark-cachelagring

Databricks rekommenderar inte att du använder Spark-cachelagring av följande skäl:

  • Du förlorar alla data som hoppar över som kan komma från ytterligare filter som läggs till ovanpå den cachelagrade DataFrame.
  • Data som cachelagras kanske inte uppdateras om tabellen används med en annan identifierare.

Skillnader mellan Delta Lake och Parquet på Apache Spark

Delta Lake hanterar följande åtgärder automatiskt. Du bör aldrig utföra dessa åtgärder manuellt:

  • REFRESH TABLE: Deltatabeller returnerar alltid den senaste informationen, så du behöver inte anropa REFRESH TABLE manuellt efter ändringar.
  • Lägg till och ta bort partitioner: Delta Lake spårar automatiskt uppsättningen partitioner som finns i en tabell och uppdaterar listan när data läggs till eller tas bort. Därför behöver du inte köra ALTER TABLE [ADD|DROP] PARTITION eller MSCK.
  • Läs in en enskild partition: Det är inte nödvändigt att läsa partitioner direkt. Du behöver till exempel inte köra spark.read.format("parquet").load("/data/date=2017-01-01"). Använd i stället en WHERE sats för att hoppa över data, till exempel spark.read.table("<table-name>").where("date = '2017-01-01'").
  • Ändra inte datafiler manuellt: Delta Lake använder transaktionsloggen för att checka in ändringar i tabellen atomiskt. Ändra, lägg inte till eller ta bort Parquet-datafiler direkt i en Delta-tabell, eftersom detta kan leda till förlorade data eller skadade tabeller.

Förbättra prestanda för Delta Lake-sammanslagning

Du kan minska tiden det tar att slå samman med hjälp av följande metoder:

  • Minska sökutrymmet för matchningar: Som standard merge söker åtgärden igenom hela Delta-tabellen för att hitta matchningar i källtabellen. Ett sätt att påskynda merge är att minska sökutrymmet genom att lägga till kända begränsningar i matchningsvillkoret. Anta till exempel att du har en tabell som partitioneras av country och date som du vill använda merge för att uppdatera information för den senaste dagen och ett visst land. Om du lägger till följande villkor blir frågan snabbare eftersom den endast söker efter matchningar i relevanta partitioner:

    events.date = current_date() AND events.country = 'USA'
    

    Dessutom minskar den här frågan också risken för konflikter med andra samtidiga åtgärder. Mer information finns i Isoleringsnivåer och skrivkonflikter i Azure Databricks .

  • Kompakta filer: Om data lagras i många små filer kan det ta lång tid att läsa data för att söka efter matchningar. Du kan komprimera små filer till större filer för att förbättra läsdataflödet. Mer information finns i Komprimera datafiler med optimera på Delta Lake .

  • Kontrollera shuffle-partitionerna för skrivningar: Åtgärden merge blandar data flera gånger för att beräkna och skriva uppdaterade data. Antalet uppgifter som används för att blanda styrs av Spark-sessionskonfigurationen spark.sql.shuffle.partitions. Om du anger den här parametern styrs inte bara parallelliteten utan även antalet utdatafiler. Att öka värdet ökar parallelliteten men genererar också ett större antal mindre datafiler.

  • Aktivera optimerade skrivningar: För partitionerade tabeller merge kan du skapa ett mycket större antal små filer än antalet shuffle-partitioner. Det beror på att varje shuffle-uppgift kan skriva flera filer i flera partitioner och kan bli en flaskhals för prestanda. Du kan minska antalet filer genom att aktivera optimerade skrivningar. Se Optimerade skrivningar för Delta Lake på Azure Databricks.

  • Justera filstorlekar i tabellen: Azure Databricks kan automatiskt identifiera om en Delta-tabell har frekventa merge åtgärder som skriver om filer och kan välja att minska storleken på omskrivna filer i väntan på ytterligare filomskrivningar i framtiden. Mer information finns i avsnittet om hur du justerar filstorlekar .

  • Low Shuffle Merge: Low Shuffle Merge ger en optimerad implementering av MERGE som ger bättre prestanda för de vanligaste arbetsbelastningarna. Dessutom bevaras befintliga optimeringar av datalayouten, till exempel Z-beställning på oförändrade data.

Hantera dataåterhämtning

I början av varje fråga uppdateras Delta-tabeller automatiskt till den senaste versionen av tabellen. Den här processen kan observeras i notebook-filer när kommandostatusen rapporterar: Updating the Delta table's state. Men när du kör historisk analys på en tabell behöver du kanske inte nödvändigtvis upp till den sista minuten-data, särskilt för tabeller där strömmande data matas in ofta. I dessa fall kan frågor köras på inaktuella ögonblicksbilder av deltatabellen. Den här metoden kan minska svarstiden för att få resultat från frågor.

Du kan konfigurera tolerans för inaktuella data genom att ange Spark-sessionskonfigurationen spark.databricks.delta.stalenessLimit med ett tidssträngsvärde, till exempel 1h eller 15m (i 1 timme respektive 15 minuter). Den här konfigurationen är sessionsspecifik och påverkar inte andra klienter som kommer åt tabellen. Om tabelltillståndet har uppdaterats inom inaktuellhetsgränsen returnerar en fråga mot tabellen resultat utan att vänta på den senaste tabelluppdateringen. Den här inställningen förhindrar aldrig att tabellen uppdateras, och när inaktuella data returneras bearbetas uppdateringsprocesserna i bakgrunden. Om den senaste tabelluppdateringen är äldre än föråldringsgränsen returnerar frågan inte resultat förrän uppdateringen av tabelltillståndet har slutförts.

Förbättrade kontrollpunkter för frågor med låg svarstid

Delta Lake skriver kontrollpunkter som ett aggregerat tillstånd för en Delta-tabell med en optimerad frekvens. Dessa kontrollpunkter fungerar som utgångspunkt för att beräkna tabellens senaste tillstånd. Utan kontrollpunkter skulle Delta Lake behöva läsa en stor samling JSON-filer ("delta"-filer) som representerar incheckningar i transaktionsloggen för att beräkna tillståndet för en tabell. Dessutom lagras den kolumnnivåstatistik som Delta Lake använder för att hoppa över data i kontrollpunkten.

Viktigt!

Delta Lake-kontrollpunkter skiljer sig från kontrollpunkter för strukturerad strömning.

Statistik på kolumnnivå lagras som en struct och en JSON (för bakåtkompatibilitet). Struct-formatet gör Delta Lake-läsningar mycket snabbare, eftersom:

  • Delta Lake utför inte dyr JSON-parsning för att hämta statistik på kolumnnivå.
  • Parquet-kolumnrensningsfunktioner minskar avsevärt I/O som krävs för att läsa statistiken för en kolumn.

Struct-formatet möjliggör en samling optimeringar som minskar omkostnaderna för Delta Lake-läsåtgärder från sekunder till tiotals millisekunder, vilket avsevärt minskar svarstiden för korta frågor.

Hantera statistik på kolumnnivå i kontrollpunkter

Du hanterar hur statistik skrivs i kontrollpunkter med hjälp av tabellegenskaperna delta.checkpoint.writeStatsAsJson och delta.checkpoint.writeStatsAsStruct. Om båda tabellegenskaperna är falsekan Delta Lake inte hoppas över data.

  • Batch skriver skrivstatistik i både JSON- och struct-format. delta.checkpoint.writeStatsAsJson är true.
  • delta.checkpoint.writeStatsAsStruct är odefinierad som standard.
  • Läsare använder struct-kolumnen när den är tillgänglig och återgår i övrigt till att använda JSON-kolumnen.

Viktigt!

Förbättrade kontrollpunkter bryter inte kompatibiliteten med öppen källkod Delta Lake-läsare. Inställningen kan dock delta.checkpoint.writeStatsAsJsonfalse få konsekvenser för upphovsrättsskyddade Delta Lake-läsare. Kontakta dina leverantörer om du vill veta mer om prestandakonsekvenser.

Aktivera förbättrade kontrollpunkter för frågor om strukturerad direktuppspelning

Om dina arbetsbelastningar för strukturerad direktuppspelning inte har krav på låg svarstid (svarstider för underminut) kan du aktivera förbättrade kontrollpunkter genom att köra följande SQL-kommando:

ALTER TABLE [<table-name>|delta.`<path-to-table>`] SET TBLPROPERTIES
('delta.checkpoint.writeStatsAsStruct' = 'true')

Du kan också förbättra svarstiden för kontrollpunktsskrivning genom att ange följande tabellegenskaper:

ALTER TABLE [<table-name>|delta.`<path-to-table>`] SET TBLPROPERTIES
(
 'delta.checkpoint.writeStatsAsStruct' = 'true',
 'delta.checkpoint.writeStatsAsJson' = 'false'
)

Om datahoppning inte är användbart i ditt program kan du ange båda egenskaperna till false. Då samlas ingen statistik in eller skrivs. Databricks rekommenderar inte den här konfigurationen.