Como otimizar seu cluster do Spark com trabalhos interativos do Spark

Neste artigo, você aprenderá:
- Como diminuir o tempo de execução do trabalho do Spark
- O que é um trabalho interativo em Ilum
- Como executar um trabalho interativo do Spark
- Diferenças entre executar um trabalho do Spark usando a API do Ilum e a API do Spark
Tipos de trabalho Ilum
Existem três tipos de trabalhos que você pode executar no Ilum: trabalho único , trabalho interativo e Código interativo . Neste artigo, vamos nos concentrar no trabalho interativo tipo. No entanto, é importante conhecer as diferenças entre os três tipos de trabalhos, então vamos dar uma rápida visão geral de cada um.
Com Trabalhos individuais , você pode enviar programas semelhantes a códigos. Eles permitem que você envie um aplicativo Spark para o cluster, com código pré-compilado, sem interação durante o tempo de execução. Nesse modo, você deve enviar um jar compilado para o Ilum, que é usado para iniciar um único trabalho. Você pode enviá-lo diretamente ou usar credenciais da AWS para obtê-lo de um bucket do S3. Um exemplo típico de uso de um único trabalho seria algum tipo de tarefa de preparação de dados.
A Ilum também fornece um interativo Modo de código , que permite enviar comandos em tempo de execução. Isso é útil para tarefas em que você precisa interagir com os dados, como análise exploratória de dados.
Trabalho interativo
Os trabalhos interativos têm sessões de longa duração, nas quais você pode enviar dados da instância do trabalho para serem executados imediatamente. O recurso matador desse modo é que você não precisa esperar que o contexto do Spark seja inicializado. Se os usuários estivessem apontando para a mesma ID de trabalho, eles interagiriam com o mesmo contexto do Spark. O Ilum encapsula a lógica do aplicativo Spark em um trabalho Spark de longa duração que é capaz de lidar com solicitações de cálculo imediatamente, sem a necessidade de aguardar a inicialização do contexto do Spark.

Iniciando um trabalho interativo
Vamos dar uma olhada em como a sessão interativa de Ilum pode ser iniciada. A primeira coisa que temos que fazer é configurar o Ilum. Você pode fazer isso facilmente com o minikube. Um tutorial com a instalação do Ilum está disponível neste link . Na próxima etapa, temos que criar um arquivo jar que contenha uma implementação da interface de trabalho do Ilum. Para usar a API de trabalho do Ilum, temos que adicioná-la ao projeto com alguns gerenciadores de dependência, como Maven ou Gradle. Neste exemplo, usaremos algum código Scala com um Gradle para calcular o PI.
O exemplo completo está disponível em nosso GitHub .
Se preferir não compilá-lo sozinho, você pode encontrar o arquivo jar compilado aqui .
O primeiro passo é criar uma pasta para o nosso projeto e alterar o diretório para ela.
$ mkdir exemplo de trabalho interativo
$ cd exemplo de trabalho interativo
Se você não tiver a versão mais recente do Gradle instalada em seu computador, verifique como fazer isso aqui . Em seguida, execute o seguinte comando em um terminal de dentro do diretório do projeto:
$ gradle init
Escolha um aplicativo Scala com Groovy como DSL. A saída deve ficar assim:
Iniciar um Daemon do Gradle (as compilações subsequentes serão mais rápidas)
Selecione o tipo de projeto a ser gerado:
1: básico
2: Aplicação
3: biblioteca
4: Plug-in do Gradle
Insira a seleção (padrão: básico) [1..4] 2
Selecione o idioma de implementação:
1: C++
2: Groovy
3: Java
4: Kotlin
5: Escalão
6: Rápido
Insira a seleção (padrão: Java) [1..6] 5
Dividir a funcionalidade em vários subprojetos?:
1: não - apenas um projeto de aplicativo
2: Sim - Projetos de aplicativos e bibliotecas
Insira a seleção (padrão: não - apenas um projeto de aplicativo) [1..2] 1
Selecione a DSL do script de compilação:
1: Groovy
2: Kotlin
Insira a seleção (padrão: Groovy) [1..2] 1
Gerar compilação usando novas APIs e comportamento (alguns recursos podem mudar na próxima versão secundária)? (Padrão: não) [Sim, não] Não
Nome do projeto (padrão: interactive-job-example):
Pacote de origem (padrão: interactive.job.example):
> Tarefa: init
Obtenha mais ajuda com seu projeto: https://docs.gradle.org/7.5.1/samples/sample_building_scala_applications_multi_project.html
CONSTRUÇÃO BEM-SUCEDIDA em 30s
2 tarefas acionáveis: 2 executadas
Agora temos que adicionar o repositório Ilum e as dependências necessárias ao seu build.gradle arquivo. Neste tutorial, usaremos o Scala 2.12.
dependências {
implementação 'org.scala-lang:scala-library:2.12.16'
implementação 'cloud.ilum:ilum-job-api:5.0.1'
compileOnly 'org.apache.spark:spark-sql_2.12:3.1.2'
}
Agora podemos criar uma classe Scala que estende o Job de Ilum e que calcula PI:
pacote interativo.job.example
importar nuvem.ilum.job.Job
import org.apache.spark.sql.SparkSession
importar scala.math.random
class InteractiveJobExample extends Job {
override def run(sparkSession: SparkSession, config: Map[String, Any]): Option[String] = {
val slices = config.getOrElse("slices", "2").toString.toInt
val n = math.min(100000L * fatias, Int.MaxValue).toInt
val count = sparkSession.sparkContext.parallelize(1 até n, fatias).map { i =>
val x = aleatório * 2 - 1
val y = aleatório * 2 - 1
se (x * x + y * y <= 1) 1 else 0
}.reduce(_ + _)
Some(s"Pi é aproximadamente ${4.0 * count / (n - 1)}")
}
}
Se o Gradle gerou algumas classes principais ou de teste, basta removê-las do projeto e fazer uma compilação.
$ compilação do gradle
O arquivo jar gerado deve estar em ' ./exemplo-de-trabalho-interativo/app/build/libs/app.jar ', podemos então voltar para Ilum. Depois que todos os pods estiverem em execução, faça um encaminhamento de porta para ilum-ui:
SVC/ILUM-UI de encaminhamento de porta kubectl 9777:9777
Abra a interface do usuário do Ilum em seu navegador e crie um novo grupo:

