SparkStreaming: избегать проверки checkpointLocation

2

Я пишу библиотеку для интеграции Apache Spark с настраиваемой средой. Я реализую как пользовательские потоковые источники, так и потоковые писатели.

Некоторые из источников, которые я разрабатываю, не подлежат восстановлению, по крайней мере, после краха приложения. Если приложение перезагружается, ему необходимо перезагрузить все данные. Поэтому мы хотели бы, чтобы пользователи не задавали явно опцию checkpointLocation. Но если опция не указана, мы видим следующую ошибку:

org.apache.spark.sql.AnalysisException: checkpointLocation must be specified either through option("checkpointLocation", ...) or SparkSession.conf.set("spark.sql.streaming.checkpointLocation", ...);

Однако, если я использую вывод консольного потока, все работает нормально.

Есть ли способ получить такое же поведение?

Примечание. Мы используем интерфейсы Spark v2 для наших потоковых считывателей/писателей.


Журнал искры:

18/06/29 16:36:48 INFO SharedState: Setting hive.metastore.warehouse.dir ('null') to the value of spark.sql.warehouse.dir ('file:/C:/mydir/spark-warehouse/').
18/06/29 16:36:48 INFO SharedState: Warehouse path is 'file:/C:/mydir/spark-warehouse/'.
18/06/29 16:36:48 INFO StateStoreCoordinatorRef: Registered StateStoreCoordinator endpoint
org.apache.spark.sql.AnalysisException: checkpointLocation must be specified either through option("checkpointLocation", ...) or SparkSession.conf.set("spark.sql.streaming.checkpointLocation", ...);
    at org.apache.spark.sql.streaming.StreamingQueryManager$$anonfun$3.apply(StreamingQueryManager.scala:213)
    at org.apache.spark.sql.streaming.StreamingQueryManager$$anonfun$3.apply(StreamingQueryManager.scala:208)
    at scala.Option.getOrElse(Option.scala:121)
    at org.apache.spark.sql.streaming.StreamingQueryManager.createQuery(StreamingQueryManager.scala:207)
    at org.apache.spark.sql.streaming.StreamingQueryManager.startQuery(StreamingQueryManager.scala:299)
    at org.apache.spark.sql.streaming.DataStreamWriter.start(DataStreamWriter.scala:296)
    ...
18/06/29 16:36:50 INFO SparkContext: Invoking stop() from shutdown hook

Вот как я запускаю потоковое задание:

spark.readStream().format("mysource").load()
  .writeStream().format("mywriter").outputMode(OutputMode.Append()).start();

Все работает отлично, вместо этого, если, например, я запускаю:

spark.readStream().format("mysource").load()
  .writeStream().format("console").outputMode(OutputMode.Append()).start();

Я не могу предоставить полный код записи данных. Во всяком случае, я сделал что-то вроде этого:

class MySourceProvider extends DataSourceRegister with StreamWriteSupport {
  def createStreamWriter(queryId: String, schema: StructType, mode: OutputMode, options: DataSourceOptions): StreamWriter = {
    new MyStreamWriter(...)
  }
  def shortName(): String = {
    "mywriter"
  }
}

class MyStreamWriter(...) extends StreamWriter { 
  def abort(epochId: Long, messages: Array[WriterCommitMessage]): Unit = {}
  def commit(epochId: Long, messages: Array[WriterCommitMessage]): Unit = {}
  def createWriterFactory(): DataWriterFactory[Row] = {
    new MyDataWriterFactory()
  }
}
  • 0
    не могли бы вы добавить полный журнал и пример кода
  • 0
    Я добавил содержимое журнала и фрагмент кода. Благодарю.
Теги:
apache-spark
spark-streaming
spark-structured-streaming

1 ответ

0
Лучший ответ

Вам нужно добавить checkpointLocation в свой код

("checkpointLocation", "/tmp/vaquarkhan/checkpoint"). //<- контрольная точка

Пример :

import org.apache.spark.sql.streaming.{OutputMode, Trigger}
import scala.concurrent.duration._
val q = records.
  writeStream.
  format("console").
  option("truncate", false).
  option("checkpointLocation", "/tmp/vaquarkhan/checkpoint"). // <-- checkpoint directory
  trigger(Trigger.ProcessingTime(10.seconds)).
  outputMode(OutputMode.Update).
  start

Обратившись к вашему вопросу, у вас есть три варианта:

.option("startOffsets", "latest")//чтение данных с конца потока

  • самое раннее - начните чтение в начале потока. Это исключает данные, которые уже были удалены из Kafka, потому что они были старше, чем период хранения (данные "устаревших").

  • last - начать сейчас, обрабатывать только новые данные, которые поступают после начала запроса.

  • для каждого раздела - указать точное смещение для начала для каждого раздела, что позволяет точно контролировать то, где должна начинаться обработка. Например, если мы хотим точно определить, где остановилась какая-либо другая система или запрос, тогда этот параметр можно использовать.

Если имя каталога для местоположения контрольной точки невозможно найти, createQuery сообщает об исключении AnalysisException.

checkpointLocation must be specified either through option("checkpointLocation", ...) or SparkSession.conf.set("spark.sql.streaming.checkpointLocation", ...)

Ниже приведен искровой код apache:

  private def createQuery(
      userSpecifiedName: Option[String],
      userSpecifiedCheckpointLocation: Option[String],
      df: DataFrame,
      extraOptions: Map[String, String],
      sink: BaseStreamingSink,
      outputMode: OutputMode,
      useTempCheckpointLocation: Boolean,
      recoverFromCheckpointLocation: Boolean,
      trigger: Trigger,
      triggerClock: Clock): StreamingQueryWrapper = {
    var deleteCheckpointOnStop = false
    val checkpointLocation = userSpecifiedCheckpointLocation.map { userSpecified =>
      new Path(userSpecified).toUri.toString
    }.orElse {
      df.sparkSession.sessionState.conf.checkpointLocation.map { location =>
        new Path(location, userSpecifiedName.getOrElse(UUID.randomUUID().toString)).toUri.toString
      }
    }.getOrElse {
      if (useTempCheckpointLocation) {
        // Delete the temp checkpoint when a query is being stopped without errors.
        deleteCheckpointOnStop = true
        Utils.createTempDir(namePrefix = s"temporary").getCanonicalPath
      } else {
        throw new AnalysisException(
          "checkpointLocation must be specified either " +
            """through option("checkpointLocation", ...) or """ +
            s"""SparkSession.conf.set("${SQLConf.CHECKPOINT_LOCATION.key}", ...)""")
      }
    }
  • 0
    Спасибо за Ваш ответ. Но на самом деле мне было интересно, можно ли избежать этой проверки в опции checkpointLocation, так как кажется, что если я использую вывод консоли, это не требуется. Я пытался хотя бы понять причину такого поведения.
  • 0
    Вы не можете избежать этого, если у вас есть общий ресурс с списком рассылки apache spark или вы создаете Jira с примером кода и данными о проблемах и всеми возможными проблемами теста .apache.org/jira/projects/SPARK/summary
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню