本文通过编写SparkCore和SparkSQL两种方式实现电商流量的PV、UV 以及会话二跳率的统计。
指标名 | 全称 | 描述 | 口径 |
---|---|---|---|
uv | User Views | 独立访客数,一台电脑(一个客户端)算一个 | count(distinct guid) 去重型 |
pv | Page Views | 页面访问量:刷新一次计算一次 | count(url) 汇总型 |
二跳率 | Two hop rate | 用户衡量用户来访后是否发生点击 | pv大于2的session/总session:rate = count(distinct case when pv>=2 then sessionid else null end) / count(distinct sessionid) |
数据准备
数据存在Hive。
链接:https://pan.baidu.com/s/1Vrb4mVE3vDdkAgU8Q8D_QA
提取码:837r
建表
drop table track_log;
create table track_log (
id string ,
url string ,
referer string ,
keyword string ,
type string ,
guid string ,
pageId string ,
moduleId string ,
linkId string ,
attachedInfo string ,
sessionId string ,
trackerU string ,
trackerType string ,
ip string ,
trackerSrc string ,
cookie string ,
orderCode string ,
trackTime string ,
endUserId string ,
firstLink string ,
sessionViewNo string ,
productId string ,
curMerchantId string ,
provinceId string ,
cityId string )
PARTITIONED BY (ds string,hour string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
导入数据
load data inpath /xxx/xxx into table track_log partition(ds=“2015082818”, hour=“18”);
SparkCore 编程
PV和UV 方式一
package com.felahong.visitcount
import org.apache.spark.storage.StorageLevel
import org.apache.spark.{
HashPartitioner, SparkConf, SparkContext}
/**
* Program: fastspark
* Package: com.felahong.visitcount
* Description: Created by felahong on 2020/4/12 23:33
* TODO 电商流量统计-uv和pv
* uv:独立访客数,一台电脑(一个客户端)算一个
* select count(*) from (select guid from track_log group by guid) t; -- 去重型
* pv:页面访问量,页面访问数,刷新一次计算一次
* count(url) -- 汇总型
*/
object VisitsCount {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("visitsCount").setMaster("local[*]")
val sc = new SparkContext(conf)
val inpath = "hdfs://felahong:9000/user/hive/warehouse/db_spark.db/track_log/ds=2015-08-28/hour=18"
// 取出并清洗数据
val logRdd = sc.textFile(inpath).map(row => {
val fields = row.split("\t")
val guid = fields(5)
val url = fields(1)
val date = fields(17).substring(0, 10) // trackTime 的格式 2015-08-28 18:10:00
(guid, url, date)
}).filter(_._2.trim.length > 0)
.persist(StorageLevel.MEMORY_AND_DISK)
// pv:select ds, count(guid) pv from track_log
// where ds='2015-08-28' and hour='18' and length(url)>0 group by ds;
// 表中为空的已经过滤掉了,所以统计fileRdd的行数就是统计pv
// println(logRdd.count())
val PVRdd = logRdd.map(line=><