本文為您介紹如何搭建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煙霧測試 (Smoke Test)
完成以上的工作之後,執行煙霧測試 (Smoke Test),驗證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。