Присоединяйтесь к двум большим столам с Apache Spark - PullRequest
0 голосов
/ 16 июня 2020

Я хочу объединить 2 очень большие таблицы, указав c общий ключ с помощью Spark, я пытаюсь понять, какой это оптимальный способ сделать это.

  • таблица 1 содержит 900 млн строк и ~ 100 столбцов
  • таблица 2 содержит 600 млн строк и ~ 200 столбцов.
  • Мы не можем использовать "широковещательное соединение", таблицы большой и не может транслироваться.

Я хочу объединить (внутреннее соединение) таблицы, используя общие столбцы id, которые существуют в них обоих, кроме того, я знаю, что столбцы id содержит одинаковые значения в обеих таблицах, нет значения id, которое существует в одной, но не существует в другой.

Идеальный способ, который я могу придумать, - это «разделить» каждую одну из моих таблиц в разделы / корзины, содержащие одинаковые значения id, и отправить их одному и тому же исполнителю, который вычислит результат соединения с минимальным перетасованием данных в кластере.

Мои вопросы: :

  1. Если я использую, например .rep artition (5, 'id') для каждой из таблиц - каждый из 5 разделов будет содержать одинаковые значения 'id'? (если у нас одинаковые значения id в обоих из них)

например:

df1
+---+---+------+
|age| id|  name|
+---+---+------+
|  5|  1| David|
| 50|  2|  Lily|
| 10|  3|   Dan|
| 15|  4|Nicole|
| 16|  5|  Dana|
| 19|  6|   Ron|
| 20|  7| Alice|
| 22|  8|  Nora|
| 45|  9|  Sara|
| 70| 10| Aaron|
+---+---+------+


df2
+---+-----+
| id|price|
+---+-----+
|  1| 30.8|
|  1| 40.3|
|  2|100.0|
|  2| 30.1|
|  3| 99.0|
|  3|102.0|
|  4| 81.2|
|  4| 91.2|
|  5| 73.4|
|  6| 22.2|
|  7|374.4|
|  8|669.7|
|  9|  4.8|
| 10|35.38|
+---+-----+

df1.repartition(5,'id')
df2.repartition(5,'id')

Если разделы df1: [id = 1, id = 2], [id = 3, id = 4], [id = 5, id = 6], [id = 7, id = 8], [id = 9, id = 10]

Это обязательно быть таким же для df2?

Если я использую bucketBy таким же образом, получу ли я те же значения id в сегментах таблиц?

Будет ли Spark отправлять правильные разделы одному исполнителю? Я имею в виду, что раздел, содержащий [id = 1, id = 2] таблицы 1, и раздел, содержащий [id = 1, id = 2] для таблицы 2, будут отправлены одному и тому же исполнителю для соединения.

Если я что-то пропущу, или вы можете порекомендовать другой способ соединения двух больших таблиц в соответствии с упомянутыми мною предположениями, это будет очень полезно.

Ответы [ 2 ]

1 голос
/ 16 июня 2020

Взгляните на этот ответ .
TL; DR: если вы хотите присоединиться к ним один раз, и это единственная цель для повторного разделения, просто присоединитесь к ним.

0 голосов
/ 16 июня 2020

Да, это должно быть так, иначе вся парадигма JOINing не была бы надежной.

Вы имеете в виду на самом деле Worker - машину с Executor (s).

переразбивка на его собственный не рекомендуется в качестве кругового.

Разбиение диапазона также работает. Проверено, чтобы быть уверенным, но предположим, что распределение значений разделения такое же, как и при условии.

Все это работает на основе ленивой оценки.

bucketBy можно использовать, но это больше для сохранения на диск и использования в следующем приложении.

Опять же, вам не нужно беспокоиться о помощи, так как ленивый eval означает, что у Оптимизатора есть шанс решить все это - какому Worker'у выделить. Но это на более низком уровне детализации, абстракции.

...