Spark – repartition () vs coalesce ()

Secondo Learning Spark

Tieni presente che la ripartizione dei dati è un’operazione abbastanza costosa. Spark ha anche una versione ottimizzata di ripartizione () chiamata coalesce () che consente di evitare lo spostamento di dati, ma solo se si sta riducendo il numero di partizioni RDD.

Una differenza che ottengo è che con la ripartizione () il numero di partizioni può essere aumentato / diminuito, ma con coalesce () il numero di partizioni può essere solo diminuito.

Se le partizioni sono distribuite su più macchine e viene eseguita la coalesce (), come può evitare lo spostamento dei dati?

    Evita un rimescolamento completo . Se è noto che il numero diminuisce, l’executor può tranquillamente conservare i dati sul numero minimo di partizioni, spostando solo i dati dai nodes aggiuntivi, sui nodes che abbiamo conservato.

    Quindi, andrebbe qualcosa di simile a questo:

    Node 1 = 1,2,3 Node 2 = 4,5,6 Node 3 = 7,8,9 Node 4 = 10,11,12 

    Quindi coalesce in 2 partizioni:

     Node 1 = 1,2,3 + (10,11,12) Node 3 = 7,8,9 + (4,5,6) 

    Si noti che il nodo 1 e il nodo 3 non hanno richiesto il trasferimento dei dati originali.

    La risposta di Justin è eccezionale e questa risposta va più in profondità.

    L’algoritmo di repartition esegue un shuffle completo e crea nuove partizioni con dati distribuiti in modo uniforms. Creiamo un DataFrame con i numeri da 1 a 12.

     val x = (1 to 12).toList val numbersDf = x.toDF("number") 

    numbersDf contiene 4 partizioni sulla mia macchina.

     numbersDf.rdd.partitions.size // => 4 

    Ecco come vengono divisi i dati sulle partizioni:

     Partition 00000: 1, 2, 3 Partition 00001: 4, 5, 6 Partition 00002: 7, 8, 9 Partition 00003: 10, 11, 12 

    Facciamo un full shuffle con il metodo di repartition e prendiamo questi dati su due nodes.

     val numbersDfR = numbersDf.repartition(2) 

    Ecco come vengono numbersDfR dati dei numbersDfR sulla mia macchina:

     Partition A: 1, 3, 4, 6, 7, 9, 10, 12 Partition B: 2, 5, 8, 11 

    Il metodo di repartition crea nuove partizioni e distribuisce uniformsmente i dati nelle nuove partizioni (la distribuzione dei dati è più uniforms per i set di dati più grandi).

    Differenza tra coalesce e repartition

    coalesce usa le partizioni esistenti per ridurre al minimo la quantità di dati che vengono mescolati. repartition crea nuove partizioni e fa un full shuffle. coalesce produce partizioni con quantità diverse di dati (a volte partizioni con dimensioni molto diverse) e risultati di repartition in partizioni di dimensioni approssimativamente uguali.

    La coalesce o repartition più veloce?

    coalesce può essere più veloce della repartition , ma le partizioni di dimensioni non uguali sono generalmente più lente da utilizzare rispetto alle partizioni di dimensioni uguali. Di solito è necessario ripartire i set di dati dopo aver filtrato un set di dati di grandi dimensioni. Ho trovato che la repartition è più veloce nel complesso perché Spark è progettato per funzionare con partizioni di dimensioni uguali.

    Leggi questo post del blog se desideri ulteriori dettagli.

    Un altro punto da notare qui è che, come il principio di base di Spark RDD è immutabilità. La ripartizione o la coalizione creerà un nuovo RDD. La base RDD continuerà ad avere esistenza con il suo numero originale di partizioni. Nel caso in cui il caso d’uso richieda di mantenere RDD in cache, allora lo stesso deve essere fatto per l’RDD appena creato.

     scala> pairMrkt.repartition(10) res16: org.apache.spark.rdd.RDD[(String, Array[String])] =MapPartitionsRDD[11] at repartition at :26 scala> res16.partitions.length res17: Int = 10 scala> pairMrkt.partitions.length res20: Int = 2 

    Tutte le risposte stanno aggiungendo alcune grandi conoscenze in questa domanda molto frequente.

    Quindi, seguendo la tradizione della cronologia di questa domanda, ecco i miei 2 centesimi.

    Ho trovato la ripartizione più veloce della coalesce , nel caso specifico.

    Nella mia applicazione quando il numero di file che stimiamo è inferiore alla soglia certa, la ripartizione funziona più velocemente.

    Ecco cosa intendo

     if(numFiles > 20) df.coalesce(numFiles).write.mode(SaveMode.Overwrite).parquet(dest) else df.repartition(numFiles).write.mode(SaveMode.Overwrite).parquet(dest) 

    In snippet sopra, se i miei file erano meno di 20, la coalesce richiedeva un’eternità per finire mentre la ripartizione era molto più veloce e quindi il codice di cui sopra.

    Naturalmente, questo numero (20) dipenderà dal numero di lavoratori e dalla quantità di dati.

    Spero possa aiutare.

    In un modo semplice COALESCE: – è solo per diminuisce il no delle partizioni, nessun rimescolamento di dati comprime solo le partizioni

    REPARTITION: – è sia per aumentare sia per diminuire il no delle partizioni, ma lo shuffling avviene

    Esempio:-

     val rdd = sc.textFile("path",7) rdd.repartition(10) rdd.repartition(2) 

    Entrambi funzionano bene

    Ma in genere prendiamo queste due cose quando abbiamo bisogno di vedere l’output in un cluster, andiamo con questo.

    Ma dovresti anche assicurarti che i dati che stanno arrivando ai nodes coalesce dovrebbero essere altamente configurati, se hai a che fare con enormi dati. Poiché tutti i dati verranno caricati su tali nodes, potrebbero causare un’eccezione di memoria. Sebbene la riparazione sia costosa, preferisco usarla. Dal momento che mescola e distribuisce i dati allo stesso modo.

    Sii saggio selezionare tra coalizione e ripartizione.

    ripartizione – si consiglia di utilizzare la ripartizione aumentando il numero di partizioni, poiché implica il rimescolamento di tutti i dati.

    coalesce: si consiglia di utilizzare la coalescenza senza ridurre le partizioni. Ad esempio se hai 3 partizioni e vuoi ridurle a 2 partizioni, Coalesce sposterà i dati della terza partizione alla partizione 1 e 2. La partizione 1 e 2 rimarranno nella stessa container.ma la ripartizione rimescola i dati in tutte le partizioni in modo tale da utilizzare la rete tra esecutore sarà alto e impatta la prestazione.

    Le prestazioni migliorano le prestazioni in modo migliore rispetto alla ripartizione riducendo al tempo stesso il numero di partizioni.