Почему чтение из Redshift в Spark так медленно? - PullRequest
0 голосов
/ 06 сентября 2018

У меня проблемы с чтением данных из AWS Redshift в мой кластер Spark. Время чтения истекло, что привело к сбою задания искры. Я использую следующее для извлечения данных в фрейм данных:

def retrieveFromDate(date: String): org.apache.spark.sql.DataFrame = {
    val query = "tstamp >= '2018-01-01' and tstamp < '2018-01-02'"
    val predicates = Array[String](query)

    val props = new Properties()
    props.put("user", "username")
    props.put("password", "password")

    spark.read
        .jdbc(url=jdbcURL, 
              table="myschema.mytable", 
              predicates=predicates,
              connectionProperties=props)
}

Следующий запрос непосредственно в SQL быстро возвращает 24 миллиона строк:

select * from myschema.mytable
WHERE tstamp >= '2018-08-01'
  AND tstamp < '2018-08-02';

В Spark задание не выполняется в тот момент, когда я выполняю какие-либо действия с кадром данных, включая только count.

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

Мой кластер AWS EMR для разработки содержит мастер M4.xlarge и 2 рабочих M3.xlarge. Это примерно 15 ГБ оперативной памяти и 8 процессорных ядер на одного работника.

1 Ответ

0 голосов
/ 06 сентября 2018
>> The read is timing out and causing the spark job to fail

Параметр предикатов просто имеет

val query = "tstamp >= '2018-01-01' and tstamp < '2018-01-02'"

Итак, результирующий фрейм данных - это разделение «1» в результате одной задачи, и он содержит 24 миллиона. В этом нет параллелизма.

Не могли бы вы изменить и предоставить предикаты, которые делят данные 24M на несколько кусков. Итак, читать можно распараллелить?

как то так,

val query = Arry [String] ("column> = value1 и column = значение2 и столбец <значение3», «столбец> = значение3 и столбец <значение4», .......) </p>

или

если вы не хотите кормить все предикаты, измените метод jdbc на тип ниже и предоставьте lowerBound, upperBound & numPartitions, и он снова подвергается значениям в этом столбце раздела, равномерно распределенных по его диапазону.

public Dataset<Row> jdbc(String url,
                String table,
                String columnName,
                long lowerBound,
                long upperBound,
                int numPartitions,
                java.util.Properties connectionProperties)

подробнее здесь

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