【问题标题】:Is the SparkSession variable staged by spark-shell (scala) a val or a var?由 spark-shell (scala) 暂存的 SparkSession 变量是 val 还是 var?
【发布时间】:2020-02-25 10:37:47
【问题描述】:

我正在尝试将我的 Spark Scala 脚本(用 spark-shell 编写)转换为 Scala 类、对象、方法(def)等,因此我为 spark-submit 创建了 JAR。我使用 Spark SQL 进行了很多调用,这些调用执行了大量关于时区的时间戳计算。我必须明确设置以下配置(因为每个分布式节点可能配置了不同的默认时区),以确保我的时区始终为 UTC,以便通过该方法中的任何 Spark SQL 函数调用(代码块)进行任何后续 Spark SQL 时间戳操作。

spark.conf.set("spark.sql.session.timeZone", "UTC")

如果该方法签名包含 (spark: org.apache.spark.sql.SparkSession) 作为参数,那么我总是可以从将时区设置为 UTC 的显式代码语句开始为SparkSession 而不会冒险(所有分布式 Spark 节点可能有也可能没有完全相同的时区配置)?

我的下一个问题是,我如何确定spark-shell 设置的“spark”变量是val 还是var?为了寻找这个问题的答案,我找到了这个code snippet,希望找出这个Scala变量是immutable还是mutable。但它没有告诉我 Scala 变量 sparkvar 还是 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)

scala> def manOf[T: Manifest](t: T): Manifest[T] = manifest[T]
manOf: [T](t: T)(implicit evidence$1: Manifest[T])Manifest[T]

scala> manOf(List(1))
res3: Manifest[List[Int]] = scala.collection.immutable.List[Int]

scala> manOf(spark)
res2: Manifest[org.apache.spark.sql.SparkSession] = org.apache.spark.sql.SparkSession

额外的上下文: 作为启动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.

【问题讨论】:

  • 它是一个 val,无论如何,如果你不打算改变它 (这没有意义) 它是什么都没关系外壳,只需将其设为val
  • 我通过spark.conf.set("spark.sql.session.timeZone", "UTC") 将时区设置为UTC,这是我的Spark SQL 时区计算正确的必要步骤,这不考虑突变吗?
  • 是的,这是一个突变,但是您可以在 val 上拥有一个可变对象 - 如果您不了解可变对象与可变引用之间的区别,我鼓励您了解更多关于 Scala 在继续 Spark 之前。
  • 感谢您提示 sparkval 并且它是可变对象!
  • 对可变对象的良好引用。 otfried.org/courses/cs109scala/tutorial_mutable.html

标签: scala apache-spark apache-spark-sql spark-shell


【解决方案1】:

感谢@Luis Miguel Mejía Suárez 为我提供问题的答案和提示。我实现了以下实验,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-shell 并执行以下操作:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    相关资源
    最近更新 更多