web-dev-qa-db-ja.com

SparkでRDDと制限を並べ替える方法は?

FooクラスのRDDがあります:class Foo( name : String, createDate : Date )Fooが10%古い別のRDDが必要です。私の最初のアイデアは、createDateで並べ替え、0.1 * countで制限することでしたが、制限機能はありません。

アイデアはありますか?

9
etig

Fooが次のようなケースクラスであると仮定します。

import Java.sql.Date
case class Foo(name: String, createDate: Java.sql.Date)
  1. プレーン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
      
  2. DataFrameの使用(注-動作が制限されているため、これは実際には最適なパフォーマンスではありません)。

    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)} 
    
15
zero323