Как я могу улучшить производительность sparklyr read csv? - PullRequest
0 голосов
/ 01 ноября 2018

Я думаю, что чтение в файлах CSV мучительно медленно при использовании sparklyr. Смотри MVE

library(sparklyr)
library(dplyr)

conf <- spark_config()
conf$spark.executor.memory <- "60GB"
conf$spark.memory.fraction <- 0.9
conf$spark.executor.cores <- 6
conf$spark.dynamicAllocation.enabled <- "false"
sc <- sparklyr::spark_connect(master = "local", config = conf)

library(data.table)

fwrite(data.table(
  id1 = sample(sprintf("id%03d",1:K), N, TRUE),      # large groups (char)
  id2 = sample(sprintf("id%03d",1:K), N, TRUE),      # large groups (char)
  id3 = sample(sprintf("id%010d",1:(N/K)), N, TRUE), # small groups (char)
  id4 = sample(K, N, TRUE),                          # large groups (int)
  id5 = sample(K, N, TRUE),                          # large groups (int)
  id6 = sample(N/K, N, TRUE),                        # small groups (int)
  v1 =  sample(5, N, TRUE),                          # int in range [1,5]
  v2 =  sample(5, N, TRUE),                          # int in range [1,5]
  v3 =  sample(round(runif(100,max=100),4), N, TRUE) # numeric e.g. 23.5749
), "a.csv")

system.time(sparklyr::spark_read_csv(sc, "a", "a.csv"))

Я уже пытался увеличить уровень оперативной памяти, доступной Spark, но скорость чтения слишком мала - 500 секунд! Это невероятно медленно по сравнению с data.table::fread.

Есть ли способ настроить Spark так, чтобы он работал быстрее?

1 Ответ

0 голосов
/ 01 ноября 2018

Здесь как минимум три проблемы:

  • local режим не распределен или даже параллелен. Он будет использовать только один локальный поток. Если у вас есть только один узел, по крайней мере, попытайтесь увеличить количество доступных потоков (возможно, превышающее количество доступных ядер).

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

  • Вы не предоставляете схему для считывателя и требует вывода схемы (значение по умолчанию infer_schema аргумент). Если вы хотите избежать этих издержек, вы должны предоставить схему .

  • Вы охотно кэшируете данные (значение по умолчанию memory аргумент), что является одновременно дорогим и редко полезным.

Дополнительно:

  • Такое высокое значение spark.memory.fraction, вероятно, сводит с ума сборщика мусора, заполняющего старые поколения. Обязательно проверьте время GC, и если оно необычно высокое, уменьшите spark.memory.fraction ниже значения по умолчанию (0,6), а не увеличьте.

Наконец:

...