Scala 从主RDD创建RDD

Scala 从主RDD创建RDD,scala,apache-spark,amazon-s3,rdd,Scala,Apache Spark,Amazon S3,Rdd,我有一个RDD(RDD[(String,Iterable[Event]),它有一个键,表示一年中的一个月,值是该月发生的数百万个事件 我想循环遍历每个键,并创建该键事件的RDD。 然后,我想为当月的每一天创建一个事件RDD,以便将它们发送到相关的s3位置(“目录”结构为bucketName/year/month/day) 问题是,似乎无法在另一个RDD的foreach中创建RDD。 因此,我不确定如何在不将整个主RDD加载到内存中的情况下实现我想要的目标(这肯定会耗尽驱动程序的内存,并挫败使用S

我有一个RDD(RDD[(String,Iterable[Event]),它有一个键,表示一年中的一个月,值是该月发生的数百万个事件

我想循环遍历每个键,并创建该键事件的RDD。 然后,我想为当月的每一天创建一个事件RDD,以便将它们发送到相关的s3位置(“目录”结构为bucketName/year/month/day)

问题是,似乎无法在另一个RDD的foreach中创建RDD。 因此,我不确定如何在不将整个主RDD加载到内存中的情况下实现我想要的目标(这肯定会耗尽驱动程序的内存,并挫败使用Spark的初衷)

也许有一种方法可以用Spark实现我想要的,我只是不太懂,希望这里的人能帮我

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

 private def store(
    eventsByMonth: RDD[(String, Iterable[Event])]
  )(
    implicit sqlContext: SQLContext
  ): Try[Unit] =
    Try(
      eventsByMonth
        .foreach {
          case (_, events: Iterable[Event]) =>
            writeToS3Files(sqlContext.sparkContext.parallelize(events.toSeq))
        }
    )

  private def writeToS3Files(events: RDD[Event])(
    implicit sqlContext: SQLContext
  ): Try[Unit] =
    Try(
      // outputFilePath will contain the day that these events are related to.
      events.groupBy(_.outputFilePath).foreach {
        case (filePath: String, eventsForFile: Iterable[Event]) =>
          writeToS3File(filePath, sqlContext.sparkContext.parallelize(eventsForFile.toSeq))
      }
    )

  private def writeToS3File(filePath: String, events: RDD[Event]): Try[Unit] = {
    val fileNameWithPath = s"${filePath}${UUID.randomUUID().toString}.gz"

    Try(events.saveAsTextFile(fileNameWithPath, classOf[GzipCodec]))
  }

我假设有某种方法可以确定事件发生的月份(例如,day(Int类型)是事件的属性)

您可以将RDD[(String,Iterable[Event]]转换为PairRDD[(K,V)],其中键(K)是事件发生的月份和月份的哪一天,值(V)是该月哪一天发生的所有事件。之后,您可以轻松地将数据转储到数据库中


写函数必须在
RDD[Event]
上操作,而不是在
Iterable[Event]
上操作,这是一个硬约束吗?因为我会尝试使用
RDD[(S3Path,Iterable[Event])]
然后使用
RDD.foreach(function.tupled(writeToS3File))
。如果您可以管理按月份分组的RDD,那么按天分组的RDD肯定也可以。
val eventsByMonthAndDate = eventsByMonth.flatMap { case (month, events) => events.map(e => ((month, e.day), e)) }
eventsByMonthAndDate.groupby(_._1).foreach(writeToDB)