spark streaming-基于sql实时统计热门产品

原创 2018年04月16日 09:27:00

本文章主要实现热门商品的top统计,源于真实案例

import java.util.ArrayList;
import java.util.List;

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.function.Function;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.hive.HiveContext;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;
import org.apache.spark.streaming.Durations;
import org.apache.spark.streaming.api.java.JavaPairDStream;
import org.apache.spark.streaming.api.java.JavaReceiverInputDStream;
import org.apache.spark.streaming.api.java.JavaStreamingContext;

import scala.Tuple2;

/**
 * 与Spark SQL整合使用,top3热门商品实时统计
 * @author Administrator
 *
 */
public class Top3HotProduct {

   public static void main(String[] args) {
      SparkConf conf = new SparkConf()
            .setMaster("local[2]")
            .setAppName("Top3HotProduct");  
      JavaStreamingContext jssc = new JavaStreamingContext(conf, Durations.seconds(1));
      
      // 首先看一下,输入日志的格式
      // leo iphone mobile_phone
      

      // 获取输入数据流
      JavaReceiverInputDStream<String> productClickLogsDStream = jssc.socketTextStream("spark1", 9999);
      
      // 然后,应该是做一个映射,将每个种类的每个商品,映射为(category_product, 1)的这种格式
      // 从而在后面可以使用window操作,对窗口中的这种格式的数据,进行reduceByKey操作
      // 从而统计出来,一个窗口中的每个种类的每个商品的,点击次数
      JavaPairDStream<String, Integer> categoryProductPairsDStream = productClickLogsDStream
            .mapToPair(new PairFunction<String, String, Integer>() {

               private static final long serialVersionUID = 1L;

               @Override
               public Tuple2<String, Integer> call(String productClickLog)
                     throws Exception {
                  String[] productClickLogSplited = productClickLog.split(" "); 
                  return new Tuple2<String, Integer>(productClickLogSplited[2] + "_" + 
                        productClickLogSplited[1], 1);
               }
               
            });
      
      // 然后执行window操作
      // 到这里,就可以做到,每隔10秒钟,对最近60秒的数据,执行reduceByKey操作
      // 计算出来这60秒内,每个种类的每个商品的点击次数
      JavaPairDStream<String, Integer> categoryProductCountsDStream = 
            categoryProductPairsDStream.reduceByKeyAndWindow(
                  
                  new Function2<Integer, Integer, Integer>() {

                     private static final long serialVersionUID = 1L;
            
                     @Override
                     public Integer call(Integer v1, Integer v2) throws Exception {
                        return v1 + v2;
                     }
                     
                  }, Durations.seconds(60), Durations.seconds(10));  
      
      // 然后针对60秒内的每个种类的每个商品的点击次数
      // foreachRDD,在内部,使用Spark SQL执行top3热门商品的统计
      categoryProductCountsDStream.foreachRDD(new Function<JavaPairRDD<String,Integer>, Void>() {
         
         private static final long serialVersionUID = 1L;

         @Override
         public Void call(JavaPairRDD<String, Integer> categoryProductCountsRDD) throws Exception {
            // 将该RDD,转换为JavaRDD<Row>的格式
            JavaRDD<Row> categoryProductCountRowRDD = categoryProductCountsRDD.map(
                  
                  new Function<Tuple2<String,Integer>, Row>() {

                     private static final long serialVersionUID = 1L;

                     @Override
                     public Row call(Tuple2<String, Integer> categoryProductCount)
                           throws Exception {
                        String category = categoryProductCount._1.split("_")[0];
                        String product = categoryProductCount._1.split("_")[1];
                        Integer count = categoryProductCount._2;
                        return RowFactory.create(category, product, count);   
                     }
                     
                  });
            
            // 然后,执行DataFrame转换
            List<StructField> structFields = new ArrayList<StructField>();
            structFields.add(DataTypes.createStructField("category", DataTypes.StringType, true)); 
            structFields.add(DataTypes.createStructField("product", DataTypes.StringType, true));  
            structFields.add(DataTypes.createStructField("click_count", DataTypes.IntegerType, true));  
            StructType structType = DataTypes.createStructType(structFields);
            
            HiveContext hiveContext = new HiveContext(categoryProductCountsRDD.context());
            
            DataFrame categoryProductCountDF = hiveContext.createDataFrame(
                  categoryProductCountRowRDD, structType);
            
            // 将60秒内的每个种类的每个商品的点击次数的数据,注册为一个临时表
            categoryProductCountDF.registerTempTable("product_click_log");  
            
            // 执行SQL语句,针对临时表,统计出来每个种类下,点击次数排名前3的热门商品
            DataFrame top3ProductDF = hiveContext.sql(
                  "SELECT category,product,click_count "
                  + "FROM ("
                     + "SELECT "
                        + "category,"
                        + "product,"
                        + "click_count,"
                        + "row_number() OVER (PARTITION BY category ORDER BY click_count DESC) rank "
                     + "FROM product_click_log"  
                  + ") tmp "
                  + "WHERE rank<=3");
            
            // 这里说明一下,其实在企业场景中,可以不是打印的
            // 案例说,应该将数据保存到redis缓存、或者是mysql db中
            // 然后,应该配合一个J2EE系统,进行数据的展示和查询、图形报表
            
            top3ProductDF.show();      
            
            return null;
         }
         
      });
      
      jssc.start();
      jssc.awaitTermination();
      jssc.close();
   }
   
}

