SparkShell(scala)暂存的SparkSession变量是val还是var?
我正在尝试将Spark Scala脚本(用SparkShell(scala)暂存的SparkSession变量是val还是var?,scala,apache-spark,apache-spark-sql,spark-shell,Scala,Apache Spark,Apache Spark Sql,Spark Shell,我正在尝试将Spark Scala脚本(用Spark shell编写)转换为Scala类、对象、方法(def)等。因此我为Spark submit创建JAR。我使用Spark SQL进行了很多调用,它执行了很多关于时区的时间戳计算。我必须显式地设置以下配置(因为每个分布式节点可能配置了不同的默认时区),以确保我的时区对于该方法中任何Spark SQL函数调用(代码块)进行的任何后续Spark SQL时间戳操作始终为UTC spark.conf.set(“spark.sql.session.tim
Spark shell
编写)转换为Scala类、对象、方法(def)等。因此我为Spark submit
创建JAR。我使用Spark SQL进行了很多调用,它执行了很多关于时区的时间戳计算。我必须显式地设置以下配置(因为每个分布式节点可能配置了不同的默认时区),以确保我的时区对于该方法中任何Spark SQL函数调用(代码块)进行的任何后续Spark SQL时间戳操作始终为UTC
spark.conf.set(“spark.sql.session.timeZone”,“UTC”)
该方法签名是否应该包括(spark:org.apache.spark.sql.SparkSession)作为参数,这样我就可以始终从显式代码语句开始,将时区设置为UTC,设置为SparkSession
,而不必冒任何风险(所有分布式spark节点可能具有也可能不具有完全相同的时区配置)
我的下一个问题是,如何确定spark shell
设置的“spark”变量是val
还是var
?在寻找这个问题的答案时,我发现了这个问题,希望找出这个Scala变量是不可变的
还是可变的
。但它没有告诉我Scala变量spark
是var
还是val
。在我将spark.sql.session.timeZone
设置为UTC
后,是否需要将spark
返回给方法调用方,因为我在方法中修改了它?目前,我的方法签名需要两个输入参数(org.apache.spark.sql.SparkSession,org.apache.spark.sql.DataFrame)
,输出是一个元组(org.apache.spark.sql.SparkSession,org.apache.spark.sql.DataFrame)
额外上下文:
作为启动spark shell
的一部分,变量spark
初始化如下:
Spark context available as 'sc' (master = yarn, app id = application_1234567890_111111).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.4.4
/_/
Using Scala version 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_REDACTED)
Type in expressions to have them evaluated.
Type :help for more information.
感谢您为我的问题提供了答案和提示。我实现了以下实验,即spark
是一个可变对象,我只是使用spark
作为方法外部和方法内部相同对象的相同引用。虽然这种不受欢迎的副作用不是纯粹的功能实现,但它确实为我省去了将spark
对象返回调用者进行其他后续处理的麻烦。如果其他人有更好的解决方案,请分享
def x(spark: SparkSession, inputDF: DataFrame) = {
import spark.implicits._
spark.conf.set("spark.sql.session.timeZone", "UTC") // mutation of the object inside method
//...spark.sql.functions...
finalDF
}
启动火花壳并执行以下操作:
Spark context available as 'sc' (master = yarn, app id = application_1234567890_222222).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.4.4
/_/
Using Scala version 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_REDACTED)
Type in expressions to have them evaluated.
Type :help for more information.
scala> spark.conf.get("spark.sql.session.timeZone")
res1: String = America/New_York
scala> :load x.scala
x: (spark: org.apache.spark.sql.SparkSession, inputDF: org.apache.spark.sql.DataFrame)org.apache.spark.sql.DataFrame
scala> val timeConvertedDF = x(spark, inputDF)
timeConvertedDF: org.apache.spark.sql.DataFrame = [att1: timestamp, att2: string ... 25 more fields]
scala> spark.conf.get("spark.sql.session.timeZone")
res4: String = UTC
它是一个val,在任何情况下,如果您不打算对它进行变异(这没有意义),它不在乎外壳上是什么,只要将它设置为
val
。事实上,我正在通过spark.conf.set(“spark.sql.session.timezone”,“UTC”)将时区设置为UTC,这是我的Sql SQL时区计算正确的前一步,难道这不是一个突变吗?是的,这是一个突变,但是你可以在<代码> Val<代码>上有一个可变对象——如果你不理解可变对象与可变引用之间的区别,在继续使用Spark之前,我鼓励您学习更多有关Scala的知识。感谢您提示Spark
是一个val
并且是一个可变对象!对可变对象的良好引用。
Spark context available as 'sc' (master = yarn, app id = application_1234567890_222222).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.4.4
/_/
Using Scala version 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_REDACTED)
Type in expressions to have them evaluated.
Type :help for more information.
scala> spark.conf.get("spark.sql.session.timeZone")
res1: String = America/New_York
scala> :load x.scala
x: (spark: org.apache.spark.sql.SparkSession, inputDF: org.apache.spark.sql.DataFrame)org.apache.spark.sql.DataFrame
scala> val timeConvertedDF = x(spark, inputDF)
timeConvertedDF: org.apache.spark.sql.DataFrame = [att1: timestamp, att2: string ... 25 more fields]
scala> spark.conf.get("spark.sql.session.timeZone")
res4: String = UTC