如果有商品品类的数据pairRDD(categoryId,clickCount_orderCount_payCount),用Spark完成Top5,你会怎么做?

这里假设使用Java语言进行编写,那么你有两种思路:

1.简化成RDD(categoryObject),其中categoryObject实现了java.lang.Comparable.然后使用top(5)获得topN

2.转换成PairRDD(categoryKey,info),其中categoryKey实现了scala.math.Ordered。然后进行sortByKey之后再take(5).

注意:

1)top(n)函数在Java的Spark API中内部调用的比较器是java.lang.Comparable进行比较.

2)而sortByKey函数在Java的Spark API中依然调用scala.math.Ordered进行比较.

相比之下,思路2的空间和时间都不如思路1,但是如果我们需要sort结果的过程中顺便获得topN,则使用思路2更好一些。

思路1实现:

CategoryObject:

package com.stan.core.spark.userAction;

import java.io.Serializable;

public class ComparableCategoryObject
implements Comparable<ComparableCategoryObject>, Serializable {
String categoryId;
Long clickCategoryCount;
Long orderCategoryCount;
Long defrayCategoryCount; @Override
public int compareTo(ComparableCategoryObject o) {
long compareNum =
(this.defrayCategoryCount - o.defrayCategoryCount) * 10000
+
(this.orderCategoryCount - o.orderCategoryCount) * 100
+
(this.clickCategoryCount - o.clickCategoryCount) * 1;
return (int)(compareNum%1000);
} @Override
public String toString() {
return "ComparableCategoryObject{" +
"categoryId='" + categoryId + '\'' +
", clickCategoryCount=" + clickCategoryCount +
", orderCategoryCount=" + orderCategoryCount +
", defrayCategoryCount=" + defrayCategoryCount +
'}';
} public String getCategoryId() {
return categoryId;
} public void setCategoryId(String categoryId) {
this.categoryId = categoryId;
} public Long getClickCategoryCount() {
return clickCategoryCount;
} public void setClickCategoryCount(Long clickCategoryCount) {
this.clickCategoryCount = clickCategoryCount;
} public Long getOrderCategoryCount() {
return orderCategoryCount;
} public void setOrderCategoryCount(Long orderCategoryCount) {
this.orderCategoryCount = orderCategoryCount;
} public Long getDefrayCategoryCount() {
return defrayCategoryCount;
} public void setDefrayCategoryCount(Long defrayCategoryCount) {
this.defrayCategoryCount = defrayCategoryCount;
}
}

具体调用方法:

        // 1.封装
JavaRDD<ComparableCategoryObject> comparableCategoryObjectJavaRDD =
categoryId2allCount.map(
new Function<Tuple2<String, String>, ComparableCategoryObject>() {
@Override
public ComparableCategoryObject call(Tuple2<String, String> stringStringTuple2) throws Exception {
String categoryId = stringStringTuple2._1;
String allCount = stringStringTuple2._2;
String[] tmpAllCountSplited = allCount.split("_");
Long clickCount = Long.valueOf(tmpAllCountSplited[0]);
Long orderCount = Long.valueOf(tmpAllCountSplited[1]);
Long defrayCount = Long.valueOf(tmpAllCountSplited[2]);
ComparableCategoryObject comparableCategoryObject =
new ComparableCategoryObject();
comparableCategoryObject.setCategoryId(categoryId);
comparableCategoryObject.setClickCategoryCount(clickCount);
comparableCategoryObject.setOrderCategoryCount(orderCount);
comparableCategoryObject.setDefrayCategoryCount(defrayCount);
return comparableCategoryObject;
}
}
);
// 2.top(5)
List<ComparableCategoryObject> top10Categorys = comparableCategoryObjectJavaRDD.top(5);

思路2实现:

CategoryKey:

package com.stan.core.spark.userAction;

