Best practices: Delta Lake

In dit artikel worden de best practices beschreven voor het gebruik van Delta Lake.

Hints voor gegevenslocatie opgeven

Als u verwacht dat een kolom veel wordt gebruikt in querypredicaten en als die kolom een hoge kardinaliteit heeft (dat wil zeggen, een groot aantal afzonderlijke waarden), gebruikt u Z-ORDER BY . Delta Lake bepaalt automatisch de gegevens in de bestanden op basis van de kolomwaarden en gebruikt de indelingsinformatie om irrelevante gegevens over te slaan tijdens het uitvoeren van query's.

Zie Z-Ordering (multi-dimensional clustering) voor meer informatie.

De juiste partitiekolom kiezen

U kunt een Delta-tabel partitioneren op een kolom. De meest gebruikte partitiekolom is date . Volg deze twee vuistregels om te bepalen op welke kolom u wilt partitioneren op:

  • Als de kardinaliteit van een kolom zeer hoog is, moet u die kolom niet gebruiken voor partitionering. Als u bijvoorbeeld partitioneert op een kolom en als er 1 miljoen afzonderlijke gebruikers-ID's kunnen zijn, is dat een slechte userId partitioneringsstrategie.
  • Hoeveelheid gegevens in elke partitie: u kunt partitioneren op een kolom als u verwacht dat de gegevens in die partitie ten minste 1 GB zijn.

Compacte bestanden

Als u continu gegevens naar een Delta-tabel schrijft, worden er na een periode een groot aantal bestanden verzameld, met name als u gegevens in kleine batches toevoegt. Dit kan een negatief effect hebben op de efficiƫntie van tabellezen en kan ook van invloed zijn op de prestaties van uw bestandssysteem. In het ideale geval moet een groot aantal kleine bestanden regelmatig worden herschreven in een kleiner aantal grotere bestanden. Dit wordt compactheid genoemd.

U kunt een tabel comprompt met de opdracht OPTIMIZE.

De inhoud of het schema van een tabel vervangen

Soms wilt u een Delta-tabel vervangen. Bijvoorbeeld:

  • U ontdekt dat de gegevens in de tabel onjuist zijn en u wilt de inhoud vervangen.
  • U wilt de hele tabel herschrijven om incompatibele schemawijzigingen uit te voeren (kolommen verwijderen of kolomtypen wijzigen).

Hoewel u de hele map van een Delta-tabel kunt verwijderen en een nieuwe tabel op hetzelfde pad kunt maken, wordt dit niet aanbevolen omdat:

  • Het verwijderen van een directory is niet efficiĆ«nt. Het verwijderen van een map met zeer grote bestanden kan uren of zelfs dagen duren.
  • U raakt alle inhoud in de verwijderde bestanden kwijt; Het is moeilijk te herstellen als u de verkeerde tabel verwijdert.
  • Het verwijderen van de map is niet atomisch. Tijdens het verwijderen van de tabel kan een gelijktijdige query die de tabel leest mislukken of een gedeeltelijke tabel zien.

Als u het tabelschema niet hoeft te wijzigen, kunt u gegevens uit een Delta-tabel verwijderen en uw nieuwe gegevens invoegen of de tabel bijwerken om de onjuiste waarden op te lossen.

Als u het tabelschema wilt wijzigen, kunt u de hele tabel atomisch vervangen. Bijvoorbeeld:

Python

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

SQL

REPLACE TABLE <your-table> USING DELTA PARTITIONED BY (<your-partition-columns>) AS SELECT ... -- Managed table
REPLACE TABLE <your-table> USING DELTA PARTITIONED BY (<your-partition-columns>) LOCATION "<your-table-path>" AS SELECT ... -- External table

Scala

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

Deze benadering heeft meerdere voordelen:

  • Het overschrijven van een tabel gaat veel sneller omdat de map niet recursief hoeft te worden weergegeven of verwijderd.
  • De oude versie van de tabel bestaat nog steeds. Als u de verkeerde tabel verwijdert, kunt u de oude gegevens eenvoudig ophalen met time travel.
  • Het is een atomische bewerking. Gelijktijdige query's kunnen de tabel nog steeds lezen terwijl u de tabel wilt verwijderen.
  • Vanwege de acid-transactiegaranties van Delta Lake heeft de tabel de vorige status als het overschrijven van de tabel mislukt.

Als u oude bestanden wilt verwijderen om opslagkosten te besparen nadat u de tabel hebt overschreven, kunt u vacuum gebruiken om ze te verwijderen. Het is geoptimaliseerd voor het verwijderen van bestanden en meestal sneller dan het verwijderen van de volledige map.

Spark-caching

Databricks raadt u aan spark-caching tegebruiken, dat wil zeggen

df = spark.read.delta("/some/path")
df .cache()

alleen als u een duur aggregatie- of samenvoegresultaat hebt dat meerdere keren wordt gebruikt, bijvoorbeeld om meer rollups uit te voeren.

Gebruik anders deze methode niet in Delta-tabellen.

  • U verliest alle gegevens die kunnen worden overgeslagen door extra filters die zijn toegevoegd boven op de in de cache opgeslagen DataFrame .
  • De gegevens die in de cache worden opgeslagen, worden mogelijk niet bijgewerkt als de tabel wordt gebruikt voor toegang met een andere id (u schrijft bijvoorbeeld wel naar de tabel met spark.table(x).cache() behulp van spark.write.save(/some/path) .