Spark:实时数据微批处理(3.Spark Core 项目实战)

1 准备数据

本项目的数据是采集自电商的用户行为数据.
主要包含用户的 4 种行为: 搜索, 点击, 下单和支付.
数据格式如下, 不同的字段使用下划线分割开_:
在这里插入图片描述数据说明:

  1. 数据采用 _ 分割字段
  2. 每一行表示用户的一个行为, 所以每一行只能是四种行为中的一种.
  3. 如果搜索关键字是 null, 表示这次不是搜索
  4. 如果点击的品类 id 和产品 id 是 -1 表示这次不是点击
  5. 下单行为来说一次可以下单多个产品, 所以品类 id 和产品 id 都是多个, id 之间使用逗号,分割. 如果本次不是下单行为, 则他们相关数据用null来表示
  6. 支付行为和下单行为类似.

2.需求 1: Top10 热门品类

2.1 需求分析

按照每个品类的 点击、下单、支付 的量来统计热门品类.
创建3个包:

  1. acc :存累加器
  2. app :要实现的功能
  3. bean :封装数据
    在这里插入图片描述

2.2 思路

使用累加器:

  1. 遍历全部日志数据, 根据品类 id 和操作类型分别累加. 需要用到累加器
  2. 定义累加器
  3. 当碰到订单和支付业务的时候注意拆分字段才能得到品类 id
  4. 遍历完成之后就得到每个每个品类 id 和操作类型的数量.
  5. 按照点击下单支付的顺序来排序
  6. 取出 Top10
    在这里插入图片描述

2.3 代码实现

2.3.1 整体入口 ProjectApp

import com.jaffe.sparkcore.project.bean.{
   CategoryCount, UserVisitAction}
import org.apache.spark.{
   SparkConf, SparkContext}

/**
 * @Author jaffe
 * @Date 2020/05/11  10:19
 */
object ProjectApp {
   
  def main(args: Array[String]): Unit = {
   
    //1.读数据
    val conf = new SparkConf().setAppName("ProjectApp").setMaster("local[2]")
    val sc = new SparkContext(conf)
    val sourceRDD = sc.textFile("E:\\bigdata\\text\\input\\spark\\project\\user_visit_action.txt")

    //2.封装到样例类
    val userVisitActionRDD = sourceRDD.map(line => {
   
      val splits = line.split("_")
      UserVisitAction(
        splits(0),
        splits(1).toLong,
        splits(2),
        splits(3).toLong,
        splits(4),
        splits(5),
        splits(6).toLong,
        splits(7).toLong,
        splits(8),
        splits(9),
        splits(10),
        splits(11),
        splits(12).toLong)

    })

    //3. 需求1的分析  返回值是top10 的品类id
val categoryCountList:List[CategoryCount]  = CategoryTopApp.calcCategoryTop10(sc, userVisitActionRDD)

    sc.stop()

  }
}

2.3.2 封装用户行为数据 UserVisitAction

package com.jaffe.sparkcore.project.bean

/**
 * @Author jaffe
 * @Date 2020/05/11  10:28
 */

/**
 * 用户访问动作表
 *
 * @param date               用户点击行为的日期
 * @param user_id            用户的ID
 * @param session_id         Session的ID
 * @param page_id            某个页面的ID
 * @param action_time        动作的时间点
 * @param search_keyword     用户搜索的关键词
 * @param click_category_id  某一个商品品类的ID
 * @param click_product_id   某一个商品的ID
 * @param order_category_ids 一次订单中所有品类的ID集合
 * @param order_product_ids  一次订单中所有商品的ID集合
 * @param pay_category_ids   一次支付中所有品类的ID集合
 * @param pay_product_ids    一次支付中所有商品的ID集合
 * @param city_id            城市 id
 */
case class UserVisitAction(date: String,
                           user_id: Long,
                           session_id: String,
                           page_id: Long,
                           action_time: String,
                           search_keyword: String,
                           click_category_id: Long,
                           click_product_id: Long,
                           order_category_ids: String,
                           order_product_ids: String,
                           pay_category_ids: String,
                           pay_product_ids: String,
                           city_id: Long)

2.3.3 定义用到的累加器 CategoryAcc

需要统计每个品类的点击量, 下单量和支付量, 所以我们在累加器中使用 Map 来存储这些数据: Map(cid-> (click, order,pay))

import com.jaffe.sparkcore.project.bean.UserVisitAction
import org.apache.spark.util.AccumulatorV2

import scala.collection.mutable

/**
 * @Author jaffe
 * @Date 2020/05/11  10:35
 */
class CategoryAcc extends AccumulatorV2[UserVisitAction, mutable.Map[String, (Long, Long, Long)]] {
   
  //可变map使用val
  private val map = mutable.Map[String, (Long, Long, Long)]()

  //判零,判断集合是否为空
  override def isZero: Boolean = map.isEmpty

  //复制累加器
  override def copy(): AccumulatorV2[UserVisitAction, mutable.Map[String, (Long, Long, Long)]] = {
   
    val acc = new CategoryAcc
    //java:sychronized(锁){}
    acc.map.synchronized {
   
      acc.map ++= this.map
    }
    acc
  }

  //重置累加器
  override def reset(): Unit = {
   
    //可变累加器,重置就是清空
    map.clear()
  }

  //累加(分区内聚合)
  override def add(v: UserVisitAction): Unit = {
   
    /*
   用户行为有可能是点击,有可能是搜索、下单、支付
     */

    v match {
   
      //判断是否点击
      case action if action.click_category_id != -1 =>
        //点击的品类id
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值