本文为《Spark大型电商项目实战》 系列文章之一,主要介绍需求回顾和思路分析,然后将之前的代码重构,最后进行获取top10活跃session的方法。
需求回顾:top10活跃session
之前已经提取到top10热门品类,这次主要是获取每个品类点击次数最多的10个session,以及其对应的访问明细。
实现思路分析
- 拿到符合筛选条件的session的明细
- 按照session粒度进行聚合,获取到session对每个品类的点击次数,用flatMap,算子函数返回的是
<categoryid,(sessionid,clickCount)>
; - 按照品类id,分组取top10,获取到top10活跃session;groupByKey;自己写算法,获取到点击次数最多的前10个session,直接写入MySQL表;返回的是sessionid ;
- 获取各品类top10活跃session的访问明细数据,写入MySQL;
- 本地测试。
本文内容
- 重构一下之前的代码,将通过筛选条件的session的访问明细数据RDD,提取成公共的RDD;这样就不用重复计算同样的RDD;
- 将之前计算出来的top10热门品类的id,生成一个PairRDD,方便后面进行join。
进行重构
将方法
//获取符合条件的session的访问明细
JavaPairRDD<String, Row> sessionid2detailRDD = filteredSessionid2AggrInfoRDD
.join(sessionid2actionRDD)
.mapToPair(new PairFunction<Tuple2<String, Tuple2<String, Row>>, String, Row>() {
private static final long serialVersionUID = 1L;
public Tuple2<String, Row> call(
Tuple2<String, Tuple2<String, Row>> tuple) throws Exception {
return new Tuple2<String, Row>(tuple._1, tuple._2._2);
}
});
单独提出来做成公共的RDD,放在过滤之后,即放在“计算访问步长范围”之后,重新创建一个方法
/**
* 获取通过筛选条件的session的访问明细数据RDD
* @param sessionid2aggrInfoRDD
* @param sessionid2actionRDD
* @return
*/
private static JavaPairRDD<String, Row> getSessionid2detailRDD(
JavaPairRDD<String, String> sessionid2aggrInfoRDD,
JavaPairRDD<String, Row> sessionid2actionRDD) {
JavaPairRDD<String, Row> sessionid2detailRDD = sessionid2aggrInfoRDD
.join(sessionid2actionRDD)
.mapToPair(new PairFunction<Tuple2<String, Tuple2<String, Row>>, String, Row>() {
private static final long serialVersionUID = 1L;
public Tuple2<String, Row> call(
Tuple2<String, Tuple2<String, Row>> tuple) throws Exception {
return new Tuple2<String, Row>(tuple._1, tuple._2._2);
}
});
return sessionid2detailRDD;
}
在public static void main(String[] args)
方法中添加
//生成公共RDD:通过筛选条件的session的访问明细数据
JavaPairRDD<String, Row> sessionid2detailRDD = getSessionid2detailRDD(
filteredSessionid2AggrInfoRDD, sessionid2actionRDD);
将getTop10Category(task.getTaskid(), filteredSessionid2AggrInfoRDD, sessionid2actionRDD);
改为getTop10Category(task.getTaskid(), sessionid2detailRDD);
并将getTop10Category
方法中的参数改为
private static void getTop10Category(
long taskid,
JavaPairRDD<String, Row> sessionid2detailRDD)
将
private static void getTop10Category(
long taskid,
JavaPairRDD<String, Row> sessionid2detailRDD)
改为:
private static List<Tuple2<CategorySortKey, String>> getTop10Category(
long taskid,
JavaPairRDD<String, Row> sessionid2detailRDD)
并添加返回return top10CategoryList;
将
//获取top10热门品类
getTop10Category(task.getTaskid(), sessionid2detailRDD);
改为:
//获取top10热门品类
List<Tuple2<CategorySortKey, String>> top10CategoryList =
getTop10Category(task.getTaskid(), sessionid2detailRDD);
将com.erik.sparkproject.spark
包改为com.erik.sparkproject.spark.session
。
获取top10活跃session
在main方法中添加
//获取top10活跃session
getTop10Session(sc, task.getTaskid(), top10CategoryList, sessionid2detailRDD);
并构建getTop10Session
函数
/**
* 获取top10活跃session
* @param taskid
* @param sessionid2detailRDD
*/
private static void getTop10Session(
JavaSparkContext sc,
final long taskid,
List<Tuple2<CategorySortKey, String>> top10CategoryList,
JavaPairRDD<String, Row> sessionid2detailRDD) {
/**
* 第一步:将top10热门品类的id生成一份RDD
*/
//处理List
List<Tuple2<Long, Long>> top10CategoryIdList =
new ArrayList<Tuple2<Long, Long>>();
for (Tuple2<CategorySortKey, String> category : top10CategoryList) {
long categoryid = Long.valueOf(StringUtils.getFieldFromConcatString(
category._2, "\\|", Constants.FIELD_CATEGORY_ID));
top10CategoryIdList.add(new Tuple2<Long, Long>(categoryid, categoryid));
}
JavaPairRDD<Long, Long> top10CategoryIdRDD =
sc.parallelizePairs(top10CategoryIdList);
}
《Spark 大型电商项目实战》源码:https://github.com/Erik-ly/SprakProject
本文为《Spark大型电商项目实战》系列文章之一,
更多文章:Spark大型电商项目实战:http://blog.csdn.net/u012318074/article/category/6744423