Spark RDD算子实例——统计广告点击量 Top3

1、数据准备

数据结构:时间戳,省份,城市,用户,广告,中间字段使用空格分隔。

数据样式如下:

1516609143867 6 7 64 16
1516609143869 9 4 75 18
1516609143869 1 7 87 12
1516609143869 2 8 92 9
1516609143869 6 7 84 24
1516609143869 1 8 95 5
1516609143869 8 1 90 29
1516609143869 3 3 36 16
1516609143869 3 3 54 22
1516609143869 7 6 33 5
1516609143869 8 2 91 27
1516609143869 0 5 66 5
1516609143869 1 3 33 6
1516609143869 6 2 97 21
1516609143869 5 2 95 24
1516609143869 8 9 73 11
1516609143869 4 8 62 15
1516609143869 5 5 40 23
1516609143869 6 6 53 17
1516609143869 3 0 86 21
1516609143869 4 6 1 11
1516609143869 3 6 49 7
1516609143869 8 3 4 18
1516609143869 8 8 69 14
1516609143869 0 6 51 29
1516609143869 5 3 59 2
1516609143869 8 4 66 25
1516609143869 3 4 63 9

2、需求

统计出每一个省份广告被点击次数的 TOP3

3、代码实现

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
//需求:统计出每一个省份广告被点击次数的 TOP3
object Practice {

	 def main(args: Array[String]): Unit = {
	 //1.初始化 spark 配置信息并建立与 spark 的连接
	 val sparkConf = new SparkConf().setMaster("local[*]").setAppName("Test")
	 val sc = new SparkContext(sparkConf)
	 //2.读取数据生成 RDD:TS,Province,City,User,AD
	 val line = sc.textFile("E:\\IDEAWorkSpace\\SparkTest\\src\\main\\resources\\agent.log")
	 //3.按照最小粒度聚合:((Province,AD),1)
	 val provinceAdAndOne = line.map { x =>
	 val fields: Array[String] = x.split(" ")
	 ((fields(1), fields(3)), 1)
	 }
	
//4.计算每个省中每个广告被点击的总数:((Province,AD),sum)
	 val provinceAdToSum = provinceAdAndOne.reduceByKey(_ + _)
	 //5.将省份作为 key,广告加点击数为 value:(Province,(AD,sum))
	 val provinceToAdSum = provinceAdToSum.map(x => (x._1._1, (x._1._2, x._2)))
	 //6.将同一个省份的所有广告进行聚合(Province,List((AD1,sum1),(AD2,sum2)...))
	 val provinceGroup = provinceToAdSum.groupByKey()
	 //7.对同一个省份所有广告的集合进行排序并取前 3 条,排序规则为广告点击总数
	 val provinceAdTop3 = provinceGroup.mapValues { x =>
	 x.toList.sortWith((x, y) => x._2 > y._2).take(3)
	 }
	 //8.将数据拉取到 Driver 端并打印
	 provinceAdTop3.collect().foreach(println)
	 //9.关闭与 spark 的连接
	 sc.stop()
	 }

}
	

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个项目实战的目标是实时统计最近1小时的广告点击,并将结果写入Redis中。 为了实现这个目标,我们可以使用Spark Streaming来处理实时数据流。首先,我们需要从Kafka中读取广告点击事件流,并将其转换为DStream对象。然后,我们可以使用窗口操作来计算最近1小时的点击。最后,我们可以将结果写入Redis中。 具体实现步骤如下: 1. 创建Spark Streaming上下文对象,并从Kafka中读取广告点击事件流。 2. 将事件流转换为DStream对象,并使用窗口操作计算最近1小时的点击。 3. 将结果写入Redis中。可以使用Redis的Java客户端库Jedis来实现。 下面是一个简单的代码示例: ```scala import org.apache.spark.streaming._ import org.apache.spark.streaming.kafka._ import redis.clients.jedis.Jedis val ssc = new StreamingContext(sparkConf, Seconds(5)) val kafkaParams = Map("metadata.broker.list" -> brokers) val topics = Set("ad-clicks") val adClicks = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder]( ssc, kafkaParams, topics) val adClicksByHour = adClicks.map { case (_, value) => val fields = value.split(",") val timestamp = fields(0).toLong val hour = timestamp / 3600 (hour, 1) }.reduceByKeyAndWindow(_ + _, _ - _, Minutes(60), Seconds(5)) adClicksByHour.foreachRDD { rdd => rdd.foreachPartition { partition => val jedis = new Jedis(redisHost, redisPort) partition.foreach { case (hour, count) => jedis.hset("ad-clicks", hour.toString, count.toString) } jedis.close() } } ssc.start() ssc.awaitTermination() ``` 在这个示例中,我们首先从Kafka中读取广告点击事件流,并将其转换为DStream对象。然后,我们使用map操作将每个事件的时间戳转换为小时数,并将其作为键,值为1。接下来,我们使用reduceByKeyAndWindow操作计算最近1小时的点击,并将结果写入Redis中。 需要注意的是,我们使用foreachPartition操作来避免在每个分区中创建多个Redis连接。这可以提高性能并减少资源消耗。 总之,使用Spark Streaming和Redis可以轻松实现最近1小时广告点击的实时统计和写入。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值