【spark】示例:求Top值

我们有这样的两个文件

第一个数字为行号,后边为三列数据。我们来求第二列数据的Top(N)

(1)我们先读取数据,创建Rdd

(2)过滤数据,取第二列数据。

我们用filter()来过滤数据

line.trim().length是除去行末尾的空格然后计算长度,长度大于0,并且分能用逗号切分为4个子数据的数据为有效数据。

然后我们来切分取出第二列数据,即arr(2),arr(0)为行号

line.map(_.split(",")(2))

(3)数据类型转换并修改成键值对的形式

我们通过.map(x=>(x.toInt,""))把原来数据(string)修改成为(int,String)类型的键值对

为什么要这么做呢?因为我们要采用orderByKey()方法进行排序。

(4)排序取出键值对中的键

我们先调用orderByKey(false)方法对rdd中的每个键值对按照键值进行排序,false参数:是否正序

然后我们通过 x=>x._1 取排序后的键值对的键,最后通过take(N)方法即可实现取TOP(N)的功能

(5)将结果存入文件

  通过saveAsTextFile(“file://”)方法将结果存入文件

完整代码 

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

object TopN {
    //建立SparkContext
    val sparkConf = new SparkConf().setAppName("TopN")
    val sc = new SparkContext(sparkConf)
    //设置日志等级,只显示报错
    sc.setLogLevel("ERROR")
    //读取数据,分区
    val lines = sc.textFile("hdfs://localhost:9000/user/local/spark/data",2)
    var num = 0//排名初始化
    var result = lines.filter(line => (line.trim.length > 0 && line.split(",").length > 4))//过滤数据
                      .map(_.split(",")(2)) //拆分文件取第二列数
                      .map(x =>(x.toInt,"")) //修改数据类型并转化为键值对的形式
                      .sortByKey(false)//排序
                      .map(x => x._1)//取键
                      .take(5)//取前五条数据
                      .foreach( x =>{ //显示数据
                            num = num + 1 //排名
                            println(num+"	"+x) //显示
    })
}

注意,我们在使用sortByKey方法前,数据是分了区的

我们使用了sortByKey方法将分区了的数据进行排序可能会出错,具体原因不是很清楚。

所以有时候我们需要在sortByKey()方法前加一个.partitionBy(new HashPartitioner(1))从新分成一个区来保证正确率。

原文地址:https://www.cnblogs.com/zzhangyuhang/p/9035042.html