Scala 如何在Spark中对RDD进行排序和限制?

Scala 如何在Spark中对RDD进行排序和限制?,scala,apache-spark,rdd,Scala,Apache Spark,Rdd,我有Foo类的RDD:类Foo(名称:String,createDate:Date)。 我想要另一个RDD,它的旧版本为10%Foo。 我的第一个想法是按createDate排序,并按0.1*计数进行限制,但没有限制函数 你有什么想法吗?假设Foo是这样一个案例类: import java.sql.Date case class Foo(name: String, createDate: java.sql.Date) 使用普通RDD: import org.apache.spark.rdd.R

我有Foo类的RDD:
类Foo(名称:String,createDate:Date)
。 我想要另一个RDD,它的旧版本为10%
Foo
。 我的第一个想法是按
createDate
排序,并按0.1*计数进行限制,但没有限制函数


你有什么想法吗?

假设
Foo
是这样一个案例类:

import java.sql.Date
case class Foo(name: String, createDate: java.sql.Date)
  • 使用普通RDD:

    import org.apache.spark.rdd.RDD
    import scala.math.Ordering
    
    val rdd: RDD[Foo] = sc
      .parallelize(Seq(
        ("a", "2015-01-03"), ("b", "2014-11-04"), ("a", "2016-08-10"),
        ("a", "2013-11-11"), ("a", "2015-06-19"), ("a", "2009-11-23")))
      .toDF("name", "createDate")
      .withColumn("createDate", $"createDate".cast("date"))
      .as[Foo].rdd
    
    rdd.cache()
    val  n = scala.math.ceil(0.1 * rdd.count).toInt
    
    • 数据放入驱动程序内存:

      • 你们想要的分数相对较小

        rdd.takeOrdered(n)(Ordering.by[Foo, Long](_.createDate.getTime))
        // Array[Foo] = Array(Foo(a,2009-11-23))
        
      • 您想要的分数相对较大:

        rdd.sortBy(_.createDate.getTime).take(n)
        
    • 否则

      rdd
        .sortBy(_.createDate.getTime)
        .zipWithIndex
        .filter{case (_, idx) => idx < n}
        .keys
      

    • 您好,zero323,您能很快告诉我们为什么数据帧的性能在极限操作上是次优的吗?与RDD上的top相比,在实现方面有什么不同@zero333@XinweiLiu我已经回答了你的问题。我希望它能解释发生了什么。很好的回答@zero323。但我仍然有刘新伟同样的问题。为什么df.limit()慢?@zero323请提供更多关于df.limit(n)慢的细节。谢谢。我认为在这种情况下使用
      .zipWithIndex
      是不安全的。也许
      zipWithUniqueId
      更安全?哦,为什么
      limit
      很慢?
      import org.apache.spark.sql.Row
      
      val topN = rdd.toDF.orderBy($"createDate").limit(n)
      topN.show
      
      // +----+----------+
      // |name|createDate|
      // +----+----------+
      // |   a|2009-11-23|
      // +----+----------+
      
      
      // Optionally recreate RDD[Foo]
      topN.map{case Row(name: String, date: Date) => Foo(name, date)}