Merk
Tilgang til denne siden krever autorisasjon. Du kan prøve å logge på eller endre kataloger.
Tilgang til denne siden krever autorisasjon. Du kan prøve å endre kataloger.
Kjernekonsepter som ligger til grunn for størrelse, optimalisering og feilsøking. Les dette først hvis du er ny bruker av Spark in Fabric.
Generelle ting du bør og ikke bør gjøre
Scenario: Du er ny bruker av Spark. Hva er hva du bør og ikke bør gjøre
| Brukstilfelle | Anbefalte fremgangsmåter |
|---|---|
| Bruk optimaliserte serialiserte formater | Gjør følgende: Foretrekk formater som Avro, Parquet eller Optimized Row Column (ORC) fordi de bygger inn skjema, er kompakte og optimaliserer lagring og behandling. I stoff bruker du Delta-format for atomisitet, konsistens, isolasjon, holdbarhet (ACID) garantier og ytelsesfordeler |
| Vær forsiktig med XML/JSON | Ikke stol på skjemaslutning for store JavaScript Object Notation (JSON) eller Extensible Markup Language (XML)-filer, siden Spark leser hele datasettet for å utlede skjema, noe som bremser behandlingen og bruker minne intensivt. Angi et statisk primærskjema når du leser JSON/XML, eller bruk .option("samplingRatio", 0.1) det til å øke hastigheten på lesinger, men vær oppmerksom på at hvis eksemplet ikke representerer hele datasettet, kan lesinger mislykkes. En tryggere tilnærming utleder skjema fra et representativt utvalg og vedvarer det for alle lesinger.Unngå å analysere store XML-filer. XML-analyse kjører i seg selv langsommere på grunn av kodebehandling og typecasting. |
| Optimaliser sammenføyninger og filtrering | Gjør følgende: Bruk kolonnebeskjæring og filtrering på radnivå før sammenføyninger for å redusere tilfeldig rekkefølge og minnebruk. Catalyst-optimaliseringen håndterer automatisk predikat-pushdown når du bruker DataFrame-API-er. Unngå RDD-API-er (Resilient Distributed Dataset) fordi de omgår Catalyst-optimaliseringer. |
| Foretrekk DataFrames fremfor RDD-er | Gjør følgende: Bruk DataFrames i stedet for RDD-er for de fleste operasjoner. DataFrames bruker Catalyst Optimizer og Tungsten-utførelsesmotoren for effektiv utførelse. |
| Aktivere adaptiv spørringskjøring (AQE) | Gjør følgende: Slå på AQE for å optimalisere tilfeldige partisjoner dynamisk og håndtere skjeve data automatisk. |
Administrasjon av utførerminne
Scenario: Du vil forstå utførerminneadministrasjonen for ytelsesjustering.
Selv om en utførende er konfigurert med 56 GB minne, tillater ikke Spark at alt brukes direkte til brukerdata. Spark Core deler og administrerer utførerminne:
Reservert minne: En fast del som er reservert for interne system- og Spark-kostnader (for eksempel Java Virtual Machine (JVM), internals).
Brukerens minne: Lagrer brukerdefinerte funksjoner (UDF-er), lokale variabler, datastrukturer (lister, kart, ordbøker) og objekter opprettet under beregning.
Lagringsminne: Inneholder bufrede/vedvarende data, kringkastingsvariabler og tilfeldige data som kan bufres.
Utførelse minne: Brukes til mellomliggende beregninger (stokker, sammenføyninger, sorteringer, aggregasjoner).
Dynamisk minnedeling: Grensen mellom lagrings- og kjøringsminne kan flyttes. Spark kan låne minne fra en region til en annen, noe som gir fleksibel minnebruk.
Søle: Oppstår når minnebehovet for lagring eller kjøring overskrider minnet som er tilgjengelig etter lån. Dette tvinger data til disken, noe som kan påvirke ytelsen.
Feil med tom minne (OOM)
Scenario: Spark-jobber mislykkes med OOM-feil (Out of Memory).
Driver OOM:
OOM-feil for drivere oppstår når Spark-driveren overskrider det tildelte minnet.
Vanlig årsak: drivertunge operasjoner som collect(), countByKey()eller store toPandas() samtaler som trekker for mye data inn i driverminnet.
Avbøtende tiltak: Unngå førertunge operasjoner når det er mulig. Hvis det er uunngåelig, øk driverstørrelsen og referansen for å finne den optimale konfigurasjonen.
Utførende tom for minne (OOM):
Executor OOM-feil oppstår når en Spark-executor overskrider det tildelte minnet.
Vanlig årsak: Minne- og databehandlingsintensive transformasjoner på store datasett (for eksempel brede sammenføyninger, aggregasjoner, stokkinger) eller bufrede/vedvarende datasett som overskrider utførerens tilgjengelige minne (kjøring + lagringsområder).
Begrensning: Øk utførerminnet om nødvendig, juster Spark-minnebrøkene (spark.memory.fraction, spark.memory.storageFraction) og vedhold selektivt. Sørg for at bufrede data passer inn i tilgjengelig minne.
Skjevheter data
Symptomer skjevhet:
- Noen få oppgaver tar lengre tid enn andre i Spark-brukergrensesnittet (faseoppgaver viser tung hale).
- Stort gap mellom median og maks oppgavetid i fasemålinger.
- Stadier med store tilfeldige lese- eller skrivestørrelser for noen få partisjoner.
Vanlige årsaker:
- Ujevn datafordeling for sammenføynings-/gruppetastene (hurtigtaster).
- Feil partisjonering eller for få partisjoner for datavolumet.
- Oppstrøms dataavvik som produserer store poster eller mange null-/tomnøkler.
Klimatiltak:
- Partisjon eller sammenslåing for å øke partisjonsparallellitet og balanseringsstørrelser.
- Bruk nøkkelsalting eller tilpasset partisjonering for å spre hurtigtaster på tvers av partisjoner.
- Bruk AQE (Adaptive Query Execution) til å slå sammen partisjoner etter tilfeldiging og aktivere optimaliseringer for skjevhet sammenføyning.
- Bruk kringkastingssammenføyninger for små oppslagstabeller for å unngå tilfeldigheter.
- Behold balanserte mellomliggende datasett før dyre faser, og kjør jobben på nytt.
Beste praksis for UDF
Scenario: Du må bruke egendefinert logikk som ikke kan uttrykkes via innebygde DataFrame-funksjoner.
Bruk Spark DataFrame-API-er når det er mulig. Catalyst Optimizer optimaliserer innebygde funksjoner og kjører dem opprinnelig på JVM, slik at de leverer best ytelse.
Hvis du må bruke en UDF (brukerdefinert funksjon), må du unngå vanlige PySpark Python UDF-er. Vurder i stedet følgende alternativer:
Pandas UDF-er (også kjent som vektoriserte UDF-er): Bruk Apache Arrow for effektiv dataoverføring mellom JVM og Python. Pandas UDF-er tillater vektoriserte operasjoner, noe som forbedrer ytelsen betydelig sammenlignet med rad-for-rad Python UDF-er.
Scala/Java UDF-er: Kjør direkte på JVM, og unngå Python-serialiseringskostnader. Scala/Java UDF-er overgår vanligvis Python UDF-er.
Vær forsiktig med Python UDF-er. Hver utførende starter en egen Python-prosess, som krever serialisering og deserialisering av data mellom JVM og Python. Dette skaper en flaskehals for ytelsen, spesielt i stor skala.
Feil logging
Scenario: Anbefalte fremgangsmåter for feillogging i Fabric Spark
Bruk
log4ji stedet forprint()som belaster sjåføren tungt. Medlog4j, kan du få tilgang til logger i driverlogger og søke i dem (ved å bruke loggernavnet, for eksempel: PySparkLogger).Bryt lesinger, skrivinger og transformasjoner i forsøk og unnta-blokker. Brukes
logger.errorfor unntak oglogger.infofor fremdriftsmeldinger.Python-logging: Ideell for logging av operasjoner, statusoppdateringer eller feilsøking av informasjon fra kode som bare kjøres på Spark-driveren. Pythons loggingsmodul sprer seg ikke til utførelseslogger. Se dokumentasjonen for å utvikle, kjøre og administrere notatblokker.
Spark log4j: Standarden for robust programlogging på produksjonsnivå i Spark ettersom den integreres opprinnelig med Sparks driver-/utførerlogger.
Eksempel på log4j-bruk i PySpark:
import traceback # Get log4j logger log4jLogger = spark._jvm.org.apache.log4j logger = log4jLogger.LogManager.getLogger("PySparkLogger") logger.info("Application started.") try: # Create DataFrame with 20 records data = [(f"Name{i}", i) for i in range(1, 21)] # 20 records df = spark.createDataFrame(data, ["name", "age"]) logger.info("DataFrame created successfully with 20 records.") df.show(s) # 's' is not defined -> will throw error but the application will not fail except Exception as e: logger.error(f"Error while creating or showing DataFrame: {str(e)}\n{traceback.format_exc()}")Sentraliser feilovervåking:
Bruk diagnosesenderutvidelse (Overvåk Apache Spark-programmer med Azure Log Analytics) i miljøet, og legg ved notatblokkene som kjører Spark-programmer. Senderen kan sende hendelseslogger, egendefinerte logger (for eksempel log4j) og måledata til Azure Log Analytics/Azure Storage/Azure Event Hubs. Send log4j-navnet til eiendommen:
spark.synapse.diagnostic.emitter.\<destination\>.filter.loggerName.match.I tillegg for feilsøking kan du også samle inn mislykkede rader/poster til Lakehouse-tabeller (LH) for dårlig datafangst på postnivå.