Принудительно использовать больше исполнителей, по одному на раздел - PullRequest
0 голосов
/ 13 мая 2019

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 снижает рабочую нагрузку до нескольких исполнителей. Остальные не получают ни разделов, ни данных. Активные исполнители занимают часы.

...