Odpowiedź Justina jest niesamowita i ta odpowiedź jest głębsza.
repartitionAlgorytm robi pełną shuffle i tworzy nowe partycje z danymi, które jest rozprowadzane równomiernie. Utwórzmy ramkę danych o liczbach od 1 do 12.
val x = (1 to 12).toList
val numbersDf = x.toDF("number")
numbersDf zawiera 4 partycje na moim komputerze.
numbersDf.rdd.partitions.size // => 4
Oto jak dane są dzielone na partycje:
Partition 00000: 1, 2, 3
Partition 00001: 4, 5, 6
Partition 00002: 7, 8, 9
Partition 00003: 10, 11, 12
Zróbmy dokładnie losowanie z tą repartitionmetodą i uzyskaj te dane w dwóch węzłach.
val numbersDfR = numbersDf.repartition(2)
Oto sposób numbersDfRpartycjonowania danych na moim komputerze:
Partition A: 1, 3, 4, 6, 7, 9, 10, 12
Partition B: 2, 5, 8, 11
repartitionMetoda sprawia, że nowe partycje i równomiernie rozprowadza dane w nowych partycji (rozkład danych jest więcej, nawet w przypadku większych zbiorów danych).
Różnica między coalesceirepartition
coalescewykorzystuje istniejące partycje, aby zminimalizować ilość danych, które są przetasowane. repartitiontworzy nowe partycje i wykonuje pełne losowanie. coalesceskutkuje partycjami o różnych ilościach danych (czasami partycjami, które mają wiele różnych rozmiarów) i repartitionskutkuje mniej więcej jednakowymi rozmiarami partycji.
Jest coalescealbo repartitionszybciej?
coalescemoże działać szybciej niż repartition, ale partycje o nierównej wielkości są zazwyczaj wolniejsze w pracy niż partycje o równej wielkości. Zwykle będziesz musiał ponownie podzielić zestawy danych po przefiltrowaniu dużego zestawu danych. Odkryłem, że repartitionogólnie jest szybszy, ponieważ Spark jest zbudowany do pracy z partycjami równej wielkości.
Uwaga: Z ciekawością zauważyłem, że podział może zwiększyć rozmiar danych na dysku . Pamiętaj, aby uruchamiać testy, gdy używasz partycji / łączenia na dużych zestawach danych.
Przeczytaj ten post na blogu, jeśli chcesz uzyskać więcej informacji.
Kiedy w praktyce użyjesz łączenia i podziału
minimize data movementzamiastavoiding data movement.