[Spark] 用Maven構建Spark項目時可能出現的問題
至於如何安裝Spark,這個網站寫的很清楚:Apache Spark - Installation (tutorialspoint.com)
另外建議閱讀官方文檔。裏面介紹瞭如何快速構建一個Spark項目。
這裏我想Maven來構建一個java項目。在Maven中添加Spark很容易,只需要在dependencies里加入對應的依賴即可。詳細內容可以去mvnrepository查。比如:
<dependency> <!-- Spark dependency -->
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.12</artifactId>
<version>3.3.1</version>
<scope>provided</scope>
</dependency>
可能出現的問題
問題一
Error: Failed to load class WordCount.
這可能是在spark-submit中,--class
的參數不對導致的。注意--class
的參數需要是一個完整的類名。如果你想要用的class的package是spark_test
,那麼你就要寫--class spark_test.WordCount
而不是--class WordCount
問題二
Error: Failed to load spark_test.WordCount: org/apache/logging/log4j/LogManager
我一開始使用的Spark版本是3.2.3,我想使用log4j2。但是Spark的3.2.x之前的版本使用的都是log4j1。這導致我的log4j2和Spark的log4j1產生衝突。雖然mvn package
不會出問題,但在spark-submit
時,就會報上面的那個錯誤,無法運行。
解決方法:最簡單的解決辦法就是將Spark升級到3.3.x。3.3版本以後的Spark都使用log4j2,這就直接避免了上面的問題。
如果你偏要同時使用低版本的Spark和log4j2,那外網上應該也有一些解決辦法,只不過不推薦(我也沒看懂)、
問題三
如何在spark-submit
中使用第三方庫?
比如,我使用了一個picocli
的第三方庫,並且在pom.xml
中添加了對應的依賴。這在mvn package
時是不會出任何問題的。但是當spark-submit
時,就會出現問題:
Exception in thread "main" java.lang.NoClassDefFoundError: picocli/CommandLine
這是因爲spark-submit
並沒有找到第三方庫的jar包。
解決方法:在官方文檔中已經簡要說明了解決辦法。只需要在maven的編譯過程中,將第三方庫一併編入到生成的jar包中去就好了。具體做法時使用插件,在pom.xml
中添加:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>cqzhangyu.spark_test.WordCount</mainClass> <!-- change to your own project name -->
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
在spark-submit
時,別忘了將jar文件換成生成的xxx-1.0-jar-with-dependencies.jar
文件。