Проблема с производительностью объединения нескольких наборов данных Spark - PullRequest
0 голосов
/ 13 декабря 2018

Итак, в настоящее время у меня есть таблица, похожая на эту

userID, day, itemID
1,       1,   A
1,       1,   B
2,       2,   A
2,       2,   C
...

, что означает, что пользователь 1 купил предмет А в 1-й день, и так далее.Сначала мне нужно извлечь другой набор данных с тем же itemID, например, после

userID, day, itemID
1,       1,   A
2,       2,   A
...

userID, day, itemID
1,       1,   B
...

, затем каждый набор данных будет выводить данные в том же формате, например:

userID result
1,      x
...

тогда я присоединюсь ко всем этим результатам.Проблема в том, что у меня есть производительность, как вы можете видеть, количество результирующих наборов данных зависит от того, сколько разных itemID у меня есть, для числа 6 он работает хорошо, все завершается в течение 2 минут, но для числа 45 этозанимает 30 минут, а я все еще жду.Программа просто зависла на ContextCleaner: 54, двигаясь очень медленно.

И я уже пробовал запускать это в облаке с более чем 100 ГБ ОЗУ, мне просто любопытно, почему объединение большого количества таблиц происходит так медленно.

Обновление: в конце концов я получил ошибку stackoverflow ... Я посмотрел на запрос выполнения, он безумно длинный, я думаю, что это не очень хорошая идея сделать цикл for для объединения более 45 таблиц ..

Просто для более детальной проработки вопроса с примером кода

List<String> itemIDs = ...;
Dataset<Row> ret = null;
for (String itemID : itemIDs) {
    Dataset<Row> df = mainDF.filter(col("itemID").equalTo(itemID));
    Dataset<Row> result = someFunction(df);
  if (ret == null) ret = combined;
  else {
    combined = combined.withColumnRenamed("userID", "userID_right");
    ret = ret.join(
            combined,
            ret.col("userID").equalTo(combined.col("userID_right")),
            "full_outer")
            .withColumn("user_id",
                    coalesce(col("userID"), col("userID_right")))
           .drop("userID", "userID_right")
            .withColumnRenamed("user_id", "userID");
  }
}

в конце концов, когда я попытался выполнить ret.show() после 45 итераций, моя машина в значительной степени просто умирает.

Другое обновление: поэтому я выяснил, как ускорить процесс, набор данных, к которому я присоединяюсь, следует за длинным и сложным преобразованием, и он наследует количество разделов по умолчанию, равное 200, и, очевидно, когда вы присоединяетесь к таблице много раз сбольшое количество разделов, он в значительной степени просто умирает, но если вы можете перераспределить ваш набор данных на меньший размер, в моем случае, 8, то это значительно ускоряетнамного быстрее, заканчивается через 3 минуты.Приветствия.Я думаю, что большая часть этого происходит из-за моего глубокого понимания того, как работает RDD.

Окончательное обновление: так что, по сути, не объединяйте более 50 или 100 маленьких столов вместе, я думаю, что это не так, как предполагает искравместо этого он может просто преобразовать его в простой Java-объект и манипулировать им.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...