Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 火花UDF螺纹安全_Scala_Apache Spark_Concurrency - Fatal编程技术网

Scala 火花UDF螺纹安全

Scala 火花UDF螺纹安全,scala,apache-spark,concurrency,Scala,Apache Spark,Concurrency,我使用Spark获取包含一列日期的数据框,并创建3个新列,其中包含从列中的日期到今天之间的时间(以天、周和月为单位) 我关心的是SimpleDataFormat的使用,它不是线程安全的。通常如果没有Spark,这会很好,因为它是一个局部变量,但是使用Spark的惰性计算,在多个UDF上共享一个SimpleDataFormat实例是否可能导致问题 def calcTimeDifference(...){ val sdf = new SimpleDateFormat(dateFormat)

我使用Spark获取包含一列日期的数据框,并创建3个新列,其中包含从列中的日期到今天之间的时间(以天、周和月为单位)

我关心的是SimpleDataFormat的使用,它不是线程安全的。通常如果没有Spark,这会很好,因为它是一个局部变量,但是使用Spark的惰性计算,在多个UDF上共享一个SimpleDataFormat实例是否可能导致问题

def calcTimeDifference(...){
    val sdf = new SimpleDateFormat(dateFormat)

    val dayDifference = udf{(x: String) => math.abs(Days.daysBetween(new DateTime(sdf.parse(x)), presentDate).getDays)}
    output = output.withColumn("days", dayDifference(myCol))

    val weekDifference = udf{(x: String) => math.abs(Weeks.weeksBetween(new DateTime(sdf.parse(x)), presentDate).getWeeks)}
    output = output.withColumn("weeks", weekDifference(myCol))

    val monthDifference = udf{(x: String) => math.abs(Months.monthsBetween(new DateTime(sdf.parse(x)), presentDate).getMonths)}
    output = output.withColumn("months", monthDifference(myCol))
}

我认为它是不安全的,正如我们所知,SimpleDateFormat不是线程安全的

因此,如果您需要,我更喜欢在Spark中使用SimpleDataFormat这种方法:

import java.text.SimpleDateFormat
import java.util.SimpleTimeZone

/**
  * Thread Safe SimpleDateFormat for Spark.
  */
object ThreadSafeFormat extends ThreadLocal[SimpleDateFormat] {

  override def initialValue(): SimpleDateFormat = {
    val dateFormat = new SimpleDateFormat("yyyy-MM-dd:H")
    // if you need get UTC time, you can set UTC timezone
    val utcTimeZone = new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC")
    dateFormat.setTimeZone(utcTimeZone)
    dateFormat
  }

}

然后使用
ThreadSafeFormat.get()
获取线程安全的SimpleDataFormat来执行任何操作。

我认为您是安全的,因为
sdf
将对每个任务进行序列化和反序列化,这意味着您在每个任务中都有单独的实例。我只是不确定每个任务实际上是有一个实例,还是每个执行者都有一个实例——在后一种情况下,您会遇到一个问题,因为每个执行者可能并行运行多个任务。