【问题标题】:Spark job not parallelising locally (using Parquet + Avro from local filesystem)Spark 作业未在本地并行化(使用本地文件系统中的 Parquet + Avro)
【发布时间】:2014-02-25 22:39:59
【问题描述】:

编辑 2

通过将RDD重新分区为8个分区间接解决了这个问题。遇到 avro 对象不是“java 可序列化”的障碍时发现了一个 sn-p here to delegate avro serialisation to kryo. 原来的问题仍然存在。

编辑 1: 删除地图函数中的局部变量引用

我正在编写一个驱动程序,以使用 parquet 和 avro 为 io/schema 在 spark 上运行计算繁重的工作。我似乎无法使用我所有的核心来获得火花。我究竟做错了什么 ?是因为我将键设置为 null 吗?

我只是想了解 hadoop 如何组织文件。 AFAIK,因为我的文件有千兆字节的原始数据,我应该期望看到与默认块和页面大小并行的东西。

ETL 我的输入进行处理的函数如下所示:

def genForum {
    class MyWriter extends AvroParquetWriter[Topic](new Path("posts.parq"), Topic.getClassSchema) {
      override def write(t: Topic) {
        synchronized {
          super.write(t)
        }
      }
    }

    def makeTopic(x: ForumTopic): Topic = {
      // Ommited to save space
    }

    val writer = new MyWriter

    val q =
      DBCrawler.db.withSession {
        Query(ForumTopics).filter(x => x.crawlState === TopicCrawlState.Done).list()
      }

    val sz = q.size
    val c = new AtomicInteger(0)

    q.par.foreach {
      x =>
        writer.write(makeTopic(x))
        val count = c.incrementAndGet()
        print(f"\r${count.toFloat * 100 / sz}%4.2f%%")
    }
    writer.close()
  }

我的转换如下:

def sparkNLPTransformation() {
    val sc = new SparkContext("local[8]", "forumAddNlp")

    // io configuration
    val job = new Job()
    ParquetInputFormat.setReadSupportClass(job, classOf[AvroReadSupport[Topic]])
    ParquetOutputFormat.setWriteSupportClass(job,classOf[AvroWriteSupport])
    AvroParquetOutputFormat.setSchema(job, Topic.getClassSchema)


    // configure annotator
    val props = new Properties()
    props.put("annotators", "tokenize,ssplit,pos,lemma,parse")
    val an = DAnnotator(props)


    // annotator function
    def annotatePosts(ann : DAnnotator, top : Topic) : Topic = {
      val new_p = top.getPosts.map{ x=>
        val at = new Annotation(x.getPostText.toString)
        ann.annotator.annotate(at)
        val t = at.get(classOf[SentencesAnnotation]).map(_.get(classOf[TreeAnnotation])).toList

        val r = SpecificData.get().deepCopy[Post](x.getSchema,x)
        if(t.nonEmpty) r.setTrees(t)
        r
      }
      val new_t = SpecificData.get().deepCopy[Topic](top.getSchema,top)
      new_t.setPosts(new_p)
      new_t
    }

    // transformation
    val ds = sc.newAPIHadoopFile("forum_dataset.parq", classOf[ParquetInputFormat[Topic]], classOf[Void], classOf[Topic], job.getConfiguration)
    val new_ds = ds.map(x=> ( null, annotatePosts(x._2) ) )

    new_ds.saveAsNewAPIHadoopFile("annotated_posts.parq",
      classOf[Void],
      classOf[Topic],
      classOf[ParquetOutputFormat[Topic]],
      job.getConfiguration
    )
  }

【问题讨论】:

  • 我已经得出结论,目前无法使用 Spark 拆分 parquet 文件,并且必须使用 Hadoop 作业通过设置 reducer 的数量来拆分文件(这可能很快,但很可怕黑客)。我问了一个类似的问题stackoverflow.com/questions/27194333/…

标签: scala hadoop parallel-processing bigdata apache-spark


【解决方案1】:

您能否确认数据确实在 HDFS 中的多个块中? forum_dataset.parq 文件上的总块数

【讨论】:

  • 感谢您的回复
  • 我也开始玩弄分区,从控制台喷出我看到这似乎正在展开工作(尽管我认为我需要为我的 avro 对象编写 kryo 的自定义序列化代码,因为什么都没有发生)。我的代码在这里gist.github.com/hsyed/8771986
  • 从控制台输出我猜是4。14/02/02 17:47:41 INFO rdd.NewHadoopRDD: Input split: ParquetInputSplit{part: file:///Users/hassan/code/scala/avro/forum_dataset.parq start: 0 length: 1023817737 hosts: [localhost] blocks: 4 requestedSchema: same as file fileSchema: message forumavroschema.Topic
猜你喜欢
  • 2015-03-03
  • 2018-02-07
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
  • 2015-12-19
  • 2016-09-02
  • 2019-01-15
  • 2015-09-23
相关资源
最近更新 更多