Scala_Spark-电商平台离线分析项目-需求八各城市各广告的实时点击流量统计

14 篇文章 0 订阅
13 篇文章 0 订阅

Scala_Spark-电商平台离线分析项目-需求八各城市各广告的实时点击流量统计

第四模块:广告流量实时统计统计

技术点:SparkStreaming、kafka集群

知识点:updateStateByKey 全局的累积操作

kafka.broker.list=node01:9092,node02:9092,node03:9092
kafka.topics=AdRealTimeLog0308、

(一)执行步骤

1)本地生产数据 发送到kafka

  1. 开启zookeeper集群

    【三台服务器启动zookeeper】,三台机器都执行以下命令启动zookeeper
    cd /export/servers/zookeeper-3.4.5-cdh5.14.0
    bin/zkServer.sh start
    进程QuorumPeerMain

  2. 开启kafka集群

    【启动kafka集群】默认端口9092
    三台机器启动kafka服务
    [root@node01 servers]# cd /export/servers/kafka_2.11-1.0.0/
    前台启动 ./kafka-server-start.sh …/config/server.properties
    后台启动命令 nohup bin/kafka-server-start.sh config/server.properties > /dev/null 2>&1 &

  3. node01开启一个消费者

    所有配置完成的情况下

    [root@node01 ~]# kafka-console-consumer.sh --zookeeper node01:2181 --topic AdRealTimeLog0308
    
    Using the ConsoleConsumer with old consumer is deprecated and will be removed in a future major release. Consider using the new consumer by passing [bootstrap-server] instead of [zookeeper].
    
    // 等待消费
    
    
  4. 本地运行模拟生产实时数据文件MockRealTimeData.scala

    该需求运行前可以把id数和秒数改小一点 不然要等很久才能过100次

    // node01上出现 集群上消费成功 代表生产数据发送到kafka没有问题
    1573145438221 3 3 93 5
    1573145438221 6 6 87 17
    1573145438221 0 0 10 16
    1573145438221 7 7 11 15
    1573145438221 0 0 8 18
    1573145438221 0 0 97 1
    
  5. 提前在本地建立的commerce数据库创建好5张ad广告表

// 以上部分和上个笔记一样

