Искра и не Serializable DateTimeFormatter

Я пытаюсь использовать DateTimeFormatter из java.time.format в Spark, но, похоже, он не сериализуем. Это соответствующий фрагмент кода:

val pattern = "<some pattern>".r
val dtFormatter = DateTimeFormatter.ofPattern("<some non-ISO pattern>")

val logs = sc.wholeTextFiles(path)

val entries = logs.flatMap(fileContent => {
    val file = fileContent._1
    val content = fileContent._2
    content.split("\\r?\\n").map(line => line match {
      case pattern(dt, ev, seq) => Some(LogEntry(LocalDateTime.parse(dt, dtFormatter), ev, seq.toInt))
      case _ => logger.error(s"Cannot parse $file: $line"); None
    })
  })

Как избежать исключения java.io.NotSerializableException: java.time.format.DateTimeFormatter? Есть ли лучшая библиотека для разбора временных меток? Я читал, что Joda также не сериализуем и был включен в Java 8-временную библиотеку.

Ответ 1

Вы можете избежать сериализации двумя способами:

  • Предполагая, что его значение может быть постоянным, поместите форматтер в object (сделав его "статическим" ). Это означало бы, что статическое значение может быть доступно для каждого рабочего, а не для сериализации драйвера и отправки работнику:

    object MyUtils {
      val dtFormatter = DateTimeFormatter.ofPattern("<some non-ISO pattern>")
    }
    
    import MyUtils._
    logs.flatMap(fileContent => {
      // can safely use formatter here
    })
    
  • создать экземпляр для записи внутри анонимной функции. Это приводит к некоторому снижению производительности (поскольку создание экземпляра будет происходить снова и снова, на запись), поэтому используйте эту опцию только в том случае, если первое не может быть применено:

    logs.flatMap(fileContent => {
      val dtFormatter = DateTimeFormatter.ofPattern("<some non-ISO pattern>")
      // use formatter here
    })