spark--网站运营指标统计案例-★★★★★

网站运营指标统计案例-★★★★★

数据

在这里插入图片描述

  • 我们后续需要关注的数据
    • 1.总共有多少条?
    • 2.不重复的IP有多少?
    • 3.来源URL字段计数并排序

需求

  • 需求1.PV:PageView ,页面访问量, 访问一次就是一个PV,上面的访问日志有多少条就有多少PV
    • 分析:读取文件,把该RDD直接count计数即可
  • 需求2.UV:UniqueVisitor:独立用户访问量, 1个用户的重复访问只算1个UV,这里可以用IP区分
    • 分析:这里可以用ip区分,也就是对ip进行去重即可
  • 需求3.来源URL-TopN:要求来源URL地址最多的排行
    • 分析:先过滤出有来源的数据,再取出来源URL,再分组计数得到(refurl,数量),再排序取前5个

代码实现

package cn.hanjiaxiaozhi.exercise
​
import org.apache.spark.rdd.RDD
import org.apache.spark.storage.StorageLevel
import org.apache.spark.{
    
    SparkConf, SparkContext}/**
 * Author hanjiaxiaozhi
 * Date 2020/7/27 14:27
 * Desc 演示网站运营指标统计案例
 * 需求1.PV:PageView ,页面访问量, 访问一次就是一个PV,上面的访问日志有多少条就有多少PV
 * 需求2.UV:UniqueVisitor:独立用户访问量, 1个用户的重复访问只算1个UV,这里可以用IP区分
 * 需求3.来源URL-TopN:要求来源URL地址最多的排行
 * 该需求很简单,可以直接使用SparkCore-RDD来完成
 * 后续一些案例可以使用SparkSQL...
 */
object WebSiteAnanlysis {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //1.创建执行环境
    //SparkCore-RDD的执行环境是SparkContext--离线
    //SparkSQL-DataFrame/DataSet的执行环境是SparkSession--离线
    //SparkStreaming-DStream的执行环境是StreamingContext--实时
    //StructuredStreaming-DataFrame/DataSet的执行环境是SparkSession--实时
    //以后执行环境不会选的话可以对照上面来
    val conf: SparkConf = new SparkConf().setAppName("WebSiteAnanlysis").setMaster("local[*]")
    val sc: SparkContext = new SparkContext(conf)
    sc.setLogLevel("WARN")
    sc.setCheckpointDir("./ckpdir")//实际开发写HDFS目录,学习测试写本地//2.加载日志文件
    //RDD[一行行的日志]
    val fileRDD: RDD[String] = sc.textFile("file:///D:\\data\\spark\\access.log")//3.处理数据
    //对每一行日志按照空格进行切分(不需要压平)//val unit: RDD[String] = fileRDD.flatMap(_.split(" "))//不对,不要压平
    //RDD[Array[String]]==>RDD[每一行按照空格切分之后形成的数组]
    val logArrayRDD: RDD[Array[String]] = fileRDD.map(_.split(" "))//logArrayRDD后续会被频繁使用,所以可以先进行缓存/持久化,在进行Checkpoint
    //logArrayRDD.cache()
    //logArrayRDD.persist()
    logArrayRDD.persist(StorageLevel.MEMORY_AND_DISK)
    logArrayRDD.checkpoint()//4.统计指标并输出结果
    // * 需求1.PV:PageView ,页面访问量, 访问1次就是1个PV,上面的访问日志有多少条就有多少PV
    val pv: Long = logArrayRDD.count()
    println("统计出来的PV为:"+pv)// * 需求2.UV:UniqueVisitor:独立用户访问量, 1个用户的重复访问只算1个UV,这里可以用ip区分,也就是对ip进行去重即可
    //logArrayRDD.map(arr=>arr(0))
    val ipRDD: RDD[String] = logArrayRDD.map(_(0))
    val uv: Long = ipRDD.distinct().count()
    println("统计出来的UV为:"+uv)// * 需求3.来源URL-Top5:要求来源URL地址最多的排行
    //先过滤出有来源的数据,再取出来源URL,再分组计数得到(refurl,数量),再排序取前5个
    //logArrayRDD.filter(arr=>arr.length>10)
    val filtedRDD: RDD[Array[String]] = logArrayRDD.filter(_.length>10)//过滤出数组长度大于10的行,里面才有refurl记录
    val refurlRDD: RDD[String] = filtedRDD.map(_(10))//取出来源URL
    val refurlAndOne: RDD[(String, Int)] = refurlRDD.map((_,1))//每个refurl记为1
    val refurlAndCount: RDD[(String, Int)] = refurlAndOne.reduceByKey(_+_)//分组聚合
    val sortedRDD: RDD[(String, Int)] = refurlAndCount.sortBy(_._2, false)//按照数量逆序排
    val result: Array[(String, Int)] = sortedRDD.take(5)
    result.foreach(println)//5.关闭资源
    sc.stop()
    
    //统计出来的PV为:14619
    //统计出来的UV为:1050
    //("-",5205)
    //("http://blog.fens.me/category/hadoop-action/",547)
    //("http://blog.fens.me/",377)
    //("http://blog.fens.me/wp-admin/post.php?post=2445&action=edit&message=10",360)
    //("http://blog.fens.me/r-json-rjson/",274)
  }
}

猜你喜欢

转载自blog.csdn.net/qq_46893497/article/details/114004039