Spark выполняет слишком много разделов в рамках одной задачи, а не распределяет ее.
Мы загружаем довольно большие объемы данных из HBase в набор данных Spark.
Из-за несовместимости мы не можем использовать HBase-Spark и прибегли к использованию базового клиента JavaAPI для HBase.
Чтобы помочь распараллелить загрузку из HBase, мы поместили «startRows» в набор данных, переразделили набор данных, чтобы получить 16 разделов, каждый из которых содержит 4 начальных строки.
Затем мы использовали mapPartitions () для запроса 4 начальных строк и возврата итератора фактических данных строки.
Это приводит к извлечению всех строк, однако, даже при том, что мы уверены, что данные равномерно распределены между этими начальными строками, Spark настаивает на перемещении большинства разделов 3 или 4 исполнителям вместо 16.
Я вполне уверен, что это связано с тем, что Spark не знает о реальных данных, которые мы загружаем, и тщательно оптимизирует начальные строки в наборе данных.
Есть ли в любом случае заставить spark выполнять их как одну задачу, одного исполнителя на раздел?
List<String> keys = new ArrayList<>();
for(int salt=0; salt<maxSalt; salt++) { // maxSalt=64
keys.add( extractStartRow( mainKey, String.valueOf(salt));
}
Dataset<String> saltSeed = sparkSession.createDataset(keys,
Encoders.STRING());
int partitions = 16;
saltRange = saltRange.repartition(partitions);
Dataset<Results> = saltRange.mapPartitions(new Ingestor(mainKey), Encoders.bean(Results.class));
// Ingestor function, does the actual read from Hbase for the given salted start row.
Мы хотели бы найти способ заставить больше задач / исполнителей работать над
проблема чтения из HBase. Что бы мы ни старались, Spark снижает рабочую нагрузку до нескольких исполнителей. Остальные не получают ни разделов, ни данных. Активные исполнители занимают часы.