使用spark-submit往yarn集群提交任務,deploy-mode可以采用client和cluster兩種模式。
若想使用hive功能,需要滿足以下條件:
- 初始化
sparkSession
對象的時候,指定enableHiveSupport
選項; - 指定hive配置,可以有兩種方式
- 配置了hive-site.xml,若是client模式可以將其放入client端SPARK_HOME/conf目錄下,若是cluster模式需要打包到jar包中(不會去找SPARK_HOME/conf目錄)。
- 程序中指定,如下:
val spark = SparkSession .builder() .appName("Test") .config("spark.sql.parquet.writeLegacyFormat", true) .config("hive.metastore.uris", "thrift://10.18.2.3:9083") .enableHiveSupport() .getOrCreate()
可以通過用spark.catalog.listDatabases.show(false)
獲取來判斷是否正確取得hive元數據信息。
另外若要指定配置文件(如數據庫的配置文件),配置文件要隨jar包一起發送到yarn集群,否則會報找不到文件異常,可以采用以下方式:
- 使用spark-submit的
--files
參數指定文件,程序中使用org.apache.spark.SparkFiles.get("filename")
獲取; - 程序中使用
spark.sparkContext.addFile("/path/filename")
添加,獲取方法同上。
實際上以上兩種方法等效,--files
參數就會轉換為addFile。
此方法的原理是:addFile
方法會將指定的文件分發到yarn集群的每一個計算節點上,保存到程序運行時的臨時目錄。
SparkFiles.get
方法會獲取到臨時文件的絕對路徑,程序就能用這個路徑訪問文件了。
addFile
能夠添加目錄,添加目錄時會按照目錄結構分發到yarn節點。
用SparkFiles.get
獲取的時候可以填入路徑,否則獲取的時候不指定路徑,只指定文件名:
object Test {
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("Test")
.enableHiveSupport
.getOrCreate()
val df = spark.table("testtable")
spark.sparkContext.addFile("hdfs:///prop/test.properties")
// spark-submit --master yarn --class Test --files hdfs:///prop/test.properties test.jar
df.foreachPartition {
par =>
val file_absolute_path = SparkFiles.get("test.properties") //這里只指定文件名,沒有路徑
...
}
}
}
不要手動分發配置文件,可能會報錯,例如yarn集群運行的時候可能沒有權限訪問手動分發的文件等。