import scala.Serializable;
import scala.math.Ordered; /**
* 用于按照
* (clickCategoryCount,orderCategoryCount,defrayCategoryCount)的优先级排序
*/
public class ComparableCategoryKey
// scala中可比较,以便于进行RDD排序
implements Ordered<ComparableCategoryKey>, Serializable {
String categoryId;
Long clickCategoryCount;
Long orderCategoryCount;
Long defrayCategoryCount; /**
* 计算比较数
*
* 因为优先级为 : 先比较支付量,若支付量相同,则比较下单量,若下单量相同,则继续比较点击量
* 所以我在进行比较的时候直接使用 比较值 = 支付量差 * 10000 + 下单量差 * 100 + 点击量差
* 若比较值小于 0 ,则小于,若比较值大于0 , 则大于,若比较值等于0,则等于
* @param comparableCategoryWithAllCount
* @return
*/
public long computeCompareNum(ComparableCategoryKey comparableCategoryWithAllCount){
long compareNum =
(this.defrayCategoryCount - comparableCategoryWithAllCount.defrayCategoryCount) * 10000
+
(this.orderCategoryCount - comparableCategoryWithAllCount.orderCategoryCount) * 100
+
(this.clickCategoryCount - comparableCategoryWithAllCount.clickCategoryCount) * 1;
return compareNum;
} @Override
public int compare(ComparableCategoryKey comparableCategoryWithAllCount) {
return (int)(computeCompareNum(comparableCategoryWithAllCount)%1000);
} @Override
public boolean $less(ComparableCategoryKey comparableCategoryWithAllCount) {
return computeCompareNum(comparableCategoryWithAllCount) < 0;
} @Override
public boolean $greater(ComparableCategoryKey comparableCategoryWithAllCount) {
return computeCompareNum(comparableCategoryWithAllCount) > 0;
} @Override
public boolean $less$eq(ComparableCategoryKey comparableCategoryWithAllCount) {
return computeCompareNum(comparableCategoryWithAllCount) <= 0;
} @Override
public boolean $greater$eq(ComparableCategoryKey comparableCategoryWithAllCount) {
return computeCompareNum(comparableCategoryWithAllCount) >= 0;
} @Override
public int compareTo(ComparableCategoryKey comparableCategoryWithAllCount) {
return (int)(computeCompareNum(comparableCategoryWithAllCount)%1000);
} public String getCategoryId() {
return categoryId;
} public void setCategoryId(String categoryId) {
this.categoryId = categoryId;
} public Long getClickCategoryCount() {
return clickCategoryCount;
} public void setClickCategoryCount(Long clickCategoryCount) {
this.clickCategoryCount = clickCategoryCount;
} public Long getOrderCategoryCount() {
return orderCategoryCount;
} public void setOrderCategoryCount(Long orderCategoryCount) {
this.orderCategoryCount = orderCategoryCount;
} public Long getDefrayCategoryCount() {
return defrayCategoryCount;
} public void setDefrayCategoryCount(Long defrayCategoryCount) {
this.defrayCategoryCount = defrayCategoryCount;
} @Override
public String toString() {
return "ComparableCategoryKey{" +
"categoryId='" + categoryId + '\'' +
", clickCategoryCount=" + clickCategoryCount +
", orderCategoryCount=" + orderCategoryCount +
", defrayCategoryCount=" + defrayCategoryCount +
'}';
}
}

具体的调用过程:

// 1.封装成(categoryKey,info)
JavaPairRDD<ComparableCategoryKey,String> comparableCategory2AllCountRDD =
categoryId2allCount.mapToPair(
new PairFunction<Tuple2<String, String>, ComparableCategoryKey,String>() {
@Override
public Tuple2<ComparableCategoryKey,String> call(Tuple2<String, String> stringStringTuple2) throws Exception {
String categoryId = stringStringTuple2._1;
String allCount = stringStringTuple2._2;
String[] tmpAllCountSplited = allCount.split("_");
Long clickCount = Long.valueOf(tmpAllCountSplited[0]);
Long orderCount = Long.valueOf(tmpAllCountSplited[1]);
Long defrayCount = Long.valueOf(tmpAllCountSplited[2]);
ComparableCategoryKey comparableCategoryWithAllCount =
new ComparableCategoryKey();
comparableCategoryWithAllCount.setCategoryId(categoryId);
comparableCategoryWithAllCount.setClickCategoryCount(clickCount);
comparableCategoryWithAllCount.setOrderCategoryCount(orderCount);
comparableCategoryWithAllCount.setDefrayCategoryCount(defrayCount);
return new Tuple2<>(comparableCategoryWithAllCount,allCount);
}
}
);
// 2.sortByKey 排序
comparableCategory2AllCountRDD.sortByKey(); // 3.获取前五
List<Tuple2<ComparableCategoryKey,String>> top10Categorys = comparableCategory2AllCountRDD.take(5);

