Utforsk anbefalte fremgangsmåter for Optimalisering Av Spark – IBM Developer

antall () På et datasett En Spark-handling. Det er et vanlig problem som jeg har sett hvor det er flere count () samtaler I Spark-applikasjoner som legges til under feilsøking, og de blir ikke fjernet. Det er en god ide å se Etter Spark-handlinger og fjerne alt som ikke er nødvendig fordi vi ikke vil bruke CPU-sykluser og andre ressurser når det ikke er nødvendig.

Filformater

når du utformer datasettene for programmet, må du sørge for at du gjør det beste ut av filformatene som er tilgjengelige Med Spark. Noen ting å vurdere:

  • Spark er optimalisert For Apache Parkett og ORC for lesegjennomstrømning. Spark har vektoriseringsstøtte som reduserer disk I / O. Kolonneformater fungerer bra.
  • Bruk Parquet-filformatet og bruk komprimering.
  • det finnes forskjellige filformater og innebygde datakilder som kan brukes I Apache Spark.Bruk splittable filformater.
  • Pass på at det ikke er for mange små filer. Hvis du har mange små filer, kan det være fornuftig å gjøre komprimering av dem for bedre ytelse.

Parallellisme

  • Øk Antall Gnistpartisjoner for å øke parallelliteten basert på størrelsen på dataene. Sørg for at klyngens ressurser utnyttes optimalt. For få partisjoner kan føre til at noen eksekutorer er inaktiv, mens for mange partisjoner kan resultere i overhead av oppgaveplanlegging.
  • Still inn partisjonene og oppgavene. Spark kan håndtere oppgaver på 100ms+ og anbefaler minst 2-3 oppgaver per kjerne for en eksekutor.
  • Spark bestemmer antall partisjoner basert på filstørrelsesinngangen. Til tider er det fornuftig å spesifisere antall partisjoner eksplisitt.
    • les API tar et valgfritt antall partisjoner.
    • gnist.sql.fil.maxPartitionBytes, tilgjengelig I Spark v2. 0.0, For Parkett, ORK og JSON.
  • shuffle-partisjonene kan stilles inn ved å sette spark.sql.tilfeldig.partisjoner, som standard til 200. Dette er veldig lite hvis du har store datasettstørrelser.

Reduser shuffle

Shuffle er en dyr operasjon da Det innebærer å flytte data over nodene i klyngen din, som involverer nettverk og disk I / O. Det er alltid en god ide å redusere mengden data som må blandes. Her er noen tips for å redusere shuffle:

  • Still inn gnisten.sql.tilfeldig.partisjoner.
  • Partisjonere inndatasettet på riktig måte, slik at hver oppgavestørrelse ikke er for stor.
  • Bruk Spark UI til å studere planen for å se etter muligheten til å redusere shuffle så mye som mulig.
  • formel anbefaling for gnist.sql.tilfeldig.skillevegger:
    • for store datasett, sikte på hvor som HELST fra 100mb til mindre ENN 200mb oppgave målstørrelse for en partisjon (bruk målstørrelse PÅ 100MB, for eksempel).
    • gnist.sql.tilfeldig.partisjoner = kvotient (shuffle stage input size/target size)/totalt kjerner) * totalt kjerner.

Filtrer / Reduser datasettstørrelsen

Se etter muligheter for å filtrere ut data så tidlig som mulig i programrørledningen. Hvis det er en filteroperasjon, og du bare er interessert i å gjøre analyse for et delsett av dataene, bruk dette filteret tidlig. Hvis du kan redusere datasettstørrelsen tidlig, gjør du det. Bruk passende filterpredikater i SQL-spørringen, slik At Spark kan skyve dem ned til den underliggende datakilden; selektive predikater er gode. Bruk dem etter behov. Bruk partisjonsfiltre hvis de er aktuelle.

Hurtigbuffer på riktig måte

Spark støtter hurtigbufring av datasett i minnet. Det finnes ulike alternativer:

  • Bruk bufring når den samme operasjonen beregnes flere ganger i rørledningen flyt.
  • Bruk bufring ved hjelp av vedvarende API for å aktivere den nødvendige cache-innstillingen(vedvarer til disk eller ikke, serialisert eller ikke).
  • Vær oppmerksom på lat lasting og prime cache om nødvendig opp foran. Noen Apier er ivrige og noen er ikke.
  • Sjekk Ut Spark UI Lagring kategorien for å se informasjon om datasettene du har bufret.
  • det er lurt å unpersist din bufrede datasett når du er ferdig med å bruke dem for å frigjøre ressurser, spesielt når du har andre personer som bruker klyngen også.

