我在main()
函数中创建了一个会话,如下所示:
val sparkSession = SparkSession.builder.master("local[*]").appName("Simple Application").getOrCreate()
现在,如果我想配置应用程序或访问属性,我可以在同一个函数中使用局部变量sparkSession
。
如果我想在同一项目的其他地方访问sparkSession
该怎么办,例如project/module/.../.../xxx.scala
。我该怎么办?
答案 0 :(得分:18)
创建会话(任何地方)后,您可以安全地使用:
SparkSession.builder().getOrCreate()
要在代码中的任何位置进行(相同)会话,只要会话仍然存在。 Spark维护一个活动会话,因此除非它被停止或崩溃,否则你将得到相同的会话。
答案 1 :(得分:3)
自 2.2.0 起,您可以通过以下方式访问活动的SparkSession :
/**
* Returns the active SparkSession for the current thread, returned by the builder.
*
* @since 2.2.0
*/
def getActiveSession: Option[SparkSession] = Option(activeThreadSession.get)
或默认SparkSession :
/**
* Returns the default SparkSession that is returned by the builder.
*
* @since 2.2.0
*/
def getDefaultSparkSession: Option[SparkSession] = Option(defaultSession.get)
答案 2 :(得分:1)
将SparkSession
变量定义为
val sparkSession = SparkSession.builder.master("local[*]").appName("Simple Application").getOrCreate()
此变量将point/refer
仅转换为SparkSession
val
。而且你总是可以传递给不同的类来访问它们以及
val newClassCall = new NewClass(sparkSession)
现在,您也可以在新课程中使用相同的sparkSession
。
答案 3 :(得分:0)
这是一个老问题,有几个答案已经足够好了,但我想再提供一种可用于使其工作的方法。
您可以创建一个从可序列化扩展的特征,并将 spark session 创建为惰性变量,然后在您创建的所有对象中贯穿您的项目,您可以扩展该特征,它将为您提供 sparksession 实例。
代码如下:
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.DataFrame
trait SparkSessionWrapper extends Serializable {
lazy val spark: SparkSession = {
SparkSession.builder().appName("TestApp").getOrCreate()
}
//object with the main method and it extends SparkSessionWrapper
object App extends SparkSessionWrapper {
def main(args: Array[String]): Unit = {
val readdf = ReadFileProcessor.ReadFile("testpath")
readdf.createOrReplaceTempView("TestTable")
val viewdf = spark.sql("Select * from TestTable")
}
}
object ReadFileProcessor extends SparkSessionWrapper{
def ReadFile(path: String) : DataFrame = {
val df = spark.read.format("csv").load(path)
df
}
}
当您在您创建的两个对象上扩展 SparkSessionWrapper 时,当第一次在代码中遇到 spark 变量时,spark 会话将被初始化,然后您在扩展该特征的任何对象上引用它而不将其作为参数传递到方法。它的工作原理或为您提供类似于 notebook 的体验。