用Spark完成复杂TopN计算的两种逻辑的更多相关文章

  1. Spark Streaming中空batches处理的两种方法(转)

    原文链接:Spark Streaming中空batches处理的两种方法 Spark Streaming是近实时(near real time)的小批处理系统.对给定的时间间隔(interval),S ...

  2. 【Spark篇】---SparkStreaming+Kafka的两种模式receiver模式和Direct模式

    一.前述 SparkStreamin是流式问题的解决的代表,一般结合kafka使用,所以本文着重讲解sparkStreaming+kafka两种模式. 二.具体 1.Receiver模式    原理图 ...

  3. spark streaming 接收kafka消息之一 -- 两种接收方式

    源码分析的spark版本是1.6. 首先,先看一下 org.apache.spark.streaming.dstream.InputDStream 的 类说明: This is the abstrac ...

  4. 第一章:1-20、试计算以下两种情况的发送时延和传播时延: (1) 数据长度为107bit,数据发送速率为100kbit/s,传播距离为1000km,信号在媒体上 的传播速率为2×108m/s。 (2) 数据长度为103bit,数据发送速率为1Gbit/s,传输距离和信号在媒体上的传播速率同 上。

    <计算机网络>谢希仁著第四版课后习题答案答: 1):发送延迟=107/(100×1000)=100s         传播延迟=1000×1000/(2×108)=5×10-3s=5ms ...

  5. spark提交任务的两种的方法

    在学习Spark过程中,资料中介绍的提交Spark Job的方式主要有两种(我所知道的): 第一种: 通过命令行的方式提交Job,使用spark 自带的spark-submit工具提交,官网和大多数参 ...

  6. sparkStreaming读取kafka的两种方式

    概述 Spark Streaming 支持多种实时输入源数据的读取,其中包括Kafka.flume.socket流等等.除了Kafka以外的实时输入源,由于我们的业务场景没有涉及,在此将不会讨论.本篇 ...

  7. 编译spark源码 Maven 、SBT 2种方式编译

    由于实际环境较为复杂,从Spark官方下载二进制安装包可能不具有相关功能或不支持指定的软件版本,这就需要我们根据实际情况编译Spark源代码,生成所需要的部署包. Spark可以通过Maven和SBT ...

  8. Spark源码剖析 - 计算引擎

    本章导读 RDD作为Spark对各种数据计算模型的统一抽象,被用于迭代计算过程以及任务输出结果的缓存读写.在所有MapReduce框架中,shuffle是连接map任务和reduce任务的桥梁.map ...

  9. spark 例子groupByKey分组计算

    spark 例子groupByKey分组计算 例子描述: [分组.计算] 主要为两部分,将同类的数据分组归纳到一起,并将分组后的数据进行简单数学计算. 难点在于怎么去理解groupBy和groupBy ...

随机推荐

  1. 关于最小生成树(并查集)prime和kruskal

    适合对并查集有一定理解的人.  新手可能看不懂吧.... 并查集简单点说就是将相关的2个数字联系起来 比如 房子                      1   2    3   4  5   6 ...

  2. python-爬虫(3)---lxml匹配css

    百度首页  部分代码 <div class="s_tab_inner"> <b>网页</b> <a href="//www.ba ...

  3. webpack入门文档教程

    .octicon{margin-right:2px}a.tabnav-extra:hover{color:#4078c0;text-decoration:none}.tabnav-btn{margin ...

  4. java 访问数据库

    Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver”);//依据不同数据库,加载不同驱动 String url = “jdbc:sq ...

  5. Kettle使用MySQL作为资源库报错解决方法

    使用Kettle5.0.1,安装的是MySQL5.1.JDK1.6,在\data-integration\lib目录里添加mysql的JDBC包mysql-connector-java-5.0.8-b ...

  6. WPF Combobox数据绑定 Binding

    combobox数据绑定List链表集合区分显示值与选择的值 整体效果: 根据combobox选择情况分别打印选取值与显示值 代码: Windows窗体: <Window x:Class=&qu ...

  7. 2018-2019-20175205 实验三敏捷开发与XP实践《Java开发环境的熟悉》实验报告

    2018-2019-20175205 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>&l ...

  8. 深入浅出Java探针技术2---java字节码生成框架ASM、Javassist和byte buddy的使用

    目前Java字节码生成框架大致有ASM.Javassist和byte buddy三种 ASM框架介绍及使用 1.ASM介绍 ASM是一种Java字节码操控框架,能够以二进制形式修改已有的类或是生成类, ...

  9. Load data local infile 实验报告

    1.实验内容: 利用SQL语句“load data local infile”将“pet.txt”文本文件中的数据导入到mysql中 (pet表在数据库menagerie中) 2.实验过程及结果: ( ...

  10. 类与对象 && 继承

      以下是本人的对类与对象.继承的一些理解,如有错误之处万望谅解,如有朋友愿意指正,十分乐意,万分感谢!   类与对象     类与对象是学习编程的基础(大概吧),那么何为类?何为对象呢?   一.简 ...