É verdade ... já foi discutido bastante.
No entanto, há muita ambiguidade e algumas das respostas fornecidas ... incluindo a duplicação de referências de jar nas opções ou na configuração de jars / executor / driver.
Os detalhes ambíguos e / ou omitidos
Após a ambiguidade, detalhes obscuros e / ou omitidos devem ser esclarecidos para cada opção:
- Como o ClassPath é afetado
- Motorista
- Executor (para tarefas em execução)
- Ambos
- de modo nenhum
- Caractere de separação: vírgula, dois pontos, ponto e vírgula
- Se os arquivos fornecidos forem distribuídos automaticamente
- para as tarefas (para cada executor)
- para o driver remoto (se executado no modo de cluster)
- tipo de URI aceito: arquivo local, hdfs, http, etc
- Se copiado para um local comum, onde está esse local (hdfs, local?)
As opções às quais isso afeta:
--jars
SparkContext.addJar(...)
métodoSparkContext.addFile(...)
método--conf spark.driver.extraClassPath=...
ou--driver-class-path ...
--conf spark.driver.extraLibraryPath=...
ou--driver-library-path ...
--conf spark.executor.extraClassPath=...
--conf spark.executor.extraLibraryPath=...
- para não esquecer, o último parâmetro do envio de spark também é um arquivo .jar.
Estou ciente de onde posso encontrar a documentação principal do spark e, especificamente, sobre como enviar , as opções disponíveis e também o JavaDoc . No entanto, isso deixou para mim ainda alguns buracos, embora respondesse parcialmente também.
Espero que não seja tão complexo e que alguém possa me dar uma resposta clara e concisa.
Se eu fosse adivinhar pela documentação, parece que --jars
, e os métodos SparkContext
addJar
e addFile
são os que distribuirão os arquivos automaticamente, enquanto as outras opções apenas modificam o ClassPath.
Seria seguro supor que, por simplicidade, eu posso adicionar arquivos jar de aplicativos adicionais usando as 3 opções principais ao mesmo tempo:
spark-submit --jar additional1.jar,additional2.jar \
--driver-library-path additional1.jar:additional2.jar \
--conf spark.executor.extraLibraryPath=additional1.jar:additional2.jar \
--class MyClass main-application.jar
Encontrei um bom artigo sobre uma resposta a outra postagem . No entanto, nada de novo aprendeu. O pôster faz uma boa observação sobre a diferença entre o driver local (cliente-fio) e o driver remoto (cluster de fios). Definitivamente importante ter em mente.
Respostas:
ClassPath:
O ClassPath é afetado dependendo do que você fornece. Existem algumas maneiras de definir algo no caminho de classe:
spark.driver.extraClassPath
ou é apelido--driver-class-path
para definir caminhos de classe extras no nó que está executando o driver.spark.executor.extraClassPath
para definir o caminho extra da classe nos nós do trabalhador.Se você deseja que um certo JAR seja efetuado no mestre e no trabalhador, é necessário especificá-los separadamente em AMBOS os sinalizadores.
Caractere de separação:
Seguindo as mesmas regras que a JVM :
:
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-java-sdk-1.10.50.jar"
;
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar;/opt/prog/aws-java-sdk-1.10.50.jar"
Distribuição de arquivos:
Isso depende do modo em que você está executando seu trabalho:
Modo cliente - O Spark aciona um servidor HTTP Netty que distribui os arquivos na inicialização de cada um dos nós do trabalhador. Você pode ver que, ao iniciar seu trabalho do Spark:
Modo de cluster - No modo de cluster, o spark selecionou um nó Worker líder para executar o processo do Driver. Isso significa que o trabalho não está sendo executado diretamente no nó Mestre. Aqui, o Spark não definirá um servidor HTTP. É necessário disponibilizar manualmente o seu JARS para todos os nós do trabalhador por meio de fontes HDFS / S3 / Other disponíveis para todos os nós.
URIs aceitos para arquivos
Em "Enviando aplicativos" , a documentação do Spark explica bem os prefixos aceitos para arquivos:
Conforme observado, os JARs são copiados para o diretório de trabalho de cada nó Worker. Onde exatamente é isso? É geralmente sob
/var/run/spark/work
, você vai vê-los como este:E quando você olhar para dentro, verá todos os JARs implementados:
Opções afetadas:
A coisa mais importante a entender é a prioridade . Se você passar qualquer propriedade via código, ela terá precedência sobre qualquer opção que você especificar via
spark-submit
. Isso é mencionado na documentação do Spark:Portanto, certifique-se de definir esses valores nos lugares adequados, para que você não se surpreenda quando um tiver prioridade sobre o outro.
Vamos analisar cada opção em questão:
--jars
vsSparkContext.addJar
: são idênticos, apenas um é definido através do envio de spark e outro via código. Escolha o que melhor combina com você. Uma coisa importante a ser observada é que o uso de uma dessas opções não adiciona o JAR ao caminho de classe do driver / executor , você precisará adicioná-las explicitamente usando aextraClassPath
configuração em ambas.SparkContext.addJar
vsSparkContext.addFile
: use o primeiro quando tiver uma dependência que precise ser usada com seu código. Use o último quando quiser simplesmente passar um arquivo arbitrário para os nós do trabalhador, o que não é uma dependência em tempo de execução do seu código.--conf spark.driver.extraClassPath=...
ou--driver-class-path
: esses são aliases, não importa qual você escolher--conf spark.driver.extraLibraryPath=..., or --driver-library-path ...
O mesmo que acima, aliases.--conf spark.executor.extraClassPath=...
: Use isso quando tiver uma dependência que não possa ser incluída em um JAR uber (por exemplo, porque há conflitos de tempo de compilação entre versões da biblioteca) e que você precisará carregar em tempo de execução.--conf spark.executor.extraLibraryPath=...
Isso é passado como ajava.library.path
opção para a JVM. Use isso quando precisar de um caminho de biblioteca visível para a JVM.Você pode assumir isso com segurança apenas no modo Cliente, não no modo Cluster. Como eu disse anteriormente. Além disso, o exemplo que você deu possui alguns argumentos redundantes. Por exemplo, passar JARs para
--driver-library-path
é inútil, você precisará passá-losextraClassPath
se quiser que eles estejam no seu caminho de classe. Por fim, o que você deseja fazer ao implantar JARs externos no driver e no trabalhador é:fonte
MANIFEST.MF
arquivo)?assemblyMergeStrategy
e seleciono as classes de que preciso se houver conflitos. Eu geralmente recomendo o mesmo.--jars
sinalizador e o caminho da classe driver / executor.zeppelin-env.sh
e adicioná--jars
- lasSPARK_SUBMIT_OPTIONS
. Isso funcionou. O formato URI que eu uso é--jars=local:///mnt/dir/file.jar
.Outra abordagem em
spark 2.1.0
é usar--conf spark.driver.userClassPathFirst=true
durante o envio do spark que altera a prioridade da carga de dependência e, portanto, o comportamento do trabalho do spark, dando prioridade aos jars que o usuário está adicionando ao caminho da classe com a--jars
opçãofonte
Outras opções configuráveis do Spark relacionadas a jars e classpath, no caso de
yarn
modo de implementação, são as seguintes:Na documentação do spark,
Os usuários podem configurar esse parâmetro para especificar seus jars, que são incluídos no caminho de classe do driver Spark.
fonte
Ao usar o envio de spark com --master yarn-cluster, o jar do aplicativo junto com os jars incluídos na opção --jars será automaticamente transferido para o cluster. URLs fornecidos após --jars devem ser separados por vírgulas. Essa lista está incluída nos caminhos de classe do driver e do executor
Exemplo:
spark-submit --master yarn-cluster --jars ../lib/misc.jar, ../lib/test.jar --class MainClass MainApp.jar
https://spark.apache.org/docs/latest/submitting-applications.html
fonte
Há restrições quanto ao uso
--jars
: se você deseja especificar um diretório para o local dejar/xml
arquivo, ele não permite expansões de diretório. Isso significa que você precisa especificar o caminho absoluto para cada jar.Se você especificar
--driver-class-path
e estiver executando no modo de cluster de fios, a classe de driver não será atualizada. Podemos verificar se o caminho da classe está atualizado ou não no spark ui ou no servidor de histórico do spark no ambiente da guia.A opção que funcionou para eu passar os frascos que contêm expansões de diretório e que funcionou no modo de cluster de fios foi a
--conf
opção. É melhor passar caminhos de classe de driver e executor como--conf
, o que os adiciona ao próprio objeto de sessão do spark e esses caminhos são refletidos na Configuração do Spark. Mas certifique-se de colocar os jarros no mesmo caminho no cluster.fonte
Enquanto enviamos trabalhos de faísca usando o utilitário de envio de faísca, há uma opção
--jars
. Usando esta opção, podemos passar o arquivo jar para acionar aplicativos.fonte
—jar
opção foi mencionada no pôster original, além de discutida com muito mais detalhes por mais de uma resposta. Não parece que você está fornecendo algo novo?