项目(day01网站流量指标统计)

(40) 2024-05-05 13:01:01

网站流量指标统计
对于网站流量指标统计,一般可以分为如下维度:
1.统计每一天的页面访问量。
2.统计每一天的独立访客数(按人头数统计)
3.统计每一天的独立会话数(Session)
收集到如上指标之后,可以按时段来分析网站整体的流量情况

项目(day01网站流量指标统计) (https://mushiming.com/)  第1张

项目(day01网站流量指标统计) (https://mushiming.com/)  第2张

项目(day01网站流量指标统计) (https://mushiming.com/)  第3张

项目(day01网站流量指标统计) (https://mushiming.com/)  第4张
4.按访客地域统计
5.按统计访客ip地址
6.按来路页面分析

项目(day01网站流量指标统计) (https://mushiming.com/)  第5张
综上,本项目统计的指标总结如下:
1.PV,页面访问量。用户点击一次页面,就算做一个PV,刷新操作也算。我们会统计一天内总的PV

2.UV,独立访客数。按人头来统计,我们会统计一天内有多少不同的用户来访问网站。处理思路:当一名用户访问网站时,后台会为此用户生成一个用户id(uvid),然后将uvid存到用户浏览器的cookie里,待下一次此用户访问时,会携带uvid信息。
所以,这个指标实际就是统计一天之内有多少不同的uvid

3.VV,独立会话(Session)数。统计一天之内有多少不同的会话。产生新会话的条件:
①关闭浏览器,再次打开,会产生一个新会话
②过了会话的操作超时时间(半小时)后,会产生一个新会话

实现思路:
当产生一个新会话时,后台会为此会话生成一个会话id(ssid),然后存到cookie里。
所以统计VV,实际上就是统计一天之内有多少不同的ssid。

4.BR,页面跳出率。BR=跳出会话数/总的会话数(VV)跳出会话指的是:只产生一次访问行为的会话。
所以BR这个指标可以衡量网站的优良性。这个指标越高,说明对用户的吸引力越低,则需要改进

5.NewCust,新增用户数。今天的某个用户在历史数据中从未出现过,则此用户算作一个新增用户。
统计今天的uvid在历史数据中没出现过的数量。
假设今天:2019-09-19
历史数据:<2019-09-19

6.NewIp,新增Ip数。统计今天的ip在历史数据中未出现过的个数。

7.AvgDepp,平均的会话访问深度。AvgDeep=总的会话访问深度/总的会话数(VV)其中,总的会话访问深度=每个会话访问深度的求和。
每个会话的访问深度=访问多少不同的url地址

8.AvgTime,平均的会话访问时长。AvgTime=总的会话访问时长/总的会话数(VV)其中,总的会话时长=每个会话时长的求和。
如何求出每个会话的访问时长。
比如:
会话1:
A.jsp时间戳1
B.jsp时间戳2
C.jsp时间戳3
会话2:
A.jsp时间戳1
B.jsp时间戳2
C.jsp时间戳3

我们可以统计获取打开页面时的时间戳,统计出每个会话的总的访问时长但是在生产环境,计算的理论值要小于真实值,因为最后一个页面的停留时长无法获取。
统计每个会话的总时长,即:Max TineStamp- Min TimeStamp

================================

项目(day01网站流量指标统计) (https://mushiming.com/)  第6张
项目(day01网站流量指标统计) (https://mushiming.com/)  第7张

项目(day01网站流量指标统计) (https://mushiming.com/)  第8张

以上架构服务搭建于zookeeper集群

tomcat配置
项目(day01网站流量指标统计) (https://mushiming.com/)  第9张
项目(day01网站流量指标统计) (https://mushiming.com/)  第10张

项目(day01网站流量指标统计) (https://mushiming.com/)  第11张
CTRL+s保存配置
新建工程
项目(day01网站流量指标统计) (https://mushiming.com/)  第12张
访问地址

http://localhost:8080/FluxAppServer/a.jsp

修改js

    var dest_path   = "http://localhost:8080/FluxLogServer/servlet/LogServlet?";

前端代码

flume配置

[root@hadoop01 data]# pwd
/home/presoftware/apache-flume-1.6.0-bin/data

[root@hadoop01 data]# cp hdfssink.conf web.conf
[root@hadoop01 data]# vim web.conf 


a1.sources=s1
a1.channels=c1
a1.sinks=k1

a1.sources.s1.type=avro
a1.sources.s1.bind=0.0.0.0
a1.sources.s1.port=44444
a1.source.s1.interceptors=i1
a1.source.s1.interceptors.i1.type=timestamp

a1.channels.c1.type=memory
#配置flume的通道容量,表示最多可以缓存
#1000Events事件。在生产环境,建议在5~10万
a1.channels.c1.capacity=1000
#批处理大小,生产环境建议在1000以上
a1.channels.c1.transactionCapacity=100

a1.sinks.k1.type=hdfs
a1.sinks.k1.hdfs.path=hdfs://hadoop01:9000/weblog/reporttime=%Y-%m-%d
#按时间周期滚动生成一个新文件。建议在一小时及以上。避免生成大量的小文件
a1.sinks.k1.hdfs.rollInterval=30
#flume在HDFS生成文件时的格式。①默认格式,是二进制格式②DataStream,普通文本格式
a1.sinks.k1.hdfs.fileType=DataStream
#按文件大小滚动生成新文件。默认是1kb。如果是0,表示不按此条件滚动
a1.sinks.k1.hdfs.rollSize=0
#按文件中行数滚动。默认是10行。
a1.sinks.k1.hdfs.rollCount=0
a1.sinks.k1.hdfs.useLocalTimeStamp = true
a1.sources.s1.channels=c1
a1.sinks.k1.channel=c1

启动(flume要比前端服务先启动)

[root@hadoop01 data]# ../bin/flume-ng agent -n a1 -c ./ -f ./web.conf -Dflum.root.logger=INFO,console

eclipse中hadoop文件乱码解决
项目(day01网站流量指标统计) (https://mushiming.com/)  第13张

==============================

hive做数据的离线处理
hive启动

[root@hadoop01 ~]# cd /home/presoftware/apache-hive-1.2.0-bin/bin
[root@hadoop01 bin]# sh hive
hive> create database weblog;
OK
Time taken: 1.983 seconds
hive> use weblog;



#hdfs
[root@hadoop01 ~]# hadoop fs -ls /weblog
Found 1 items
drwxr-xr-x   - root supergroup          0 2022-09-27 23:19 /weblog/reporttime=2022-09-27

1.建立总表(外部表+分区表),加载和管理所有的字段数据,比如url, urlname,color…等。
2.为总表添加分区信息。
3.建立清洗表(内部表),清洗出有用的业务字段。
4.从总表中将清洗后的字段数据插入到清洗表
5.建立业务表,用于存储统计后的各个指标,本项目的pv, uv, vv… .

#建表(总表)
create external table flux (url string,urlname string,title string,chset string,src string,col string,lg string, je string,ec string,fv string,cn string,ref string,uagent string,stat_uv string,stat_ss string,cip string) partitioned by (reportTime string) row format delimited fields terminated by '|' location '/weblog';

添加分区
方式1

msck repair table flux;

方式2
因为以上分区已经添加好,所以先删除

alter table flux drop partition(reporttime='2022-09-27');
alter table flux add partition(reporttime='2022-09-27') location '/weblog/reporttime=2022-09-27';

查询数据验证

hive> select * from flux tablesample(1 ROWS);
OK
http://localhost:8080/FluxAppServer/b.jsp	b.jsp	页面B	UTF-8	1920x1080     24-bit	en	0	1		0.6097321720366953	http://localhost:8080/FluxAppServer/a.jsp	Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36	59844165863196852806	2672496465_9_1664291312834	0:0:0:0:0:0:0:1	2022-09-27
Time taken: 0.121 seconds, Fetched: 1 row(s)

创建清洗表

create table dataclear(reportTime string,url string,urlname string,uvid string,ssid string,sscount string,sstime string,cip string) row format delimited fields terminated by '|';

将总表数据插入到清洗表
方式一

insert overwrite table dataclear select reporttime,url,urlname,stat_uv,split(stat_ss,"_")[0],split(stat_ss,"_")[1],split(stat_ss,"_")[2],cip from flux where url!='';

方式2,加了条件----日期

insert overwrite table dataclear select reporttime,url,urlname,stat_uv,split(stat_ss,"_")[0],split(stat_ss,"_")[1],split(stat_ss,"_")[2],cip from flux where url!='' where reporttime='2022-09-27';

查询清洗表的pv(页面访问量)

select count(*)  from dataclear where reportTime='2022-09-27';

用户个数

#效率低---一个job
select count(distinct uvid) as uv from dataclear where reporttime='2022-09-27';
#解决方式---底层开启机制,一个job转成多个job(count和distinct分开工作)
set hive.groupby.skewindata=true;
#设置reduce task的数量
set mapred.reduce.tasks=3;
#创建业务表
 create table tongji(reportTime string,pv int,uv int,vv int, br double,newip int, newcust int, avgtime double,avgdeep double) row format delimited fields terminated by '|';


数据处理分解步骤
数据处理
PV:访问量

select count(*) as pv from dataclear where reportTime='2020-11-19';

UV:独立访客数

select count(distinct uvid) as uv from dataclear where reportTime='2020-11-19';

SV:独立会话数

select count(distinct ssid) as sv from dataclear where reportTime='2020-11-19';


BR:跳出率

set hive.mapred.mode=nonstrict;

select round(br_taba.a/br_tabb.b,4) as br from (select count(*) as a from (select ssid from dataclear where reportTime='2020-11-19' group by ssid having count(ssid)=1) as br_tab) as br_taba,(select count(distinct ssid) as b from dataclear where reportTime='2020-11-19') as br_tabb;

NewIP:新增IP数

select count(distinct dataclear.cip) from dataclear where dataclear.reportTime='2020-11-19' and cip not in (select dc2.cip from dataclear as dc2 where dc2.reportTime<'2020-11-19');

NewCust:新增访客数

select count(distinct dataclear.uvid) from dataclear where dataclear.reportTime='2020-11-19' and uvid not in (select dc2.uvid from dataclear as dc2 where dc2.reportTime < '2019-11-19');


AvgTime:平均访问时长

select round(avg(atTab.usetime),4) as avgtime from (select max(sstime) -min(sstime) as usetime from dataclear where reportTime='2020-11-19' group by ssid) as atTab;


AvgDeep:平均访问深度

select round(avg(deep),2) as viewdeep from (select count(distinct urlname) as deep from flux where reportTime='2020-11-19' group by ssid as tviewdeep;


插入业务表的语句

insert overwrite table tongji select '2022-09-28',tab1.pv,tab2.uv,tab3.vv,tab4.br,tab5.newip,tab6.newcust,tab7.avgtime,tab8.avgdeep from (select count(*) as pv from dataclear where reportTime = '2022-09-28') as tab1, (select count(distinct uvid) as uv from dataclear where reportTime = '2022-09-28') as tab2, (select count(distinct ssid) as vv from dataclear where reportTime = '2022-09-28') as tab3,(select round(br_taba.a/br_tabb.b,4)as br from (select count(*) as a from (select ssid from dataclear where reportTime='2022-09-28' group by ssid having count(ssid) = 1) as br_tab) as br_taba,(select count(distinct ssid) as b from dataclear where reportTime='2022-09-28') as br_tabb) as tab4,(select count(distinct dataclear.cip) as newip from dataclear where dataclear.reportTime = '2022-09-28' and cip not in (select dc2.cip from dataclear as dc2 where dc2.reportTime < '2022-09-28')) as tab5,  (select count(distinct dataclear.uvid) as newcust from dataclear where dataclear.reportTime='2022-09-28' and uvid not in (select dc2.uvid from dataclear as dc2 where dc2.reportTime < '2022-09-28')) as tab6,(select round(avg(atTab.usetime),4) as avgtime from (select max(sstime) - min(sstime) as usetime from dataclear where reportTime='2022-09-28' group by ssid) as atTab) as tab7,(select round(avg(deep),4) as avgdeep from (select count(distinct urlname) as deep from dataclear where reportTime='2022-09-28' group by ssid) as adTab) as tab8;

报错连接拒绝
这是因为DataNode 需要访问 MapReduce JobHistory Server,它的默认端口为0.0.0.0:10020 。

java.io.IOException: java.net.ConnectException: Call From hadoop01/192.168.253.129 to 0.0.0.0:10020 failed on connection exception: java.net.ConnectException: 拒绝连接; For more details see:  http://wiki.apache.org/hadoop/ConnectionRefused

解决

1)在/etc/hadoop/mapred-site.xml配置文件中开启jobhistory

<property>

        <name>mapreduce.jobhistory.address</name>

        <!-- 配置实际的主机名和端口-->

        <value>hadoop01:10020</value>

 </property>

 

2)并增加historyserver的heap 的大小,根据具体情况而定。 

在配置文件${ 
   HADOOP_DIR}/etc/hadoop/mapred-env.sh下:

export HADOOP_JOB_HISTORYSERVER_HEAPSIZE=2000

 

3)开启historyserver

[root@hadoop01 sbin]# mr-jobhistory-daemon.sh start historyserver

运行之后报错

ERROR : Ended Job = job_1494385775332_0823 with exception 'java.io.IOException(java.io.IOException: Unknown Job job_1494385775332_0823
        at org.apache.hadoop.mapreduce.v2.hs.HistoryClientService$HSClientProtocolHandler.verifyAndGetJob(HistoryClientService.java:218)

解决(同时做了内存的扩容)
yarn.app.mapreduce.am.staging-dir:mapreduce中间数据和准备数据的存储临时目录

[root@hadoop01 hadoop]# pwd
/home/presoftware/hadoop-2.7.1/etc/hadoop

[root@hadoop01 hadoop]# vim yarn-site.xml
<property>
                <name>yarn.app.mapreduce.am.staging-dir</name>
                <value>/user</value>
          </property>

结果

hive> select * from tongji;
OK
2022-09-28	11	4	7	0.8571	0	3	107.0	1.0
Time taken: 0.069 seconds, Fetched: 1 row(s)
hive> 

THE END

发表回复