Utilizando o spark 2.4.4 em execução no modo de cluster YARN com o planejador FIFO do spark.
Estou enviando várias operações de quadro de dados spark (ou seja, gravando dados no S3) usando um executor de pool de threads com um número variável de threads. Isso funciona bem se eu tiver ~ 10 threads, mas se eu usar centenas de threads, parece haver um impasse, sem trabalhos agendados de acordo com a interface do usuário do Spark.
Quais fatores controlam quantos trabalhos podem ser agendados simultaneamente? Recursos do driver (por exemplo, memória / núcleos)? Algumas outras definições de configuração do spark?
EDITAR:
Aqui está uma breve sinopse do meu código
ExecutorService pool = Executors.newFixedThreadPool(nThreads);
ExecutorCompletionService<Void> ecs = new ExecutorCompletionService<>(pool);
Dataset<Row> aHugeDf = spark.read.json(hundredsOfPaths);
List<Future<Void>> futures = listOfSeveralHundredThings
.stream()
.map(aThing -> ecs.submit(() -> {
df
.filter(col("some_column").equalTo(aThing))
.write()
.format("org.apache.hudi")
.options(writeOptions)
.save(outputPathFor(aThing));
return null;
}))
.collect(Collectors.toList());
IntStream.range(0, futures.size()).forEach(i -> ecs.poll(30, TimeUnit.MINUTES));
exec.shutdownNow();
Em algum momento, à medida que nThreads
aumenta, a faísca não parece mais agendar trabalhos, conforme evidenciado por:
ecs.poll(...)
tempo limite eventualmente- A guia Trabalhos da interface do usuário do Spark que não mostra trabalhos ativos
- A guia Executores da interface do usuário do Spark que não mostra tarefas ativas para nenhum executor
- A guia SQL da UI do Spark mostrando
nThreads
consultas em execução sem IDs de tarefa em execução
Meu ambiente de execução é
- AWS EMR 5.28.1
- Spark 2.4.4
- Nó mestre =
m5.4xlarge
- Nós principais = 3x
rd5.24xlarge
spark.driver.cores=24
spark.driver.memory=32g
spark.executor.memory=21g
spark.scheduler.mode=FIFO
jstack -l
para obter um despejo de thread com informações de bloqueio.