Coloque o nome de um grupo, escolha ou crie um cluster, carregue seu arquivo jar e aplique as alterações:

O Ilum criará um pod de driver do Spark e você poderá controlar o número de pods de executores do Spark dimensionando-os. Depois que o contêiner do Spark estiver pronto, vamos executar os trabalhos:

Agora temos que colocar o nome canônico da nossa classe Scala
interactive.job.example.InteractiveJobExample
e defina o parâmetro slices no formato JSON:
{
"config": {
"fatias": "10"
}
}
Você deve ver o resultado logo após o início do trabalho

Você pode alterar parâmetros e executar novamente um trabalho e seus cálculos ocorrerão no local.
Comparação interativa e de trabalho único
No Ilum, você também pode executar um único trabalho. A diferença mais importante em comparação com o modo interativo é que você não precisa implementar a API de trabalho. Podemos usar o jar SparkPi de exemplos do Spark:

Executar um trabalho como esse também é rápido, mas os trabalhos interativos são 20 vezes mais rápido (4s vs 200ms) . Se você quiser iniciar um trabalho semelhante com outros parâmetros, terá que preparar um novo trabalho e fazer o upload do jar novamente.
Comparação entre Ilum e Apache Spark simples
Configurei o Apache Spark localmente com um bitnami/faísca imagem do docker. Se você também quiser executar o Spark em sua máquina, poderá usar docker-compose:
$ curl -LO https://raw.githubusercontent.com/bitnami/containers/main/bitnami/spark/docker-compose.yml
$ docker-compose para cima
Depois que o Spark estiver em execução, você poderá acessar localhost:8080 e ver a interface do usuário do administrador. Precisamos obter o URL do Spark no navegador:
Em seguida, temos que abrir o contêiner do Spark no modo interativo usando
$ docker exec -it <containerid> -- bash
E agora, dentro do contêiner, podemos enviar o trabalho do sparkPi. Neste caso, usará o SparkiPi do jar de exemplos e, como parâmetro mestre, colocará a URL do navegador:
$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi\
--mestre spark://78c84485d233:7077 \
/opt/bitnami/spark/exemplos/jars/spark-examples_2.12-3.3.0.jar\
10
Resumo
Como você pode ver no exemplo acima, você pode evitar a configuração e a instalação complicadas do cliente Spark usando o Ilum. Ilum assume o trabalho e fornece uma interface simples e conveniente. Além disso, permite superar as limitações do Apache Spark, que podem levar muito tempo para inicializar. Se você tiver que fazer muitas execuções de trabalho com lógica semelhante, mas parâmetros diferentes e gostaria de ter cálculos feitos imediatamente, você definitivamente deve usar o modo de trabalho interativo.

Semelhanças com Apache Livy
O Ilum é uma ferramenta nativa da nuvem para gerenciar implantações do Apache Spark no Kubernetes. É semelhante ao Apache Livy em termos de funcionalidade - ele pode controlar uma sessão do Spark por meio da API REST e criar uma interação em tempo real com um cluster do Spark. No entanto, o Ilum foi projetado especificamente para ambientes modernos e nativos da nuvem.
Usamos o Apache Livy no passado, mas chegamos ao ponto em que o Livy simplesmente não era adequado para ambientes modernos. Tito Lívio está obsoleto em comparação com Ilum. Em 2018, começamos a mover todos os nossos ambientes para o Kubernetes e tivemos que encontrar uma maneira de implantar, monitorar e manter o Apache Spark no Kubernetes. Esta foi a ocasião perfeita para construir Ilum.