本文為您介紹如何搭建Spark on MaxCompute開發環境。
如果您安裝了Windows操作系統,請前往搭建Windows開發環境。
前提條件
搭建Spark開發環境前,請確保您已經在Linux操作系統中安裝如下軟件:
本文采用的軟件版本號及軟件安裝路徑僅供參考,請根據您的操作系統下載合適的軟件版本進行安裝。
JDK
安裝命令示例如下。JDK名稱請以實際為準。具體的JDK名稱可通過執行
sudo yum -y list java*
獲取。sudo yum install -y java-1.8.0-openjdk-devel.x86_64
Python
安裝命令示例如下。Python包名稱請以實際為準。
# 獲取Python包。 sudo wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tgz # 解壓縮Python包。 sudo tar -zxvf Python-2.7.10.tgz # 切換到解壓后的目錄,指定安裝路徑。 cd Python-2.7.10 sudo ./configure --prefix=/usr/local/python2 # 編譯并安裝Python。 sudo make sudo make install
Maven
安裝命令示例如下。Maven包路徑請以實際為準。
# 獲取Maven包。 sudo wget https://dlcdn.apache.org/maven/maven-3/3.8.7/binaries/apache-maven-3.8.7-bin.tar.gz # 解壓縮Maven包。 sudo tar -zxvf apache-maven-3.8.7-bin.tar.gz
Git
安裝命令示例如下。
# 獲取Git包。 sudo wget https://github.com/git/git/archive/v2.17.0.tar.gz # 解壓縮Git包。 sudo tar -zxvf v2.17.0.tar.gz # 安裝編譯源碼所需依賴。 sudo yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker # 切換到解壓后的目。 cd git-2.17.0 # 編譯。 sudo make prefix=/usr/local/git all # 安裝Git至/usr/local/git路徑。 sudo make prefix=/usr/local/git install
下載Spark on MaxCompute客戶端包并上傳至操作系統
Spark on MaxCompute發布包集成了MaxCompute認證功能。作為客戶端工具,它通過Spark-Submit方式提交作業到MaxCompute項目中運行。MaxCompute提供了面向Spark1.x、Spark2.x和Spark3.x發布包,下載路徑如下:
Spark-1.6.3:適用于Spark1.x應用的開發。
Spark-2.3.0:適用于Spark2.x應用的開發。
Spark-2.4.5:適用于Spark2.x應用的開發。使用Spark-2.4.5的注意事項請參見Spark 2.4.5使用注意事項。
Spark-3.1.1:適用于Spark3.x應用的開發。使用Spark-3.1.1的注意事項請參見Spark 3.1.1使用注意事項。
將Spark on MaxCompute客戶端包上傳至Linux操作系統中,并解壓。您可以進入Spark客戶端包所在目錄,執行如下命令解壓包。
sudo tar -xzvf spark-2.3.0-odps0.33.0.tar.gz
設置環境變量
下述設置環境變量的命令,只能由具有管理員權限的用戶執行。
您需要在Linux操作系統的命令行執行窗口配置如下環境變量信息,配置方法及信息如下。
配置Java環境變量。
獲取Java安裝路徑。命令示例如下。
# 如果通過yum方式安裝,默認安裝在usr目錄下,您可以按照如下命令查找。如果您自定義了安裝路徑,請以實際路徑為準。 whereis java ls -lrt /usr/bin/java ls -lrt /etc/alternatives/java # 返回信息如下。/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-1.1.al7.x86_64即為安裝路徑。 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-1.1.al7.x86_64/jre/bin/java
編輯Java環境變量信息。命令示例如下。
# 編輯環境變量配置文件。 vim /etc/profile # 按下i進入編輯狀態后,在配置文件末尾添加環境變量信息。 # JAVA_HOME需要修改為實際Java的安裝路徑。 export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-1.1.al7.x86_64 export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$JAVA_HOME/bin:$PATH # 按ESC退出編輯,按:wq退出配置文件。 # 執行如下命令使修改生效。 source /etc/profile # 確認Java已配置成功。 java -version # 返回結果示例如下。 openjdk version "1.8.0_322" OpenJDK Runtime Environment (build 1.8.0_322-b06) OpenJDK 64-Bit Server VM (build 25.322-b06, mixed mode)
配置Spark環境變量。
獲取Spark客戶端包解壓后的路徑。圖示如下,表明包所在路徑為
/home/spark-2.3.0-odps0.33.0
。請以實際解壓路徑及名稱為準。編輯Spark環境變量信息。命令示例如下。
# 編輯環境變量配置文件。 vim /etc/profile # 按下i進入編輯狀態后,在配置文件末尾添加環境變量信息。 # SPARK_HOME需要修改為實際解壓后的Spark客戶端包所在路徑。 export SPARK_HOME=/home/spark-2.3.0-odps0.33.0 export PATH=$SPARK_HOME/bin:$PATH # 按ESC退出編輯,按:wq退出配置文件。 # 執行如下命令使修改生效。 source /etc/profile
配置Python環境變量。
使用PySpark的用戶,需要配置該信息。
獲取Python安裝路徑。命令示例如下。
編輯Python環境變量信息。命令示例如下。
# 編輯環境變量配置文件。 vim /etc/profile # 按下i進入編輯狀態后,在配置文件末尾添加環境變量信息。 # PATH需要修改為Python的實際安裝路徑。 export PATH=/usr/bin/python/bin/:$PATH # 按ESC退出編輯,按:wq退出配置文件。 # 執行如下命令使修改生效。 source /etc/profile # 確認Python已配置成功。 python --version # 返回結果示例如下。 Python 2.7.5
配置Maven環境變量。
獲取Maven包解壓后的路徑。圖示如下,表明包所在路徑為
/home/apache-maven-3.8.7
。請以實際解壓路徑及名稱為準。編輯Maven環境變量信息。命令示例如下。
# 編輯環境變量配置文件。 vim /etc/profile # 按下i進入編輯狀態后,在配置文件末尾添加環境變量信息。 # MAVEN_HOME需要修改為實際解壓后的Maven包所在路徑。 export MAVEN_HOME=/home/apache-maven-3.8.7 export PATH=$MAVEN_HOME/bin:$PATH # 按ESC退出編輯,按:wq退出配置文件。 # 執行如下命令使修改生效。 source /etc/profile # 確認Maven已配置成功。 mvn -version # 返回結果示例如下。 Apache Maven 3.8.7 (9b656c72d54e5bacbed989b64718c159fe39b537) Maven home: /home/apache-maven-3.8.7 Java version: 1.8.0_322, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-1.1.al7.x86_64/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "4.19.91-25.1.al7.x86_64", arch: "amd64", family: "unix"
配置Git環境變量。
獲取Git安裝路徑。命令示例如下。
whereis git
編輯Git環境變量信息。命令示例如下。
# 編輯環境變量配置文件。 vim /etc/profile # 按下i進入編輯狀態后,在配置文件末尾添加環境變量信息。# PATH需要修改為Git的實際安裝路徑。 export PATH=/usr/local/git/bin/:$PATH # 按ESC退出編輯,按:wq退出配置文件。 # 執行如下命令使修改生效。 source /etc/profile # 確認Git已配置成功。 git --version # 返回結果示例如下。 git version 2.24.4
配置spark-defaults.conf
第一次使用Spark on MaxCompute客戶端時,請在Spark客戶端包的解壓路徑下,將conf
文件夾下的spark-defaults.conf.template文件重命名為spark-defaults.conf后再進行相關配置。如果沒有對文件進行重命名,將會導致配置無法生效。命令示例如下。
# 切換至Spark客戶端包的解壓路徑,并進入conf文件夾。請以實際路徑為準。
cd /home/spark-2.3.0-odps0.33.0/conf
# 修改文件名。
mv spark-defaults.conf.template spark-defaults.conf
# 編輯spark-defaults.conf。
vim spark-defaults.conf
# 按下i進入編輯狀態后,在配置文件末尾添加如下配置信息。
spark.hadoop.odps.project.name = <MaxCompute_project_name>
spark.hadoop.odps.access.id = <AccessKey_id>
spark.hadoop.odps.access.key = <AccessKey_secret>
spark.hadoop.odps.end.point = <Endpoint> # Spark客戶端連接訪問MaxCompute項目的Endpoint,您可以根據自己情況進行修改。詳情請參見Endpoint。
# spark 2.3.0請將spark.sql.catalogImplementation設置為odps,spark 2.4.5請將spark.sql.catalogImplementation設置為hive。
spark.sql.catalogImplementation={odps|hive}
# 如下參數配置保持不變
spark.hadoop.odps.task.major.version = cupid_v2
spark.hadoop.odps.cupid.container.image.enable = true
spark.hadoop.odps.cupid.container.vm.engine.type = hyper
spark.hadoop.odps.moye.trackurl.host = http://jobview.odps.aliyun.com
MaxCompute_project_name:待訪問MaxCompute項目的名稱。
此處為MaxCompute項目名稱,非工作空間名稱。您可以登錄MaxCompute控制臺,左上角切換地域后,在左側導航欄選擇工作區 > 項目管理,查看具體的MaxCompute項目名稱。
AccessKey_id:具備目標MaxCompute項目訪問權限的AccessKey ID。
您可以進入AccessKey管理頁面獲取AccessKey ID。
AccessKey_secret:AccessKey ID對應的AccessKey Secret。
您可以進入AccessKey管理頁面獲取AccessKey Secret。
Endpoint:MaxCompute項目所屬區域的外網Endpoint。
各地域的外網Endpoint信息,請參見各地域Endpoint對照表(外網連接方式)。
VPC_endpoint:MaxCompute項目所屬區域的VPC網絡的Endpoint。
各地域的VPC網絡Endpoint信息,請參見各地域Endpoint對照表(阿里云VPC網絡連接方式)。
特殊場景和功能,需要開啟一些其他的配置參數,詳情請參見Spark配置詳解。
準備項目工程
Spark on MaxCompute提供了項目工程模板,建議您下載模板復制后直接在模板里開發。
模板工程里的關于spark依賴的scope為provided,請不要更改,否則提交的作業無法正常運行。
準備項目工程命令示例如下:
下載Spark-1.x模板并編譯
git clone https://github.com/aliyun/MaxCompute-Spark.git cd MaxCompute-Spark/spark-1.x mvn clean package
下載Spark-2.x 模板并編譯
git clone https://github.com/aliyun/MaxCompute-Spark.git cd MaxCompute-Spark/spark-2.x mvn clean package
下載Spark-3.x 模板并編譯
git clone https://github.com/aliyun/MaxCompute-Spark.git cd MaxCompute-Spark/spark-3.x mvn clean package
上述命令執行完畢后,如果顯示創建失敗,說明環境配置有誤,請按照上述配置指導仔細檢查并修正環境配置信息。
配置依賴說明
在準備的Spark on MaxCompute項目下,配置依賴信息。命令示例如下。
配置訪問MaxCompute表所需的依賴。
使用Spark-1.x模板場景
# 進入spark-1.x文件夾。 cd MaxCompute-Spark/spark-1.x # 編輯Pom文件,添加odps-spark-datasource依賴。 <dependency> <groupId>com.aliyun.odps</groupId> <artifactId>odps-spark-datasource_2.10</artifactId> <version>3.3.8-public</version> </dependency>
使用Spark-2.x模板場景
# 進入spark-2.x文件夾。 cd MaxCompute-Spark/spark-2.x # 編輯Pom文件,添加odps-spark-datasource依賴。 <dependency> <groupId>com.aliyun.odps</groupId> <artifactId>odps-spark-datasource_2.11</artifactId> <version>3.3.8-public</version> </dependency>
配置訪問OSS所需的依賴。
如果作業需要訪問OSS,直接添加以下依賴即可。
<dependency> <groupId>com.aliyun.odps</groupId> <artifactId>hadoop-fs-oss</artifactId> <version>3.3.8-public</version> </dependency>
更多Spark-1.x、Spark-2.x以及Spark-3.x的依賴配置信息,請參見Spark-1.x pom文件、Spark-2.x pom文件和Spark-3.x pom文件。
引用外部文件
用戶在開發過程中涉及到如下場景時,需要引用外部文件:
作業需要讀取一些配置文件。
作業需要額外的資源包或第三方庫。例如JAR包、Python庫。
在實際操作中,您需要先上傳文件后才可以引用文件,上傳文件方式有以下兩種,任選其中一種即可:
方式一:通過Spark參數上傳文件
Spark on MaxCompute支持Spark社區版原生的
--jars
、--py-files
、--files
、--archives
參數,您可以在提交作業時,通過這些參數上傳文件,這些文件在作業運行時會被上傳到用戶的工作目錄下。通過Spark on MaxCompute客戶端,使用Spark-Submit方式上傳文件。
說明--jars
:會將配置的JAR包上傳至Driver和Executor的當前工作目錄,多個文件用英文逗號(,)分隔。這些JAR包都會加入Driver和Executor的Classpath。在Spark作業中直接通過"./your_jar_name"
即可引用,與社區版Spark行為相同。--files
、--py-files
:會將配置的普通文件或Python文件上傳至Driver和Executor的當前工作目錄,多個文件用英文逗號(,)分隔。在Spark作業中直接通過"./your_file_name"
即可引用,與社區版Spark行為相同。--archives
:與社區版Spark行為略有不同,多個文件用英文逗號(,)分隔,配置方式為xxx#yyy
,會將配置的歸檔文件(例如.zip)解壓到Driver和Executor的當前工作目錄的子目錄中。例如當配置方式為xx.zip#yy
時,應以"./yy/xx/"
引用到歸檔文件中的內容;當配置方式為xx.zip
時,應以"./xx.zip/xx/"
引用到歸檔文件中的內容。如果一定要將歸檔內容直接解壓到當前目錄,即直接引用"./xxx/"
,請使用下文中的spark.hadoop.odps.cupid.resources
參數進行配置。
通過DataWorks,添加作業需要的資源,操作詳情請參見創建并使用MaxCompute資源。
說明DataWorks中上傳資源限制最大為200 MB,如果需要使用更大的資源,您需要通過MaxCompute客戶端將資源上傳為MaxCompute資源,并將資源添加至數據開發面板。更多MaxCompute資源信息,請參見MaxCompute資源管理。
方式二:通過MaxCompute資源上傳文件
Spark on MaxCompute提供
spark.hadoop.odps.cupid.resources
參數,可以直接引用MaxCompute中的資源,這些資源在作業運行時會被上傳到用戶的工作目錄下。使用方式如下:通過MaxCompute客戶端將文件上傳至MaxCompute項目。單個文件最大支持500 MB。
在Spark作業配置中添加
spark.hadoop.odps.cupid.resources
參數,指定Spark作業運行所需要的MaxCompute資源。格式為<projectname>.<resourcename>
,如果需要引用多個文件,需要用英文逗號(,)分隔。配置示例如下:spark.hadoop.odps.cupid.resources=public.python-python-2.7-ucs4.zip,public.myjar.jar
指定的資源將被下載到Driver和Executor的當前工作目錄,資源下載到工作目錄后默認名稱是
<projectname>.<resourcename>
。此外,您可以在配置時通過
<projectname>.<resourcename>:<newresourcename>
方式重命名資源名稱。配置示例如下:spark.hadoop.odps.cupid.resources=public.myjar.jar:myjar.jar
重要該配置項必須在spark-defaults.conf或DataWorks的配置項中進行配置才能生效,不能寫在代碼中。
通過上述兩種方式將文件上傳后,即可在代碼中引用文件,文件讀取示例如下:
val targetFile = "文件名"
val file = Source.fromFile(targetFile)
for (line <- file.getLines)
println(line)
file.close
SparkPi冒煙測試
完成以上的工作之后,執行冒煙測試,驗證Spark on MaxCompute是否可以端到端連通。以Spark-2.x為例,您可以提交一個SparkPi驗證功能是否正常,提交命令如下。
# /path/to/MaxCompute-Spark請指向正確的編譯出來后的應用程序的Jar包。
cd $SPARK_HOME
bin/spark-submit \
--class com.aliyun.odps.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
/path/to/your/spark-examples_2.11-1.0.0-SNAPSHOT-shaded.jar
# 當看到以下日志表明冒煙作業成功。
19/06/11 11:57:30 INFO Client:
client token: N/A
diagnostics: N/A
ApplicationMaster host: 11.222.166.90
ApplicationMaster RPC port: 38965
queue: queue
start time: 1560225401092
final status: SUCCEEDED
IDEA本地執行注意事項
通常,本地調試成功后會在集群上執行代碼。但是Spark可以支持在IDEA里以Local模式直接運行代碼,運行時請注意以下幾點:
代碼需要手動設置spark.master。
val spark = SparkSession .builder() .appName("SparkPi") .config("spark.master", "local[4]") // 需要設置spark.master為local[N]才能直接運行,N為并發數。 .getOrCreate()
在IDEA里手動添加Spark on MaxCompute客戶端的相關依賴。
<dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_${scala.binary.version}</artifactId> <version>${spark.version}</version> <scope>provided</scope> </dependency>
pom.xml中設置要求scope為provided,所以運行時會出現NoClassDefFoundError報錯。
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/sql/SparkSession$ at com.aliyun.odps.spark.examples.SparkPi$.main(SparkPi.scala:27) at com.aliyun.odps.spark.examples.Spa。r。kPi.main(SparkPi.scala) Caused by: java.lang.ClassNotFoundException: org.apache.spark.sql.SparkSession$ at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 2 more
您可以按照以下方式手動將Spark on MaxCompute下的Jars目錄加入IDEA模板工程項目中,既可以保持
scope=provided
,又能在IDEA里直接運行不報錯:在IDEA中單擊頂部菜單欄上的File,選中Project Structure…。
在Project Structure頁面,單擊左側導航欄上的Modules。選擇資源包,并單擊資源包的Dependencies頁簽。
在資源包的Dependencies頁簽下,單擊左下角的+,選擇JARs or directories…添加Spark on MaxCompute下的Jars目錄。
Local不能直接引用spark-defaults.conf里的配置,需要手動指定相關配置。
通過Spark-Submit方式提交作業,系統會讀取spark-defaults.conf文件中的配置。通過Local模式提交作業,需要手動在代碼里指定相關配置。例如,在Local模式下如果要通過Spark-Sql讀取MaxCompute的表,配置如下。
val spark = SparkSession .builder() .appName("SparkPi") .config("spark.master", "local[4]") // 需設置spark.master為local[N]才能直接運行,N為并發數。 .config("spark.hadoop.odps.project.name", "****") .config("spark.hadoop.odps.access.id", "****") .config("spark.hadoop.odps.access.key", "****") .config("spark.hadoop.odps.end.point", "http://service.cn.maxcompute.aliyun.com/api") .config("spark.sql.catalogImplementation", "odps") .getOrCreate()
Spark 2.4.5使用注意事項
使用Spark 2.4.5提交作業
直接使用Yarn-cluster模式在本地提交任務。詳情請參見Cluster模式。
在DataWorks中配置參數
spark.hadoop.odps.spark.version=spark-2.4.5-odps0.33.0
。當前DataWorks獨享資源組尚未升級到Spark 2.4.5,用戶可以采用公共資源組進行調度,或聯系MaxCompute技術支持團隊進行升級。
Spark 2.4.5使用變化
如果使用Yarn-cluster模式在本地提交任務,需要新增環境變量
export HADOOP_CONF_DIR=$SPARK_HOME/conf
。如果使用Local模式進行調試,需要在
$SPARK_HOME/conf
目錄下新建odps.conf文件,并添加如下配置。odps.project.name = odps.access.id = odps.access.key = odps.end.point =
Spark 2.4.5參數配置變化
spark.sql.catalogImplementation
配置為hive
。spark.sql.sources.default
配置為hive
。spark.sql.odps.columnarReaderBatchSize
,向量化讀每個batch包含的行數,默認值為4096。spark.sql.odps.enableVectorizedReader
,開啟向量化讀,默認值為True。spark.sql.odps.enableVectorizedWriter
,開啟向量化寫,默認值為True。spark.sql.odps.split.size
,該配置可以用來調節讀MaxCompute表的并發度,默認每個分區為256 MB。
Spark 3.1.1使用注意事項
使用Spark 3.1.1提交作業
直接使用Yarn-cluster模式在本地提交任務。詳情請參見Cluster模式。
針對Scala、Java類型的作業,可以在spark-defaults.conf配置文件中添加以下參數運行Spark 3.x。
spark.hadoop.odps.cupid.resources = public.__spark_libs__3.1.1-odps0.33.0.zip,[projectname].[用戶主jar包],[projectname].[用戶其他jar包] spark.driver.extraClassPath = ./public.__spark_libs__3.1.1-odps0.33.0.zip/* spark.executor.extraClassPath = ./public.__spark_libs__3.1.1-odps0.33.0.zip/*
說明采用如上方式提交任務,需要將所依賴的資源全部添加到spark.hadoop.odps.cupid.resources參數中(包括主JAR包),否則可能出現類找不到的問題。
暫時還無法通過以上方式提交Pyspark作業。
Spark 3.1.1使用變化
如果使用Yarn-cluster模式在本地提交任務,需要新增環境變量
export HADOOP_CONF_DIR=$SPARK_HOME/conf
。如果使用Yarn-cluster模式提交PySpark作業,需要在spark-defaults.conf配置文件添加以下參數使用Python3。
spark.hadoop.odps.cupid.resources = public.python-3.7.9-ucs4.tar.gz spark.pyspark.python = ./public.python-3.7.9-ucs4.tar.gz/python-3.7.9-ucs4/bin/python3
如果使用Local模式進行調試:
需要在
$SPARK_HOME/conf
目錄下新建odps.conf文件,并添加如下配置。odps.project.name = odps.access.id = odps.access.key = odps.end.point =
需要在代碼中添加
spark.hadoop.fs.defaultFS = file:///
,示例如下。val spark = SparkSession .builder() .config("spark.hadoop.fs.defaultFS", "file:///") .enableHiveSupport() .getOrCreate()
Spark 3.1.1參數配置變化
spark.sql.defaultCatalog
配置為odps
。spark.sql.catalog.odps
配置為org.apache.spark.sql.execution.datasources.v2.odps.OdpsTableCatalog
。spark.sql.sources.partitionOverwriteMode
配置為dynamic
。spark.sql.extensions
配置為org.apache.spark.sql.execution.datasources.v2.odps.extension.OdpsExtensions
。spark.sql.odps.enableVectorizedReader
,開啟向量化讀,默認值為True。spark.sql.odps.enableVectorizedWriter
,開啟向量化寫,默認值為True。spark.sql.catalog.odps.splitSizeInMB
,該配置可以用來調節讀MaxCompute表的并發度,默認每個分區為256 MB。