sparkR gapply медленный по сравнению с SQL - PullRequest
0 голосов
/ 28 июня 2018

У меня есть набор данных ~ 8 ГБ с ~ 10 миллионами строк (около 10 столбцов), и я хотел доказать, что SparkR может превзойти SQL. Наоборот, я вижу крайне низкую производительность SparkR по сравнению с SQL.

Мой код просто загружает файл из S3, где прогоны выполняются gapply, где мои группировки обычно состоят из 1-15 строк - так что 10 миллионов строк, разделенных на 15, дают много групп. Я заставляю слишком много перетасовки, сериализации / десериализации? Поэтому все так медленно?

Чтобы проиллюстрировать, что моя функция build_transition не является узким местом производительности, я создал тривиальную версию build_transition2, как показано ниже, которая возвращает фиктивную информацию с постоянным временем выполнения для каждой группы.

Что-нибудь фундаментальное или очевидное в моей формулировке решения?

build_transition2 <- function(key, x) {

  patient_id <- integer()
  seq_val <- integer()

  patient_id <- append(patient_id, as.integer(1234))
  seq_val <- append(seq_val, as.integer(5678))

  y <- data.frame(patient_id, 
                  seq_val,
                  stringsAsFactors = FALSE
                  )
}


dat_spark <- read.df("s3n://my-awss3/data/myfile.csv", "csv", header = "true", inferSchema = "true", na.strings = "NA")


schema <- structType(structField("patient_ID","integer"),
                     structField("sequence","integer")
                     )


result <- gapply(dat_spark, "patient_encrypted_id", build_transition2, schema)

1 Ответ

0 голосов
/ 28 июня 2018

и хотел доказать, что SparkR может превосходить SQL.

Это просто не тот случай. Издержки косвенного обращения, вызванные языком гостя:

  • Внутренний формат Catalyst
  • Внешний тип Java
  • Отправка данных в R
  • ....
  • Отправка данных обратно в JVM
  • Преобразование в формат Catalyst

огромен.

Кстати, gapply - это, в основном, пример группирования по ключу - то, чего мы обычно избегаем в Spark.

В целом gapply следует использовать в том и только в том случае, если бизнес-логика не может быть выражена с помощью стандартных функций SQL. Это определенно не способ оптимизировать ваш код при нормальных обстоятельствах (могут быть граничащие случаи, когда он может быть быстрее, но в целом любая специальная логика, если требуется, выиграет больше от нативного выполнения JVM с Scala UDF, UDAF, Aggregator или reduceGroups / mapGroups).

...