Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.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

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 SparkContext.textFile能否与自定义接收器一起使用?_Scala_Apache Spark_Spark Streaming - Fatal编程技术网

Scala SparkContext.textFile能否与自定义接收器一起使用?

Scala SparkContext.textFile能否与自定义接收器一起使用?,scala,apache-spark,spark-streaming,Scala,Apache Spark,Spark Streaming,我正在尝试实现一个流式作业,该作业使用自定义接收器从SQS读取消息。每个消息都包含一个对S3文件的引用,然后我希望将其读取、解析并存储为ORC 以下是我目前掌握的代码: val sc = new SparkContext(conf) val streamContext = new StreamingContext(sc, Seconds(5)) val sqs = streamContext.receiverStream(new SQSReceiver("events-elb") .cre

我正在尝试实现一个流式作业,该作业使用自定义接收器从SQS读取消息。每个消息都包含一个对S3文件的引用,然后我希望将其读取、解析并存储为ORC

以下是我目前掌握的代码:

val sc = new SparkContext(conf)
val streamContext = new StreamingContext(sc, Seconds(5))

val sqs = streamContext.receiverStream(new SQSReceiver("events-elb")
  .credentials("accessKey", "secretKey")
  .at(Regions.US_EAST_1)
  .withTimeout(5))

val s3File = sqs.map(messages => {
  val sqsMsg: JsValue = Json.parse(messages)
  val s3Key = "s3://" +
    Json.stringify(sqsMsg("Records")(0)("s3")("bucket")("name")).replace("\"", "") + "/" +
    Json.stringify(sqsMsg("Records")(0)("s3")("object")("key")).replace("\"", "")
  val rawLogs = sc.textFile(s3Key)

  rawLogs
}).saveAsTextFiles("/tmp/output")
不幸的是,此操作失败,出现以下错误:

Caused by: java.io.NotSerializableException: org.apache.spark.SparkContext
Serialization stack:
    - object not serializable (class: org.apache.spark.SparkContext, value: org.apache.spark.SparkContext@52fc5eb1)
    - field (class: SparrowOrc$$anonfun$1, name: sc$1, type: class org.apache.spark.SparkContext)
    - object (class SparrowOrc$$anonfun$1, <function1>)
at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)
at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:46)
at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:100)
at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:295)
原因:java.io.notserializableeexception:org.apache.spark.SparkContext
序列化堆栈:
-对象不可序列化(类:org.apache.spark.SparkContext,值:org.apache.spark)。SparkContext@52fc5eb1)
-字段(类:SparrowOrc$$anonfun$1,名称:sc$1,类型:class org.apache.spark.SparkContext)
-对象(类SparrowOrc$$anonfun$1,)
位于org.apache.spark.serializer.SerializationDebugger$.ImproveeException(SerializationDebugger.scala:40)
位于org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:46)
位于org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:100)
位于org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:295)
这是一种不正确的
sc.textFile
使用方法吗?如果是这样,我可以使用什么方法将从SQS接收到的每个文件路径转发到文件读取器进行处理

FWIW,
val s3File
的类型为
mappedDStream


为了进一步说明,我将它用作我的接收器:。

否。这不正确,因为SparkContext是:

  • 不可序列化(如日志中所示)
  • 这毫无意义
  • 我非常感谢Spark开发人员,他们处理了它,所以我们不会忘记它

    不允许这种使用的原因是
    SparkContext
    存在于驱动程序中(或者可以说构成驱动程序),并负责编排任务(用于Spark作业)

    执行者很笨,因此只知道如何运行任务

    Spark不是这样工作的,您越早接受该设计决策,就越能熟练地正确开发Spark应用程序

    如果是这样,我可以使用什么方法将从SQS接收到的每个文件路径转发到文件读取器进行处理


    这是我无法回答的,因为我从未开发过自定义接收器。

    事实上,我们不能在
    映射
    操作中使用
    sparkContext
    ,因为在一个阶段中转换的闭包是在执行器中运行的,在执行器中没有定义
    sparkContext

    方法是将过程分为两部分:首先,我们使用现有的
    映射
    计算文件,但在
    转换
    操作中使用
    文本文件

    val s3Keys = sqs.map(messages => {
      val sqsMsg: JsValue = Json.parse(messages)
      val s3Key = "s3://" +
      Json.stringify(sqsMsg("Records")(0)("s3")("bucket")("name")).replace("\"", "") + "/" +
      Json.stringify(sqsMsg("Records")(0)("s3")("object")("key")).replace("\"", "")
    }
    val files DStream = s3Keys.transform{keys => 
        val fileKeys= keys.collect()
        Val files = fileKeys.map(f=>
          sparkContext.textFile(f))
        sparkContext.union(files)
    }
    filesDStream.saveAsTextFiles(..)