美文网首页
大数据(spark+hadoop)之topN

大数据(spark+hadoop)之topN

作者: 机器不能学习 | 来源:发表于2018-11-21 18:58 被阅读0次

    我们平时很容易遇到说排序,并取前N个的状况。
    我们根据数据类型可以简单分为重复键和不重复键的topN

    MapReduce

    对于MR来说,topN代码比较多一些,在这里我只讲讲思路。
    当无重复键的时候,
    我们有数据("w"->2,"ww"->3,"r"->3)
    我们的目的是对值进行排序,如用户点击了几次网页,值记录的就是网页。
    map阶段,我们要做的是获取并且处理数据,并完成本地的topN排序。
    在排序时我们用的是java自带的treeMap(它是一个基于红黑树的实现)。
    为什么要在map阶段就进行排序呢?
    因为在数据量巨大的时候,为了减少RPC和reduce的压力。于是我们在map排好序并筛选出前N个。
    reduce阶段,我们只需要把map传来的topN再进行一次排序筛选出前N个。
    这样我们的目的就达成了。

    对于非唯一键,MR显得笨拙一些,它必须先经过一次reduce,把非唯一键变成唯一键后再重复上述操作。

    spark

    spark具有高层抽象函数。所以排序显得十分简单。在这里主要看看这几个函数。

    • sortby
      def sortBy[S](f: JFunction[T, S], ascending: Boolean, numPartitions: Int): JavaRDD[T]
      sortby函数可以完成对指定数据的排序,(k,v)既可以指定k也可以指定v,第二个参数是选择正序还是逆序(默认是true正序,一般要topN的话用逆序),因为这是一个shuffle操作所以可要指定分区。

    • sortbykey
      比sortby少一个第一个参数,它是仅对key的排序。

    • sortwith
      def sortWith(lt: (A, A) => Boolean): Repr = sorted(Ordering fromLessThan lt)
      一种自定义排序的方法

    • takeOrder

    • take
      def take(num: Int): Array[T]
      抽取rdd的前n个元素

    • top
      def top(num: Int)(implicit ord: Ordering[T]): Array[T]
      默认使用降序,并抽取前n个元素

    • tabkeOrdered
      def takeOrdered(num: Int)(implicit ord: Ordering[T]): Array[T]
      默认使用升序,并抽取前n个元素

     val arr=Map(1->2,2->3,3->1,4->4,4->5,10->23,12->21,10->2,9->1,0->2,9->3)
        val conf=new SparkConf().setAppName("test")
        val sc=new SparkContext(conf)
        val rdd=sc.parallelize(arr.toList,4)
        println(rdd.partitions.size+"======================================")
        val rerdd=rdd.coalesce(3)
        println((rerdd.partitions.size+"======================================"))
        val pairs=rerdd.map(x=>new Tuple2(x._1,x._2))
        val result=pairs.reduceByKey(_+_)
    
        println(result.partitions.size+"======================================")
        val partitions=result.sortBy(x=>x._2,false)
        val res=partitions.take(3)
        res.foreach(x=>println(x))
    

    代码的简单实现。

    思考:如果大量数据中进行topN有什么优化呢?
    个人认为剪枝是必要的,假如对于1-100分布的数服从正态分布,我们自然就可以过滤掉百分之50-70的数。
    如果在已知平均值等情况下,更方便进行剪枝。

    相关文章

      网友评论

          本文标题:大数据(spark+hadoop)之topN

          本文链接:https://www.haomeiwen.com/subject/dlthqqtx.html