spark(SortBy与SortByKey)

本文详细介绍了Apache Spark中RDD的sortBy与sortByKey函数的使用方法与原理,包括参数解析、函数依赖及其实现机制,并通过Scala与Java示例展示了如何对数据进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sortBy函数

sortBy函数是在org.apache.spark.rdd.RDD类中实现的。
该函数有三个参数:
  第一个参数是一个函数,该函数的也有一个带T泛型的参数,返回类型和RDD中元素的类型是一致的;
  第二个参数是ascending,从字面的意思大家应该可以猜到,这参数决定排序后RDD中的元素是升序还是降序,默认是true,也就是升序;
  第三个参数是numPartitions,该参数决定排序后的RDD的分区个数,默认排序后的分区个数和排序之前的个数相等。
  
sortBy函数的实现可以看出,第一个参数是必须传入的,而后面的两个参数可以不传入。而且sortBy函数函数的实现依赖于sortByKey函数。

案例
scala写

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Top_SortBy {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
      .setMaster("local")
      .setAppName("Top_SortBy")

    val sc = new SparkContext(conf)

    val lines: RDD[String] = sc.textFile("D:\\eclipse\\wc\\scalaworid\\top.txt")

    val ints: Array[Int] = lines.map(Integer.parseInt(_)).sortBy((e:Int) => e,false,1).take(3)

    for (a <- ints){
      println(a)
    }
    //结果:
    //9
    //7
    //6

  }
}

java写

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;


import java.util.List;

public class SortBya {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf()
                .setAppName("SortBy")
                .setMaster("local");

        JavaSparkContext sc = new JavaSparkContext(conf);

        JavaRDD<String> textFile = sc.textFile("D:\\eclipse\\wc\\scalaworid\\top.txt");
        //将一列String类型的数据转换成int
        JavaRDD<Integer> map = textFile.map(new Function<String, Integer>() {
            @Override
            public Integer call(String s) throws Exception {
                return Integer.parseInt(s);
            }
        });
        //用sortBy进行排序三个参数(new Function,升序或降序,分区)
        JavaRDD<Integer> sortBy = map.sortBy(new Function<Integer, Integer>() {
            @Override
            public Integer call(Integer integer) throws Exception {
                return integer;
            }
        }, false, 3);
        //用take算子取前几个
        List<Integer> take = sortBy.take(3);

        for (Integer e : take) {
            System.out.println(e);
        }
        //结果
        //9
        //7
        //6
    }
}

sortByKey函数

sortByKey函数作用于Key-Value形式的RDD,并对Key进行排序。它是在org.apache.spark.rdd.OrderedRDDFunctions中实现的。
和sortBy一样,该函数返回的RDD一定是ShuffledRDD类型的,因为对源RDD进行排序,必须进行Shuffle操作,而Shuffle操作的结果RDD就是ShuffledRDD。里面用到了RangePartitioner,它可以使得相应的范围Key数据分到同一个partition中,然后内部用到了mapPartitions对每个partition中的数据进行排序,而每个partition中数据的排序用到了标准的sort机制,避免了大量数据的shuffle。

案例
scala写

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Top_SortByKeta {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
      .setAppName("Top_SortByKey")
      .setMaster("local")

    val sc = new SparkContext(conf)

    val lines: RDD[String] = sc.textFile("D:\\eclipse\\wc\\scalaworid\\top.txt")

    val strings: Array[String] = lines.map((_,1)).sortByKey(false,1).map(_._1).take(3)

    for (e <- strings){
      println(e)
    }
    //结果:
    // 9
    //7
    //6
  }
}

java写

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2;

import java.util.List;

public class SortByKeya {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf()
                .setMaster("local")
                .setAppName("SortByKey");

        JavaSparkContext sc = new JavaSparkContext(conf);

        JavaRDD<String> textFile = sc.textFile("D:\\eclipse\\wc\\scalaworid\\top.txt");
        //将一列String类型数据转换成Tuple2(Integer,Integer)例如(源数据,1)...
        JavaPairRDD<Integer, Integer> pairRDD = textFile.mapToPair(new PairFunction<String, Integer, Integer>() {
            @Override
            public Tuple2<Integer, Integer> call(String s) throws Exception {
                return new Tuple2<>(Integer.parseInt(s),1);
            }
        });
        //用sortByKey排序,取元组的第一个值
        JavaPairRDD<Integer, Integer> sortByKey = pairRDD.sortByKey(false);

        JavaRDD<Integer> map = sortByKey.map(new Function<Tuple2<Integer, Integer>, Integer>() {
            @Override
            public Integer call(Tuple2<Integer, Integer> tuple2) throws Exception {
                return tuple2._1;
            }
        });
        //用take算子取前三
        List<Integer> take = map.take(3);

        for (Integer a:take) {
            System.out.println(a);
        }
        //结果:
        // 9
        //7
        //6

    }
}
您好!如果您想使用`sortBy`函数按照时间排序,可以按照以下步骤操作: 1. 首先,将数据加载到一个RDD中。 2. 然后,使用`map`函数将时间字符串转换为时间戳,并以元组的形式返回时间戳和原始数据。 3. 最后,使用`sortBy`函数按照时间戳排序,并使用`map`函数将排序后的数据转换回原始数据格式。例如,以下是一份示例代码: ``` val rdd = sc.parallelize(Seq( ("2019-07-17 06:51:44", "data1"), ("2020-08-01 12:30:00", "data2"), ("2021-01-08 18:15:30", "data3") )) val sortedRDD = rdd .map{ case (timeString, data) => (java.sql.Timestamp.valueOf(timeString).getTime, (timeString, data)) } .sortByKey() .map{ case (timestamp, (timeString, data)) => (timeString, data) } sortedRDD.foreach(println) ``` 在上面的代码中,我们首先使用`parallelize`函数将数据加载到一个RDD中。然后,使用`map`函数将时间字符串转换为时间戳,并以元组的形式返回时间戳和原始数据。注意,我们使用`java.sql.Timestamp.valueOf`函数将时间字符串转换为`Timestamp`类型,并使用`getTime`函数获取时间戳。最后,使用`sortByKey`函数按照时间戳排序,并使用`map`函数将排序后的数据转换回原始数据格式。 请注意,上述代码中使用的是Scala API。如果您使用的是Java API,则可以使用`java.time.LocalDateTime.parse`函数将时间字符串转换为`LocalDateTime`类型,并使用`java.time.LocalDateTime.toEpochSecond`函数将其转换为时间戳。另外,如果您的数据量较大,建议使用`sortByKey`函数的变体`sortByKey(numPartitions: Int)`来进行分区排序,以提高性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值