Bli Med

Bli med er generelt en dyr operasjon, så vær oppmerksom på leddene i søknaden din for å optimalisere dem. BroadcastHashJoin er mest performant for tilfeller der en av relasjonene er liten nok til at den kan sendes. Nedenfor er noen tips:

  • Bli med ordre saker; start med den mest selektive delta. For relasjoner mindre enn gnist.sql.autoBroadcastJoinThreshold, du kan sjekke om kringkasting HashJoin er hentet.
  • Bruk SQL-tips om nødvendig for å tvinge en bestemt type sammenføyning.
    • Eksempel: når du kobler til et lite datasett med stort datasett, kan en kringkastingskobling bli tvunget til å kringkaste det lille datasettet.
    • Bekreft At Spark plukker opp broadcast hash join; hvis ikke, kan man tvinge den ved HJELP AV SQL-hinten.
  • Unngå kryssforbindelser.
  • Broadcast HashJoin er mest performant, men kan ikke være aktuelt hvis begge relasjonene i join er store.
  • Samle statistikk på tabeller For Spark for å beregne en optimal plan.

Tune cluster resources

  • Tune ressursene i klyngen avhengig av ressursbehandling og Versjon Av Spark.
  • Still inn tilgjengelig minne til driveren: spark.driveren.minne.
  • Still inn antall eksekutorer og minne og kjernebruk basert på ressurser i klyngen: eksekutor-minne, num-eksekutorer og eksekutor-kjerner.

Sjekk ut konfigurasjonsdokumentasjonen for Spark release du arbeider med, og bruk de riktige parameterne.

Unngå dyre operasjoner

  • Unngå bestill med hvis det ikke er nødvendig.
  • når du skriver spørringene dine, kan du i stedet for å bruke select * for å hente alle kolonnene, bare hente kolonnene som er relevante for spørringen.
  • ikke kall antall unødvendig.

data skew

  • Kontroller at partisjonene er like store for å unngå data skew og lav CPU-utnyttelse problemer.
    • Som et eksempel: hvis du har data som kommer inn fra en jdbc-datakilde parallelt, og hver av disse partisjonene ikke henter et tilsvarende antall poster, vil dette resultere i oppgaver med ulik størrelse (en form for dataskjev). Kanskje en partisjon er bare noen FÅ KB, mens en annen er noen få hundre MB. Noen oppgaver vil være større enn andre, og mens eksekutorer på større oppgaver vil være opptatt, vil de andre eksekutorer, som håndterer den mindre oppgaven, fullføre og være inaktiv.
    • hvis data ved kilden ikke er partisjonert optimalt, kan du også evaluere avvikene ved å bruke repartisjonering for å få en balansert partisjon og deretter bruke caching for å fortsette den i minnet hvis det er hensiktsmessig.
  • Partisjonering vil føre til en shuffle, og shuffle er en dyr operasjon, så dette bør vurderes på søknadsbasis.
  • Bruk Spark-BRUKERGRENSESNITTET til å se etter partisjonsstørrelser og aktivitetsvarighet.

UDFs

Spark har en rekke innebygde brukerdefinerte funksjoner (UDFs) tilgjengelig. For ytelse, sjekk for å se om du kan bruke en av de innebygde funksjonene siden de er gode for ytelse. Egendefinerte UDFs i Scala API er mer performant enn Python UDFs. Hvis Du må bruke Python API, bruk den nylig introduserte pandas UDF I Python som ble utgitt I Spark 2.3. Pandas UDF (vectorized Udf) – støtten I Spark har betydelige ytelsesforbedringer i motsetning til å skrive en tilpasset Python UDF. Få mer informasjon om å skrive en pandas UDF.

jeg håper dette var nyttig for deg når du går om å skrive Spark-applikasjonene dine. Glad utvikling! I en kommende blogg vil jeg vise hvordan du får utførelsesplanen for Spark-jobben din.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.