Spark日志分析项目Demo(7)--临时表查询,各区域top3热门商品统计

如果是在关系数据库里实现各区域top3热门商品统计,需要编写sql查询语句。 之前用RDD先排序,后获取top的方法实现top n, 下面换成用临时表的sql top查询来实现,流程是: (1)...
  • zhi_fu
  • zhi_fu
  • 2017-09-09 16:41:01
  • 590

第97课: 使用Spark Streaming+Spark SQL实现在线动态计算出特定时间窗口下的不同种类商品中的热门商品排名

第97课: 使用Spark Streaming+Spark SQL实现在线动态计算出特定时间窗口下的不同种类商品中的热门商品排名 本节课将在之前学习的Spark SQL和 DataFra...
  • duan_zhihua
  • duan_zhihua
  • 2016-05-04 20:03:39
  • 1075

第97讲:使用Spark Streaming+Spark SQL来在线动态计算电商中不同类别中最热门的商品排名,

package com.dt.streaming import org.apache.spark.SparkConf import org.apache.spark.sql.Row import o...
  • qq_21234493
  • qq_21234493
  • 2016-05-15 22:56:03
  • 832

SparkSQL结合SparkStreaming,使用SQL完成实时计算中的数据统计

SparkSQL结合SparkStreaming,使用SQL完成实时计算中的数据统计 主题 SQL Spark SQL 实时计算 关键字:SparkSQL、Spark Streaming、S...
  • zhangshucheng129
  • zhangshucheng129
  • 2017-04-12 10:07:38
  • 4869

第110讲: Spark Streaming电商广告点击综合案例通过updateStateByKey等实现广告点击流量的在线更新统计

package com.dt.spark.SparkApps.sparkstreaming; import java.sql.Connection; import java.sql.Dri...
  • qq_21234493
  • qq_21234493
  • 2016-06-05 20:10:28
  • 1270

基于Spark实时计算商品关注度

基于Spark实时计算商品关注度 一、实验介绍 1.1 内容简介 处于网络时代的我们,随着 O2O 的营销模式的流行,越来越多的人开始做起了电商。 与此同时也产生了许多网络数据...
  • oxuzhenyi
  • oxuzhenyi
  • 2017-05-02 14:53:02
  • 864

如何基于 Spark Streaming 构建实时计算平台

GitChat 作者:潘国庆 前言随着互联网技术的迅速发展,用户对于数据处理的时效性、准确性与稳定性要求越来越高,如何构建一个稳定易用并提供齐备的监控与预警功能的实时计算平台也成了很多公司一个很大的...
  • GitChat
  • GitChat
  • 2017-09-21 11:49:16
  • 2354

reduceByKeyAndWindow实现基于滑动窗口的热点搜索词实时统计(Java版本)

package gh.spark.SparkStreaming; import java.util.List; import org.apache.spark.SparkConf; im...
  • accptanggang
  • accptanggang
  • 2016-11-08 13:43:22
  • 2207

实战SparkStream+Kafka+Redis实时计算商品销售额

写在前面2016年天猫双十一当天,零点的倒计时话音未落,52秒交易额冲破10亿。随后,又迅速在0时6分28秒,达到100亿!每一秒开猫大屏上的交易额都在刷新,这种时实刷新的大屏看着感觉超爽。天猫这个大...
  • whzhaochao
  • whzhaochao
  • 2017-08-30 16:45:39
  • 1522

第105课: Spark Streaming电商广告点击综合案例在线点击统计实战

第105课:  Spark Streaming电商广告点击综合案例在线点击统计实战 语言选择:Java中大规模项目开发(京东) Scala看Spark源代码 数据来自于kafka 1,复制代码 Spa...
  • duan_zhihua
  • duan_zhihua
  • 2016-05-18 21:16:23
  • 1696
收藏助手
不良信息举报
您举报文章:spark streaming-基于sql实时统计热门产品
举报原因:
原因补充:

(最多只允许输入30个字)