2)IDEA运行AdverStat.scala

  1. 在以上试验成功状态下,IDEA运行AdverStat.scala文件

    运行成功后不断去数据库中刷新ad_stat表 数字在不断变化

    其中主要方法部分如下:

    def provinceCityClickStat
     /**
       * 锚点2的方法
       * 需求八 各城市一天中的广告点击(去除了黑名单里的id点击的)
       *
       * 知识点
       * updateStateByKey 全局的累积操作
       * reduceByKey 统计每个rdd的值的累积量
       *
       * @param adRealTimeFilterDStream 所有不在黑名单里的数据
       * @return
       */
      def provinceCityClickStat(adRealTimeFilterDStream: DStream[String])={
        // adReadTimeValueDStream:DStream[RDD RDD RDD ...] RDD[String]
        // String: timestamp province city userid adid
        // todo map
        val key2ProvinceCityDStream = adRealTimeFilterDStream.map{
          case log =>
            val logSplit: Array[String] = log.split(" ")
            val timeStamp = logSplit(0).toLong
            // dateKey : yy-mm-dd
            val dateKey = DateUtils.formatDateKey(new Date(timeStamp))
            val province = logSplit(1)
            val city = logSplit(2)
            val adid = logSplit(4)
    
            val key = dateKey+"_"+province+"_"+city+"_"+adid // 要加广告id 每个城市 每个广告的点击量 这意思 唯独不要用户id
    
            (key,1L)
        }
    
        // todo updateStateByKey
        // 聚合 关键步骤 sparkStreaming常用的updateStateByKey,按key进行遍历  记住是遍历
        // 所有的rdd都会被遍历 全局的累积操作
        val key2StateDStream = key2ProvinceCityDStream.updateStateByKey[Long]{ // updateStateByKey 必须有了Some(类实例)才会不爆红(长的像没导包的爆红 还以为不能用 南)
          // values:Seq[Long] 就是当期执行的key 对应到的所有数据 以Seq形式传进来 所有的(当前key,1L)里面的1
          // state:Option[Long] 就是当前执行的key 对应的之前checkpoint出去的值
          (values:Seq[Long],state:Option[Long]) =>
            var newValue = 0L
            if(state.isDefined) // 判断Option里面有没有值 None/可get
              newValue = state.get // 如果之前有checkpoint出去就get出来 如果这个key是第一次执行 没有就是上面的0
    
            for(value <- values){ // 增强for循环 其实就是遍历的一个一个的1
              newValue += value //
            }
    
            // 返回最新的累积值 它会自动的帮我checkpoint到当前key
            Some(newValue)
        }
        // 至此 获得全局的累加结果
    
        //
        key2StateDStream.foreachRDD{
          rdd => rdd.foreachPartition{
            items =>
              val adStatArray = new ArrayBuffer[AdStat]()
              // key: date_province_city_adid
              for((key,count) <- items){
                val keySplit = key.split("_")
                val date = keySplit(0)
                val province = keySplit(1)
                val city = keySplit(2)
                val adid = keySplit(3).toLong
    
                adStatArray += AdStat(date,province,city,adid,count)
              }
    
              // 调用DAO类 更新到数据库
              AdStatDAO.updateBatch(adStatArray.toArray)
    
          }
        }
      }
      // 需求八结束 运行后刷新看ad_stat表
    
    主方法
     def main(args: Array[String]): Unit = {
    
        val sparkConf = new SparkConf().setAppName("adverstat").setMaster("local[*]")
        val sparkSession = SparkSession.builder().config(sparkConf).enableHiveSupport().getOrCreate()
    
        // 标准应当是 val streamingContext = StreamingContext.getActiveOrCreate(checkpointDir,func)
        val streamingContext = new StreamingContext(sparkSession.sparkContext,Seconds(5))
    
        // 配置kafka相关信息
        val kafka_brokers = ConfigurationManager.config.getString(Constants.KAFKA_BROKERS) //node01:9092,node02:9092,node03:9092
        val kafka_topics = ConfigurationManager.config.getString(Constants.KAFKA_TOPICS) //kafka.topics=AdRealTimeLog0308
    
        // kafka配置信息
        val kafkaParam = Map(
          "bootstrap.servers" -> kafka_brokers,
          "key.deserializer" -> classOf[StringDeserializer],
          "value.deserializer" -> classOf[StringDeserializer],
          "group.id" -> "group1",
          // auto.offset.reset
          // latest: 先去Zookeeper获取offset,如果有,直接使用,如果没有,从最新的数据开始消费
          // earlist: 先去zookeeper获取offset,如果有直接使用,如果没有,从最开始的数据开始消费
          // none: 先去Zookeeper获取offset,如果有,直接使用,如果没有,直接报错
          "auto.offset.reset" -> "latest",
          "enable.auto.commit" -> (false:java.lang.Boolean)
        )
    
        // 创建DStream
        // 从kafka中消费数据 拿到的每一条数据都是messege,里面是key-value
        val adRealTimeDStream = KafkaUtils.createDirectStream[String,String](
          streamingContext,
          // 让kafka分区均匀地在excutor上分配 有三种选择
          LocationStrategies.PreferConsistent,
          // 消费者订阅
          ConsumerStrategies.Subscribe[String,String](Array(kafka_topics),kafkaParam)
        )
    
        // 取出了DStream里面每一条数据的value值
        // adReadTimeValueDStream:DStream[RDD RDD RDD ...] RDD[String]
        // String: timestamp province city userid adid
        val adReadTimeValueDStream = adRealTimeDStream.map(item => item.value())
    
        // adRealTimeFilterDStream  所有不在黑名单里的实时数据都在里面了
        val adRealTimeFilterDStream =adReadTimeValueDStream.transform{
          logRDD => {
            // blackListArray:Array[AdBlacklist]  AdBlacklist:userId
            val blackListArray = AdBlacklistDAO.findAll() // 这里连接了数据库 创建了mySqlPool
    
            // userIdArray:Array[Long] [userId1,userId2,...]
            var userIdArray = blackListArray.map(item => item.userid)
    
            // 过滤掉已经存在在黑名单里的
            logRDD.filter {
              // log: timestamp province city userid adid
              case log =>
                val logSplit = log.split(" ")
                val userId = logSplit(3).toLong
                !userIdArray.contains(userId)
            }
          } // end logRDD
        } //end adRealTimeFilterDStream
    
            // 测试 本地能否消费kafka集群的数据
        // adRealTimeFilterDStream.foreachRDD(rdd=>rdd.foreach(println(_)))
    
    
        // todo 需求七:实时维护黑名单
        // 1
        generateBlackList(adRealTimeFilterDStream)
    
    
        // todo 需求八:各省各城市(即各城市)一天中的各广告点击量(累积统计)
        // 在使用 前要指定一下checkpoint目录
        // 因为它是以k-v保存在目录里 每次累积的时候把v反序列化出来 累积后再序列化进去
        streamingContext.checkpoint("./spark-streaming")
        // 对所有不在黑名单里的数据checkpoint 时间间隔必须是创建streamingContext的指定时间间隔的倍数
        adRealTimeFilterDStream.checkpoint(Duration(10000))
        // 2
        provinceCityClickStat(adRealTimeFilterDStream)
    
    
        // 开启
        streamingContext.start()
        streamingContext.awaitTermination()
    
    
    
      }
    
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目Spark离线处理本项目来源于企业级电商网站的大数据统计分析平台,该平台以 Spark 框架为核心,对电商网站的日志进行离线实时分析。 该大数据分析平台对电商网站的各种用户行为(访问行为、购物行为、广告点击行为等)进行分析,根据平台统计出来的数据,辅助公司中的 PM(产品经理)、数据分析师以及管理人员分析现有产品的情况,并根据用户行为分析结果持续改进产品的设计,以及调整公司的战略和业务。最终达到用大数据技术来帮助提升公司的业绩、营业额以及市场占有率的目标。 本项目使用了 Spark 技术生态栈中最常用的三个技术框架,Spark Core、Spark SQL 和 Spark Streaming,进行离线计算和实时计算业务模块的开发。实现了包括用户访问 session 分析、页面单跳转化率统计、热门商品离线统计广告流量实时统计 4 个业务模块。通过合理的将实际业务模块进行技术整合与改造,该项目几乎完全涵盖了 Spark Core、Spark SQL 和 Spark Streaming 这三个技术框架中大部分的功能点、知识点,学员对于 Spark 技术框架的理解将会在本项目中得到很大的提高。 项目Spark实时处理项目简介对于实时性要求高的应用,如用户即时详单查询,业务量监控等,需要应用实时处理架构项目场景对于实时要求高的应用、有对数据进行实时展示和查询需求项目技术分别使用canal和kafka搭建各自针对业务数据库和用户行为数据的实时数据采集系统,使用SparkStreaming搭建高吞吐的数据实时处理模块,选用ES作为最终的实时数据处理结果的存储位置,并从中获取数据进行展示,进一步降低响应时间。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值