精华内容
下载资源
问答
  • 网站点击流数据分析项目

    万次阅读 多人点赞 2017-08-07 15:05:24
    什么是点击流数据 1.1.1 WEB访问日志 即指用户访问网站时的所有访问、浏览、点击行为数据。比如点击了哪一个链接,在哪个网页停留时间最多,采用了哪个搜索项、总体浏览时间等。而所有这些信息都可被保存在网站...

    什么是点击流数据
    1.1.1 WEB访问日志
    即指用户访问网站时的所有访问、浏览、点击行为数据。比如点击了哪一个链接,在哪个网页停留时间最多,采用了哪个搜索项、总体浏览时间等。而所有这些信息都可被保存在网站日志中。通过分析这些数据,可以获知许多对网站运营至关重要的信息。采集的数据越全面,分析就能越精准。

     日志的生成渠道:
    1)是网站的web服务器所记录的web访问日志;
    2)是通过在页面嵌入自定义的js代码来获取用户的所有访问行为(比如鼠标悬停的位置,点击的页面组件等),然后通过ajax请求到后台记录日志;这种方式所能采集的信息最全面;
    3)通过在页面上埋点1像素的图片,将相关页面访问信息请求到后台记录日志;

     日志数据内容详述:
    在实际操作中,有以下几个方面的数据可以被采集:
    1) 访客的系统属性特征。比如所采用的操作系统、浏览器、域名和访问速度等。
    2) 访问特征。包括停留时间、点击的URL等。
    3) 来源特征。包括网络内容信息类型、内容分类和来访URL等。
    4) 产品特征。包括所访问的产品编号、产品类别、产品颜色、产品价格、产品利润、产品数量和特价等级等。

    以电商某东为例,其点击日志格式如下:
    GET /log.gif?t=item.010001&m=UA-J2011-1&pin=-&uid=1679790178&sid=1679790178|12&v=je=1 sc=24bit sr=1600x900 ul=zhcn cs=GBK dt=180g×3 hn=item.jd.com fl=16.0r0 os=win br=chrome bv=39.0.2171.95 wb=1437269412 xb=1449548587 yb=1456186252 zb=12 cb=4 usc=direct ucp= umd=none uct= ct=1456186505411 lt=0 tad=- sku=1326523 cid1=1316 cid2=1384 cid3=1405 brand=20583 pinid=-&ref=&rm=1456186505411 HTTP/1.1

    1.1.2 点击流数据模型
    点击流概念
    点击流这个概念更注重用户浏览网站的整个流程,网站日志中记录的用户点击就像是图上的“点”,而点击流更像是将这些“点”串起来形成的“线”。也可以把“点”认为是网站的Page,而“线”则是访问网站的Session。所以点击流数据是由网站日志中整理得到的,它可以比网站日志包含更多的信息,从而使基于点击流数据统计得到的结果更加丰富和高效。

    点击的关键度量与指标
    1) 请求数(Hits)-用户点击次数,对服务器资源的请求个数。
    2) 点击数(Clicks)-页面资源的请求数。
    3) 会话数(Sessions)-超过30分钟没有请求,重新开始一次会话
    4) 访问数(Visits)
    5) 唯一访客数(Unique Visitor,UV)
    6) 重复访客数(Repearted Visitors)
    7) 页面浏览量(Page Views,PV)
    用户行为分析
    1) 每次会话PV数
    2) 每日/每小时PV数
    3) 网站访问时长
    4) 离开退出率
    解决方案:
    1. 基于命令行和sql的纯手工分析
    常用的linux命令有:
    Sort、tail、less、uniq、grep、sed、awk等
    如统计日志中访问量最高的前100个ip地址
    Shell命令:
    Cat localhost_access_log.2017-08-05.txt|awk ‘{a[$1]++}END{for(b in a) print b”\t”a[b]}’|sort-k2-r|head –n 100
    点击流模型生成
    点击流数据在具体操作上是由散点状的点击日志数据梳理所得,从而,点击数据在数据建模时应该存在两张模型表(Pageviews和visits):

    1、用于生成点击流的访问日志表
    时间戳 IP地址 Cookie Session 请求URL Referal
    2012-01-01 12:31:12 101.0.0.1 User01 S001 /a/… somesite.com
    2012-01-01 12:31:16 201.0.0.2 User02 S002 /a/… -
    2012-01-01 12:33:06 101.0.0.2 User03 S002 /b/… baidu.com
    2012-01-01 15:16:39 234.0.0.3 User01 S003 /c/… google.com
    2012-01-01 15:17:11 101.0.0.1 User01 S004 /d/… /c/…
    2012-01-01 15:19:23 101.0.0.1 User01 S004 /e/… /d/….

    2、页面点击流模型Pageviews表
    Session userid 时间 访问页面URL 停留时长 第几步
    S001 User01 2012-01-01 12:31:12 /a/…. 30 1
    S002 User02 2012-01-01 12:31:16 /a/…. 10 1
    S002 User02 2012-01-01 12:33:06 /b/…. 110 2
    S002 User02 2012-01-01 12:35:06 /e/…. 30 3

    3、点击流模型Visits表
    Session 起始时间 结束时间 进入页面 离开页面 访问页面数 IP cookie referal
    S001 2012-01-01 12:31:12 2012-01-01 12:31:12 /a/… /a/… 1 101.0.0.1 User01 somesite.com
    S002 2012-01-01 12:31:16 2012-01-01 12:35:06 /a/… /e/… 3 201.0.0.2 User02 -
    S003 2012-01-01 12:35:42 2012-01-01 12:35:42 /c/… /c/… 1 234.0.0.3 User03 baidu.com
    S003 2012-01-01 15:16:39 2012-01-01 15:19:23 /c/… /e/… 3 101.0.0.1 User01 google.com
    …… …… …… …… …… …… …… …… ……

    这就是点击流模型。当WEB日志转化成点击流数据的时候,很多网站分析度量的计算变得简单了,这就是点击流的“魔力”所在。基于点击流数据我们可以统计出许多常见的网站分析度量

    1.2网站流量数据分析的意义
    网站流量统计分析,可以帮助网站管理员、运营人员、推广人员等实时获取网站流量信息,并从流量来源、网站内容、网站访客特性等多方面提供网站分析的数据依据。从而帮助提高网站流量,提升网站用户体验,让访客更多的沉淀下来变成会员或客户,通过更少的投入获取最大化的收入。

    如下表:
    网站的眼睛 网站的神经 网站的大脑
    访问者来自哪里?
    访问者在寻找什么?
    哪些页面最受欢迎?
    访问者从哪里进入?
    网页布局合理吗?
    网站导航清晰吗?
    哪些功能存在问题
    网站内容有效吗
    转化路径靠谱吗? 如何分解目标?
    如何分配广告预算?
    如何衡量产品表现?
    哪些产品需要优化?
    哪些指标需要关注?

    点击流分析的意义可分为两大方面:
    1、技术上
    可以合理修改网站结构及适度分配资源,构建后台服务器群组,比如
    辅助改进网络的拓扑设计,提高性能
    在有高度相关性的节点之间安排快速有效的访问路径
    帮助企业更好地设计网站主页和安排网页内容

    2、业务上
    1) 帮助企业改善市场营销决策,如把广告放在适当的Web页面上。
    2) 优化页面及业务流程设计,提高流量转化率。
    3) 帮助企业更好地根据客户的兴趣来安排内容。
    4) 帮助企业对客户群进行细分,针对不同客户制定个性化的促销策略等。

    终极目标是:改善网站(电商、社交、电影、小说)的运营,获取更高投资回报率(ROI)

    如何进行网站流量分析
    流量分析整体来说是一个内涵非常丰富的体系,其整体过程是一个金字塔结构:

    1.3.1 流量分析模型举例
    通常有以下几大类的分析需求:
    1)网站流量质量分析
    流量对于每个网站来说都是很重要,但流量并不是越多越好,应该更加看重流量的质量,换句话来说就是流量可以为我们带来多少收入。

    2)网站流量多维度细分
    细分是指通过不同维度对指标进行分割,查看同一个指标在不同维度下的表现,进而找出有问题的那部分指标,对这部分指标进行优化。

    3)网站内容及导航分析
    对于所有网站来说,页面都可以被划分为三个类别:
     导航页
     功能页
     内容页

    首页和列表页都是典型的导航页;
    站内搜索页面、注册表单页面和购物车页面都是典型的功能页,
    而产品详情页、新闻和文章页都是典型的内容页。

    比如从内容导航分析中,以下两类行为就是网站运营者不希望看到的行为:

    第一个问题:访问者从导航页进入,在还没有看到内容页面之前就从导航页离开网站,需要分析导航页造成访问者中途离开的原因。
    第二个问题:访问者从导航页进入内容页后,又返回到导航页,说明需要分析内容页的最初设计,并考虑中内容页提供交叉的信息推荐

    4)网站转化及漏斗分析
    所谓转化,即网站业务流程中的一个封闭渠道,引导用户按照流程最终实现业务目标(比如商品成交);而漏斗模型则是指进入渠道的用户在各环节递进过程中逐渐流失的形象描述;
    对于转化渠道,主要进行两部分的分析:
    访问者的流失和迷失

    1、阻力和流失

    造成流失的原因很多,如:
    不恰当的商品或活动推荐
    对支付环节中专业名词的解释、帮助信息等内容不当

    2、迷失

    造成迷失的主要原因是转化流量设计不合理,访问者在特定阶段得不到需要的信息,并且不能根据现有的信息作出决策

    总之,网站流量分析是一门内容非常丰富的学科,本课程中主要关注网站分析过程中的技术运用,更多关于网站流量分析的业务知识可学习推荐资料。
    1.3.2 流量分析常见指标
    课程中涉及的分析指标主要位于以下几大方面:
    1)基础分析(PV,IP,UV)
     趋势分析:根据选定的时段,提供网站流量数据,通过流量趋势变化形态,为您分析网站访客的访问规律、网站发展状况提供参考。
     对比分析:根据选定的两个对比时段,提供网站流量在时间上的纵向对比报表,帮您发现网站发展状况、发展规律、流量变化率等。
     当前在线:提供当前时刻站点上的访客量,以及最近15分钟流量、来源、受访、访客变化情况等,方便用户及时了解当前网站流量状况。
     访问明细:提供最近7日的访客访问记录,可按每个PV或每次访问行为(访客的每次会话)显示,并可按照来源、搜索词等条件进行筛选。 通过访问明细,用户可以详细了解网站流量的累计过程,从而为用户快速找出流量变动原因提供最原始、最准确的依据。

    来源分析
     来源分类:提供不同来源形式(直接输入、搜索引擎、其他外部链接、站内来源)、不同来源项引入流量的比例情况。通过精确的量化数据,帮助用户分析什么类型的来路产生的流量多、效果好,进而合理优化推广方案。
     搜索引擎:提供各搜索引擎以及搜索引擎子产品引入流量的比例情况。从搜索引擎引入流量的的角度,帮助用户了解网站的SEO、SEM效果,从而为制定下一步SEO、SEM计划提供依据。
     搜索词:提供访客通过搜索引擎进入网站所使用的搜索词,以及各搜索词引入流量的特征和分布。帮助用户了解各搜索词引入流量的质量,进而了解访客的兴趣关注点、网站与访客兴趣点的匹配度,为优化SEO方案及SEM提词方案提供详细依据。
     最近7日的访客搜索记录,可按每个PV或每次访问行为(访客的每次会话)显示,并可按照访客类型、地区等条件进行筛选。为您搜索引擎优化提供最详细的原始数据。
     来路域名:提供具体来路域名引入流量的分布情况,并可按“社会化媒体”、“搜索引擎”、“邮箱”等网站类型对来源域名进行分类。 帮助用户了解哪类推广渠道产生的流量多、效果好,进而合理优化网站推广方案。
     来路页面:提供具体来路页面引入流量的分布情况。 尤其对于通过流量置换、包广告位等方式从其他网站引入流量的用户,该功能可以方便、清晰地展现广告引入的流量及效果,为优化推广方案提供依据。
     来源升降榜:提供开通统计后任意两日的TOP10000搜索词、来路域名引入流量的对比情况,并按照变化的剧烈程度提供排行榜。 用户可通过此功能快速找到哪些来路对网站流量的影响比较大,从而及时排查相应来路问题。

    3)受访分析
     受访域名:提供访客对网站中各个域名的访问情况。 一般情况下,网站不同域名提供的产品、内容各有差异,通过此功能用户可以了解不同内容的受欢迎程度以及网站运营成效。
     受访页面:提供访客对网站中各个页面的访问情况。 站内入口页面为访客进入网站时浏览的第一个页面,如果入口页面的跳出率较高则需要关注并优化;站内出口页面为访客访问网站的最后一个页面,对于离开率较高的页面需要关注并优化。
     受访升降榜:提供开通统计后任意两日的TOP10000受访页面的浏览情况对比,并按照变化的剧烈程度提供排行榜。 可通过此功能验证经过改版的页面是否有流量提升或哪些页面有巨大流量波动,从而及时排查相应问题。
     热点图:记录访客在页面上的鼠标点击行为,通过颜色区分不同区域的点击热度;支持将一组页面设置为”关注范围”,并可按来路细分点击热度。 通过访客在页面上的点击量统计,可以了解页面设计是否合理、广告位的安排能否获取更多佣金等。
     用户视点:提供受访页面对页面上链接的其他站内页面的输出流量,并通过输出流量的高低绘制热度图,与热点图不同的是,所有记录都是实际打开了下一页面产生了浏览次数(PV)的数据,而不仅仅是拥有鼠标点击行为。
     访问轨迹:提供观察焦点页面的上下游页面,了解访客从哪些途径进入页面,又流向了哪里。 通过上游页面列表比较出不同流量引入渠道的效果;通过下游页面列表了解用户的浏览习惯,哪些页面元素、内容更吸引访客点击。

    4)访客分析
     地区运营商:提供各地区访客、各网络运营商访客的访问情况分布。 地方网站、下载站等与地域性、网络链路等结合较为紧密的网站,可以参考此功能数据,合理优化推广运营方案。
     终端详情:提供网站访客所使用的浏览终端的配置情况。 参考此数据进行网页设计、开发,可更好地提高网站兼容性,以达到良好的用户交互体验。
     新老访客:当日访客中,历史上第一次访问该网站的访客记为当日新访客;历史上已经访问过该网站的访客记为老访客。 新访客与老访客进入网站的途径和浏览行为往往存在差异。该功能可以辅助分析不同访客的行为习惯,针对不同访客优化网站,例如为制作新手导航提供数据支持等。
     忠诚度:从访客一天内回访网站的次数(日访问频度)与访客上次访问网站的时间两个角度,分析访客对网站的访问粘性、忠诚度、吸引程度。 由于提升网站内容的更新频率、增强用户体验与用户价值可以有更高的忠诚度,因此该功能在网站内容更新及用户体验方面提供了重要参考。

     活跃度:从访客单次访问浏览网站的时间与网页数两个角度,分析访客在网站上的活跃程度。 由于提升网站内容的质量与数量可以获得更高的活跃度,因此该功能是网站内容分析的关键指标之一。

    5)转化路径分析
    转化定义
    ·访客在您的网站完成了某项您期望的活动,记为一次转化,如注册或下载。
    目标示例
    ·获得用户目标:在线注册、创建账号等。
    ·咨询目标:咨询、留言、电话等。
    ·互动目标:视频播放、加入购物车、分享等。
    ·收入目标:在线订单、付款等。
    转化数据的应用
    ·在报告的自定义指标中勾选转化指标,实时掌握网站的推广及运营情况。
    ·结合“全部来源”、“转化路径”、“页面上下游”等报告分析访问漏斗,提高转化率。
    ·对“转化目标”设置价值,预估转化收益,衡量ROI。

    路径分析:根据设置的特定路线,监测某一流程的完成转化情况,算出每步的转换率和流失率数据,如注册流程,购买流程等。

    转化类型:
    1、页面

    2、事件

    2 整体技术流程及架构

    2.1 数据处理流程
    该项目是一个纯粹的数据分析项目,其整体流程基本上就是依据数据的处理流程进行,依此有以下几个大的步骤:
    1) 数据采集
    首先,通过页面嵌入JS代码的方式获取用户访问行为,并发送到web服务的后台记录日志
    然后,将各服务器上生成的点击流日志通过实时或批量的方式汇聚到HDFS文件系统中

    当然,一个综合分析系统,数据源可能不仅包含点击流数据,还有数据库中的业务数据(如用户信息、商品信息、订单信息等)及对分析有益的外部数据。

    2) 数据预处理
    通过mapreduce程序对采集到的点击流数据进行预处理,比如清洗,格式整理,滤除脏数据等

    3) 数据入库
    将预处理之后的数据导入到HIVE仓库中相应的库和表中

    4) 数据分析
    项目的核心内容,即根据需求开发ETL分析语句,得出各种统计结果

    5) 数据展现
    将分析所得数据进行可视化
    2.2 项目结构
    由于本项目是一个纯粹数据分析项目,其整体结构亦跟分析流程匹配,并没有特别复杂的结构,如下图:
    这里写图片描述
    模块开发——数据采集
    3.1 需求
    数据采集的需求广义上来说分为两大部分。
    1)是在页面采集用户的访问行为,具体开发工作:
    1、开发页面埋点js,采集用户访问行为
    2、后台接受页面js请求记录日志
    此部分工作也可以归属为“数据源”,其开发工作通常由web开发团队负责

    2)是从web服务器上汇聚日志到HDFS,是数据分析系统的数据采集,此部分工作由数据分析平台建设团队负责,具体的技术实现有很多方式:
     Shell脚本
    优点:轻量级,开发简单
    缺点:对日志采集过程中的容错处理不便控制
     Java采集程序
    优点:可对采集过程实现精细控制
    缺点:开发工作量大
     Flume日志采集框架
    成熟的开源日志采集系统,且本身就是hadoop生态体系中的一员,与hadoop体系中的各种框架组件具有天生的亲和力,可扩展性强

    3.2 技术选型
    在点击流日志分析这种场景中,对数据采集部分的可靠性、容错能力要求通常不会非常严苛,因此使用通用的flume日志采集框架完全可以满足需求。
    本项目即使用flume来实现日志采集。

    3.3 Flume日志采集系统搭建
    1、数据源信息
    本项目分析的数据用nginx服务器所生成的流量日志,存放在各台nginx服务器上,如:
    /var/log/httpd/access_log.2015-11-10-13-00.log
    /var/log/httpd/access_log.2015-11-10-14-00.log
    /var/log/httpd/access_log.2015-11-10-15-00.log
    /var/log/httpd/access_log.2015-11-10-16-00.log

    2、数据内容样例
    数据的具体内容在采集阶段其实不用太关心。
    58.215.204.118 - - [18/Sep/2013:06:51:35 +0000] “GET /wp-includes/js/jquery/jquery.js?ver=1.10.2 HTTP/1.1” 304 0 “http://blog.fens.me/nodejs-socketio-chat/” “Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0”
    字段解析:
    1、访客ip地址: 58.215.204.118
    2、访客用户信息: - -
    3、请求时间:[18/Sep/2013:06:51:35 +0000]
    4、请求方式:GET
    5、请求的url:/wp-includes/js/jquery/jquery.js?ver=1.10.2
    6、请求所用协议:HTTP/1.1
    7、响应码:304
    8、返回的数据流量:0
    9、访客的来源url:http://blog.fens.me/nodejs-socketio-chat/
    10、访客所用浏览器:Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0

    3、日志文件生成规律

    基本规律为:
    当前正在写的文件为access_log;
    文件体积达到64M,或时间间隔达到60分钟,即滚动重命名切换成历史日志文件;
    形如: access_log.2015-11-10-13-00.log

    当然,每个公司的web服务器日志策略不同,可在web程序的log4j.properties中定义,如下:
    log4j.appender.logDailyFile = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.logDailyFile.layout = org.apache.log4j.PatternLayout
    log4j.appender.logDailyFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
    log4j.appender.logDailyFile.Threshold = DEBUG
    log4j.appender.logDailyFile.ImmediateFlush = TRUE
    log4j.appender.logDailyFile.Append = TRUE
    log4j.appender.logDailyFile.File = /var/logs/access_log
    log4j.appender.logDailyFile.DatePattern = ‘.’yyyy-MM-dd-HH-mm’.log’
    log4j.appender.logDailyFile.Encoding = UTF-8

    4、Flume采集实现
    Flume采集系统的搭建相对简单:
    1、在个web服务器上部署agent节点,修改配置文件
    2、启动agent节点,将采集到的数据汇聚到指定的HDFS目录中

     版本选择:apache-flume-1.6.0
     采集规则设计:
    1、 采集源:nginx服务器日志目录
    2、 存放地:hdfs目录/home/hadoop/weblogs/
     采集规则配置详情
    agent1.sources = source1
    agent1.sinks = sink1
    agent1.channels = channel1

    Describe/configure spooldir source1

    agent1.sources.source1.type = spooldir

    agent1.sources.source1.spoolDir = /var/logs/nginx/

    agent1.sources.source1.fileHeader = false

    Describe/configure tail -F source1

    使用exec作为数据源source组件

    agent1.sources.source1.type = exec

    使用tail -F命令实时收集新产生的日志数据

    agent1.sources.source1.command = tail -F /var/logs/nginx/access_log
    agent1.sources.source1.channels = channel1

    configure host for source

    配置一个拦截器插件

    agent1.sources.source1.interceptors = i1
    agent1.sources.source1.interceptors.i1.type = host

    使用拦截器插件获取agent所在服务器的主机名

    agent1.sources.source1.interceptors.i1.hostHeader = hostname

    配置sink组件为hdfs

    agent1.sinks.sink1.type = hdfs

    a1.sinks.k1.channel = c1

    agent1.sinks.sink1.hdfs.path=hdfs://hdp-node-01:9000/weblog/flume-collection/%y-%m-%d/%H%M%S

    指定文件sink到hdfs上的路径

    agent1.sinks.sink1.hdfs.path=
    hdfs://hdp-node-01:9000/weblog/flume-collection/%y-%m-%d/%H-%M_%hostname

    指定文件名前缀

    agent1.sinks.sink1.hdfs.filePrefix = access_log
    agent1.sinks.sink1.hdfs.maxOpenFiles = 5000

    指定每批下沉数据的记录条数

    agent1.sinks.sink1.hdfs.batchSize= 100
    agent1.sinks.sink1.hdfs.fileType = DataStream
    agent1.sinks.sink1.hdfs.writeFormat =Text

    指定下沉文件按1G大小滚动

    agent1.sinks.sink1.hdfs.rollSize = 1024*1024*1024

    指定下沉文件按1000000条数滚动

    agent1.sinks.sink1.hdfs.rollCount = 1000000

    指定下沉文件按30分钟滚动

    agent1.sinks.sink1.hdfs.rollInterval = 30

    agent1.sinks.sink1.hdfs.round = true

    agent1.sinks.sink1.hdfs.roundValue = 10

    agent1.sinks.sink1.hdfs.roundUnit = minute

    agent1.sinks.sink1.hdfs.useLocalTimeStamp = true

    Use a channel which buffers events in memory

    使用memory类型channel

    agent1.channels.channel1.type = memory
    agent1.channels.channel1.keep-alive = 120
    agent1.channels.channel1.capacity = 500000
    agent1.channels.channel1.transactionCapacity = 600

    Bind the source and sink to the channel

    agent1.sources.source1.channels = channel1
    agent1.sinks.sink1.channel = channel1

    启动采集
    在部署了flume的nginx服务器上,启动flume的agent,命令如下:
    bin/flume-ng agent –conf ./conf -f ./conf/weblog.properties.2 -n agent

    注意:启动命令中的 -n 参数要给配置文件中配置的agent名称

    4 模块开发——数据预处理
    4.1 主要目的:
    过滤“不合规”数据
    格式转换和规整
    根据后续的统计需求,过滤分离出各种不同主题的基础数据

    4.2 实现方式:
    开发一个mr程序WeblogPreProcess(内容太长,见工程代码)
    public class WeblogPreProcess {
    static class WeblogPreProcessMapper extends Mapper

    ##

    mm string 分区字段–月
    dd string 分区字段–日

    5.2 维度表

    时间维度 v_year_month_date
    year
    month
    day
    hour
    minute

    访客地域维度t_dim_area
    北京
    上海
    广州
    深圳
    河北
    河南

    终端类型维度t_dim_termination
    uc
    firefox
    chrome
    safari
    ios
    android

    网站栏目维度 t_dim_section
    跳蚤市场
    房租信息
    休闲娱乐
    建材装修
    本地服务
    人才市场

    6 模块开发——ETL
    该项目的数据分析过程在hadoop集群上实现,主要应用hive数据仓库工具,因此,采集并经过预处理后的数据,需要加载到hive数据仓库中,以进行后续的挖掘分析。
    6.1创建原始数据表
    –在hive仓库中建贴源数据表
    drop table if exists ods_weblog_origin;
    create table ods_weblog_origin(
    valid string,
    remote_addr string,
    remote_user string,
    time_local string,
    request string,
    status string,
    body_bytes_sent string,
    http_referer string,
    http_user_agent string)
    partitioned by (datestr string)
    row format delimited
    fields terminated by ‘\001’;

    点击流模型pageviews表
    drop table if exists ods_click_pageviews;
    create table ods_click_pageviews(
    Session string,
    remote_addr string,
    time_local string,
    request string,
    visit_step string,
    page_staylong string,
    http_referer string,
    http_user_agent string,
    body_bytes_sent string,
    status string)
    partitioned by (datestr string)
    row format delimited
    fields terminated by ‘\001’;

    时间维表创建
    drop table dim_time if exists ods_click_pageviews;
    create table dim_time(
    year string,
    month string,
    day string,
    hour string)
    row format delimited
    fields terminated by ‘,’;

    6.2导入数据
    导入清洗结果数据到贴源数据表ods_weblog_origin
    load data inpath ‘/weblog/preprocessed/16-02-24-16/’ overwrite into table ods_weblog_origin partition(datestr=’2013-09-18’);

    0: jdbc:hive2://localhost:10000> show partitions ods_weblog_origin;
    +——————-+–+
    | partition |
    +——————-+–+
    | timestr=20151203 |
    +——————-+–+

    0: jdbc:hive2://localhost:10000> select count(*) from ods_origin_weblog;
    +——–+–+
    | _c0 |
    +——–+–+
    | 11347 |
    +——–+–+

    导入点击流模型pageviews数据到ods_click_pageviews表
    0: jdbc:hive2://hdp-node-01:10000> load data inpath ‘/weblog/clickstream/pageviews’ overwrite into table ods_click_pageviews partition(datestr=’2013-09-18’);

    0: jdbc:hive2://hdp-node-01:10000> select count(1) from ods_click_pageviews;
    +——+–+
    | _c0 |
    +——+–+
    | 66 |
    +——+–+

    导入点击流模型visit数据到ods_click_visit表

    导入时间维表:
    load data inpath ‘/dim_time.txt’ into table dim_time;

    6.3 生成ODS层明细宽表
    6.3.1 需求概述
    整个数据分析的过程是按照数据仓库的层次分层进行的,总体来说,是从ODS原始数据中整理出一些中间表(比如,为后续分析方便,将原始数据中的时间、url等非结构化数据作结构化抽取,将各种字段信息进行细化,形成明细表),然后再在中间表的基础之上统计出各种指标数据

    6.3.2 ETL实现
    建表——明细表 (源:ods_weblog_origin) (目标:ods_weblog_detail)
    drop table ods_weblog_detail;
    create table ods_weblog_detail(
    valid string, –有效标识
    remote_addr string, –来源IP
    remote_user string, –用户标识
    time_local string, –访问完整时间
    daystr string, –访问日期
    timestr string, –访问时间
    month string, –访问月
    day string, –访问日
    hour string, –访问时
    request string, –请求的url
    status string, –响应码
    body_bytes_sent string, –传输字节数
    http_referer string, –来源url
    ref_host string, –来源的host
    ref_path string, –来源的路径
    ref_query string, –来源参数query
    ref_query_id string, –来源参数query的值
    http_user_agent string –客户终端标识
    )
    partitioned by(datestr string);

    –抽取refer_url到中间表 “t_ods_tmp_referurl”
    –将来访url分离出host path query query id
    drop table if exists t_ods_tmp_referurl;
    create table t_ ods _tmp_referurl as
    SELECT a.,b.
    FROM ods_origin_weblog a LATERAL VIEW parse_url_tuple(regexp_replace(http_referer, “\”“, “”), ‘HOST’, ‘PATH’,’QUERY’, ‘QUERY:id’) b as host, path, query, query_id;

    –抽取转换time_local字段到中间表明细表 ”t_ ods _detail”
    drop table if exists t_ods_tmp_detail;
    create table t_ods_tmp_detail as
    select b.*,substring(time_local,0,10) as daystr,
    substring(time_local,11) as tmstr,
    substring(time_local,5,2) as month,
    substring(time_local,8,2) as day,
    substring(time_local,11,2) as hour
    From t_ ods _tmp_referurl b;

    以上语句可以改写成:
    insert into table zs.ods_weblog_detail partition(datestr=’$day_01’)
    select c.valid,c.remote_addr,c.remote_user,c.time_local,
    substring(c.time_local,0,10) as daystr,
    substring(c.time_local,12) as tmstr,
    substring(c.time_local,6,2) as month,
    substring(c.time_local,9,2) as day,
    substring(c.time_local,11,3) as hour,
    c.request,c.status,c.body_bytes_sent,c.http_referer,c.ref_host,c.ref_path,c.ref_query,c.ref_query_id,c.http_user_agent
    from
    (SELECT
    a.valid,a.remote_addr,a.remote_user,a.time_local,
    a.request,a.status,a.body_bytes_sent,a.http_referer,a.http_user_agent,b.ref_host,b.ref_path,b.ref_query,b.ref_query_id
    FROM zs.ods_weblog_origin a LATERAL VIEW parse_url_tuple(regexp_replace(http_referer, “\”“, “”), ‘HOST’, ‘PATH’,’QUERY’, ‘QUERY:id’) b as ref_host, ref_path, ref_query, ref_query_id) c

    0: jdbc:hive2://localhost:10000> show partitions ods_weblog_detail;
    +———————+–+
    | partition |
    +———————+–+
    | dd=18%2FSep%2F2013 |
    +———————+–+
    1 row selected (0.134 seconds)

    7 模块开发——统计分析
    注:每一种统计指标都可以跟各维度表进行叉乘,从而得出各个维度的统计结果
    篇幅限制,叉乘的代码及注释信息详见项目工程代码文件
    为了在前端展示时速度更快,每一个指标都事先算出各维度结果存入mysql

    提前准备好维表数据,在hive仓库中创建相应维表,如:
    时间维表:
    create table v_time(year string,month string,day string,hour string)
    row format delimited
    fields terminated by ‘,’;

    load data local inpath ‘/home/hadoop/v_time.txt’ into table v_time;

    在实际生产中,究竟需要哪些统计指标通常由相关数据需求部门人员提出,而且会不断有新的统计需求产生,以下为网站流量分析中的一些典型指标示例。
    1. PV统计
    1.1 多维度统计PV总量
    1. 时间维度
    –计算指定的某个小时pvs
    select count(*),month,day,hour from dw_click.ods_weblog_detail group by month,day,hour;

    –计算该处理批次(一天)中的各小时pvs
    drop table dw_pvs_hour;
    create table dw_pvs_hour(month string,day string,hour string,pvs bigint) partitioned by(datestr string);

    insert into table dw_pvs_hour partition(datestr=’2016-03-18’)
    select a.month as month,a.day as day,a.hour as hour,count(1) as pvs from ods_weblog_detail a
    where a.datestr=’2016-03-18’ group by a.month,a.day,a.hour;

    或者用时间维表关联

    维度:日
    drop table dw_pvs_day;
    create table dw_pvs_day(pvs bigint,month string,day string);

    insert into table dw_pvs_day
    select count(1) as pvs,a.month as month,a.day as day from dim_time a
    join ods_weblog_detail b
    on b.dd=’18/Sep/2013’ and a.month=b.month and a.day=b.day
    group by a.month,a.day;

    –或者,从之前算好的小时结果中统计
    Insert into table dw_pvs_day
    Select sum(pvs) as pvs,month,day from dw_pvs_hour group by month,day having day=’18’;

    结果如下:

    维度:月
    drop table t_display_pv_month;
    create table t_display_pv_month (pvs bigint,month string);
    insert into table t_display_pv_month
    select count(*) as pvs,a.month from t_dim_time a
    join t_ods_detail_prt b on a.month=b.month group by a.month;

    1. 按终端维度统计pv总量
      注:探索数据中的终端类型
      select distinct(http_user_agent) from ods_weblog_detail where http_user_agent like ‘%Mozilla%’ limit 200;

    终端维度:uc
    drop table t_display_pv_terminal_uc;
    create table t_display_pv_ terminal_uc (pvs bigint,mm string,dd string,hh string);

    终端维度:chrome
    drop table t_display_pv_terminal_chrome;
    create table t_display_pv_ terminal_ chrome (pvs bigint,mm string,dd string,hh string);

    终端维度:safari
    drop table t_display_pv_terminal_safari;
    create table t_display_pv_ terminal_ safari (pvs bigint,mm string,dd string,hh string);

    1. 按栏目维度统计pv总量
      栏目维度:job
      栏目维度:news
      栏目维度:bargin
      栏目维度:lane

    1.2 人均浏览页数
    需求描述:比如,今日所有来访者,平均请求的页面数

    –总页面请求数/去重总人数
    drop table dw_avgpv_user_d;
    create table dw_avgpv_user_d(
    day string,
    avgpv string);

    insert into table dw_avgpv_user_d
    select ‘2013-09-18’,sum(b.pvs)/count(b.remote_addr) from
    (select remote_addr,count(1) as pvs from ods_weblog_detail where datestr=’2013-09-18’ group by remote_addr) b;

    1.3 按referer维度统计pv总量
    需求:按照来源及时间维度统计PVS,并按照PV大小倒序排序

    – 按照小时粒度统计,查询结果存入:( “dw_pvs_referer_h” )
    drop table dw_pvs_referer_h;
    create table dw_pvs_referer_h(referer_url string,referer_host string,month string,day string,hour string,pv_referer_cnt bigint) partitioned by(datestr string);

    insert into table dw_pvs_referer_h partition(datestr=’2016-03-18’)
    select http_referer,ref_host,month,day,hour,count(1) as pv_referer_cnt
    from ods_weblog_detail
    group by http_referer,ref_host,month,day,hour
    having ref_host is not null
    order by hour asc,day asc,month asc,pv_referer_cnt desc;

    按天粒度统计各来访域名的访问次数并排序
    drop table dw_ref_host_visit_cnts_h;
    create table dw_ref_host_visit_cnts_h(ref_host string,month string,day string,hour string,ref_host_cnts bigint) partitioned by(datestr string);

    insert into table dw_ref_host_visit_cnts_h partition(datestr=’2016-03-18’)
    select ref_host,month,day,hour,count(1) as ref_host_cnts
    from ods_weblog_detail
    group by ref_host,month,day,hour
    having ref_host is not null
    order by hour asc,day asc,month asc,ref_host_cnts desc;
    注:还可以按来源地域维度、访客终端维度等计算

    1.4 统计pv总量最大的来源TOPN
    需求描述:按照时间维度,比如,统计一天内产生最多pvs的来源topN

    需要用到row_number函数
    以下语句对每个小时内的来访host次数倒序排序标号,
    select ref_host,ref_host_cnts,concat(month,hour,day),
    row_number() over (partition by concat(month,hour,day) order by ref_host_cnts desc) as od
    from dw_ref_host_visit_cnts_h
    效果如下:

    根据上述row_number的功能,可编写Hql取各小时的ref_host访问次数topn
    drop table dw_pvs_refhost_topn_h;
    create table dw_pvs_refhost_topn_h(
    hour string,
    toporder string,
    ref_host string,
    ref_host_cnts string
    ) partitioned by(datestr string);

    insert into table zs.dw_pvs_refhost_topn_h partition(datestr=’2016-03-18’)
    select t.hour,t.od,t.ref_host,t.ref_host_cnts from
    (select ref_host,ref_host_cnts,concat(month,day,hour) as hour,
    row_number() over (partition by concat(month,day,hour) order by ref_host_cnts desc) as od
    from zs.dw_ref_host_visit_cnts_h) t where od<=3;

    结果如下:

    注:还可以按来源地域维度、访客终端维度等计算

    1. 受访分析
      统计每日最热门的页面top10
      drop table dw_pvs_d;
      create table dw_pvs_d(day string,url string,pvs string);

    insert into table dw_pvs_d
    select ‘2013-09-18’,a.request,a.request_counts from
    (select request as request,count(request) as request_counts from ods_weblog_detail where datestr=’2013-09-18’ group by request having request is not null) a
    order by a.request_counts desc limit 10;

    结果如下:

    注:还可继续得出各维度交叉结果

    1. 访客分析
      3.1 独立访客
      需求描述:按照时间维度比如小时来统计独立访客及其产生的pvCnts
      对于独立访客的识别,如果在原始日志中有用户标识,则根据用户标识即很好实现;
      此处,由于原始日志中并没有用户标识,以访客IP来模拟,技术上是一样的,只是精确度相对较低

    时间维度:时
    drop table dw_user_dstc_ip_h;
    create table dw_user_dstc_ip_h(
    remote_addr string,
    pvs bigint,
    hour string);

    insert into table dw_user_dstc_ip_h
    select remote_addr,count(1) as pvs,concat(month,day,hour) as hour
    from ods_weblog_detail
    Where datestr=’2013-09-18’
    group by concat(month,day,hour),remote_addr;

    在此结果表之上,可以进一步统计出,每小时独立访客总数,每小时请求次数topn访客等
    如每小时独立访客总数:
    select count(1) as dstc_ip_cnts,hour from dw_user_dstc_ip_h group by hour;

    练习:
    统计每小时请求次数topn的独立访客
    时间维度:月
    select remote_addr,count(1) as counts,month
    from ods_weblog_detail
    group by month,remote_addr;

    时间维度:日
    select remote_addr,count(1) as counts,concat(month,day) as day
    from ods_weblog_detail
    Where dd=’18/Sep/2013’
    group by concat(month,day),remote_addr;

    注:还可以按来源地域维度、访客终端维度等计算

    3.2 每日新访客
    需求描述:将每天的新访客统计出来
    实现思路:创建一个去重访客累积表,然后将每日访客对比累积表

    时间维度:日
    –历日去重访客累积表
    drop table dw_user_dsct_history;
    create table dw_user_dsct_history(
    day string,
    ip string
    )
    partitioned by(datestr string);

    –每日新用户追加到累计表
    drop table dw_user_dsct_history;
    create table dw_user_dsct_history(
    day string,
    ip string
    )
    partitioned by(datestr string);

    –每日新用户追加到累计表
    insert into table dw_user_dsct_history partition(datestr=’2013-09-19’)
    select tmp.day as day,tmp.today_addr as new_ip from
    (
    select today.day as day,today.remote_addr as today_addr,old.ip as old_addr
    from
    (select distinct remote_addr as remote_addr,”2013-09-19” as day from ods_weblog_detail where datestr=”2013-09-19”) today
    left outer join
    dw_user_dsct_history old
    on today.remote_addr=old.ip
    ) tmp
    where tmp.old_addr is null;

    验证:
    select count(distinct remote_addr) from ods_weblog_detail;
    – 1005

    select count(1) from dw_user_dsct_history where prtflag_day=’18/Sep/2013’;
    –845

    select count(1) from dw_user_dsct_history where prtflag_day=’19/Sep/2013’;
    –160

    时间维度:月
    类似日粒度算法

    注:还可以按来源地域维度、访客终端维度等计算

    1. Visit分析(点击流模型)
      4.2 回头/单次访客统计
      需求描述:查询今日所有回头访客及其访问次数

    实现思路:上表中出现次数>1的访客,即回头访客;反之,则为单次访客

    drop table dw_user_returning;
    create table dw_user_returning(
    day string,
    remote_addr string,
    acc_cnt string)
    partitioned by (datestr string);

    insert overwrite table dw_user_returning partition(datestr=’2013-09-18’)

    select tmp.day,tmp.remote_addr,tmp.acc_cnt
    from
    (select ‘2013-09-18’ as day,remote_addr,count(session) as acc_cnt from click_stream_visit group by remote_addr) tmp
    where tmp.acc_cnt>1;

    4.3 人均访问频次
    需求:统计出每天所有用户访问网站的平均次数(visit)
    总visit数/去重总用户数
    select sum(pagevisits)/count(distinct remote_addr) from click_stream_visit partition(datestr=’2013-09-18’);

    1. Visit分析另一种实现方式
      5.1 mr程序识别出访客的每次访问
      a.) 首先开发MAPREDUCE程序:UserStayTime
      注:代码略长,见项目工程代码

    b.) 提交MAPREDUCE程序进行运算
    [hadoop@hdp-node-01 ~]$ hadoop jar weblog.jar cn.itcast.bigdata.hive.mr.UserStayTime /weblog/input /weblog/stayout4
    –导入hive表(“t_display_access_info”)中
    drop table ods_access_info;
    create table ods_access_info(remote_addr string,firt_req_time string,last_req_time string,stay_long string)
    partitioned by(prtflag_day string)
    row format delimited
    fields terminated by ‘\t’;

    load data inpath ‘/weblog/stayout4’ into table ods_access_info partition(prtflag_day=’18/Sep/2013’);
    创建表时stay_long使用的string类型,但是在后续过程中发现还是用bigint更好,进行表修改
    alter table ods_access_info change column stay_long stay_long bigint;

    5.2 将mr结果导入访客访问信息表 “t_display_access_info”
    由于有一些访问记录是单条记录,mr程序处理处的结果给的时长是0,所以考虑给单次请求的停留时间一个默认市场30秒
    drop table dw_access_info;
    create table dw_access_info(remote_addr string,firt_req_time string,last_req_time string,stay_long string)
    partitioned by(prtflag_day string);

    insert into table dw_access_info partition(prtflag_day=’19/Sep/2013’)
    select remote_addr,firt_req_time,last_req_time,
    case stay_long
    when 0 then 30000
    else stay_long
    end as stay_long
    from ods_access_info
    where prtflag_day=’18/Sep/2013’;

    在访问信息表的基础之上,可以实现更多指标统计,如:
    统计所有用户停留时间平均值,观察用户在站点停留时长的变化走势
    select prtflag_day as dt,avg(stay_long) as avg_staylong
    from dw_access_info group by prtflag_day;

    5.3 回头/单次访客统计
    注:从上一步骤得到的访问信息统计表“dw_access_info”中查询

    –回头访客访问信息表 “dw_access_info_htip”
    drop table dw_access_info_htip;
    create table dw_access_info_htip(remote_addr string, firt_req_time string, last_req_time string, stay_long string,acc_counts string)
    partitioned by(prtflag_day string);

    insert into table dw_access_info_htip partition(prtflag_day=’18/Sep/2013’)
    select b.remote_addr,b.firt_req_time,b.last_req_time,b.stay_long,a.acc_counts from
    (select remote_addr,count(remote_addr) as acc_counts from dw_access_info where prtflag_day=’18/Sep/2013’ group by remote_addr having acc_counts>1) a
    join
    dw_access_info b
    on a.remote_addr = b.remote_addr;

    –单次访客访问信息表 “dw_access_info_dcip”
    drop table dw_access_info_dcip;
    create table dw_access_info_dcip(remote_addr string, firt_req_time string, last_req_time string, stay_long string,acc_counts string)
    partitioned by(prtflag_day string);

    insert into table dw_access_dcip partition(prtflag_day=’18/Sep/2013’)
    select b.remote_addr,b.firt_req_time,b.last_req_time,b.stay_long,a.acc_counts from
    (select remote_addr,count(remote_addr) as acc_counts from dw_access_info where prtflag_day=’18/Sep/2013’ group by remote_addr having acc_counts<2) a
    join
    dw_access_info b
    on a.remote_addr = b.remote_addr;

    在回头/单词访客信息表的基础之上,可以实现更多统计指标,如:

    –当日回头客占比
    drop table dw_htpercent_d;
    create table dw_htpercent_d(day string,ht_percent float);

    Insert into table dw_htpercent_d
    select ‘18/Sep/2013’,(tmp_ht.ht/tmp_all.amount)*100 from
    (select count( distinct a.remote_addr) as ht from dw_access_info_htip a where prtflag_day=’18/Sep/2013’) tmp_ht
    Join
    (select count(distinct b.remote_addr) as amount from dw_access_info b where prtflag_day=’18/Sep/2013’) tmp_all;

    5.4 人均访问频度
    –总访问次数/去重总人数,从访客次数汇总表中查询
    select avg(user_times.counts) as user_access_freq
    from
    (select remote_addr,counts from t_display_htip
    union all
    select remote_addr,counts from t_display_access_dcip) user_times;

    –或直接从 访问信息表 t_display_access_info 中查询
    select avg(a.acc_cts) from
    (select remote_addr,count(*) as acc_cts from dw_access_info group by remote_addr) a;

    6.关键路径转化率分析——漏斗模型
    转化:在一条指定的业务流程中,各个步骤的完成人数及相对上一个步骤的百分比
    6.1 需求分析

    6.2 模型设计
    定义好业务流程中的页面标识,下例中的步骤为:
    Step1、 /item%
    Step2、 /category
    Step3、 /order
    Step4、 /index

    6.3 开发实现
    分步骤开发:

    1、查询每一个步骤的总访问人数
    create table route_numbs as
    select ‘step1’ as step,count(distinct remote_addr) as numbs from ods_click_pageviews where request like ‘/item%’
    union
    select ‘step2’ as step,count(distinct remote_addr) as numbs from ods_click_pageviews where request like ‘/category%’
    union
    select ‘step3’ as step,count(distinct remote_addr) as numbs from ods_click_pageviews where request like ‘/order%’
    union
    select ‘step4’ as step,count(distinct remote_addr) as numbs from ods_click_pageviews where request like ‘/index%’;

    2、查询每一步骤相对于路径起点人数的比例

    思路:利用join
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs from route_num rn
    inner join
    route_num rr

    select tmp.rnstep,tmp.rnnumbs/tmp.rrnumbs as ratio
    from
    (
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs from route_num rn
    inner join
    route_num rr) tmp
    where tmp.rrstep=’step1’;

    3、查询每一步骤相对于上一步骤的漏出率
    select tmp.rrstep as rrstep,tmp.rrnumbs/tmp.rnnumbs as ration
    from
    (
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs from route_num rn
    inner join
    route_num rr) tmp
    where cast(substr(tmp.rnstep,5,1) as int)=cast(substr(tmp.rrstep,5,1) as int)-1

    4、汇总以上两种指标
    select abs.step,abs.numbs,abs.ratio as abs_ratio,rel.ratio as rel_ratio
    from
    (
    select tmp.rnstep as step,tmp.rnnumbs as numbs,tmp.rnnumbs/tmp.rrnumbs as ratio
    from
    (
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs from route_num rn
    inner join
    route_num rr) tmp
    where tmp.rrstep=’step1’
    ) abs
    left outer join
    (
    select tmp.rrstep as step,tmp.rrnumbs/tmp.rnnumbs as ratio
    from
    (
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs from route_num rn
    inner join
    route_num rr) tmp
    where cast(substr(tmp.rnstep,5,1) as int)=cast(substr(tmp.rrstep,5,1) as int)-1
    ) rel
    on abs.step=rel.step

    8 模块开发——结果导出
    报表统计结果,由sqoop从hive表中导出,示例如下,详见工程代码
    sqoop export \
    –connect jdbc:mysql://hdp-node-01:3306/webdb –username root –password root \
    –table click_stream_visit \
    –export-dir /user/hive/warehouse/dw_click.db/click_stream_visit/datestr=2013-09-18 \
    –input-fields-terminated-by ‘\001’

    9 模块开发——工作流调度
    注:将整个项目的数据处理过程,从数据采集到数据分析,再到结果数据的导出,一系列的任务分割成若干个oozie的工作流,并用coordinator进行协调

    工作流定义示例
    Ooize配置片段示例,详见项目工程
    1、日志预处理mr程序工作流定义




    jobTracker {nameNode}





    mapreduce.job.map.class
    cn.itcast.bigdata.hive.mr.WeblogPreProcess$WeblogPreProcessMapper


    mapreduce.job.output.key.class
    org.apache.hadoop.io.Text


    mapreduce.job.output.value.class
    org.apache.hadoop.io.NullWritable


    mapreduce.input.fileinputformat.inputdir
    inpathmapreduce.output.fileoutputformat.outputdir {outpath}


    mapred.mapper.new-api
    true


    mapred.reducer.new-api
    true




    2、数据加载etl工作流定义:



    jobTracker {nameNode}


    mapred.job.queue.name
    ${queueName}


    jdbc:hive2://hdp-node-01:10000

    input=/weblog/outpre2




    Hive2 (Beeline) action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]


    3、数据加载工作流所用hive脚本:
    create database if not exists dw_weblog;
    use dw_weblog;
    drop table if exists t_orgin_weblog;
    create table t_orgin_weblog(valid string,remote_addr string,
    remote_user string,
    time_local string,
    request string,
    status string,
    body_bytes_sent string,
    http_referer string,
    http_user_agent string)
    row format delimited
    fields terminated by ‘\001’;
    load data inpath ‘/weblog/preout’ overwrite into table t_orgin_weblog;

    drop table if exists t_ods_detail_tmp_referurl;
    create table t_ods_detail_tmp_referurl as
    SELECT a.,b.
    FROM t_orgin_weblog a
    LATERAL VIEW parse_url_tuple(regexp_replace(http_referer, “\”“, “”), ‘HOST’, ‘PATH’,’QUERY’, ‘QUERY:id’) b as host, path, query, query_id;

    drop table if exists t_ods_detail;
    create table t_ods_detail as
    select b.*,substring(time_local,0,11) as daystr,
    substring(time_local,13) as tmstr,
    substring(time_local,4,3) as month,
    substring(time_local,0,2) as day,
    substring(time_local,13,2) as hour
    from t_ods_detail_tmp_referurl b;

    drop table t_ods_detail_prt;
    create table t_ods_detail_prt(
    valid string,
    remote_addr string,
    remote_user string,
    time_local string,
    request string,
    status string,
    body_bytes_sent string,
    http_referer string,
    http_user_agent string,
    host string,
    path string,
    query string,
    query_id string,
    daystr string,
    tmstr string,
    month string,
    day string,
    hour string)
    partitioned by (mm string,dd string);

    insert into table t_ods_detail_prt partition(mm=’Sep’,dd=’18’)
    select * from t_ods_detail where daystr=’18/Sep/2013’;
    insert into table t_ods_detail_prt partition(mm=’Sep’,dd=’19’)
    select * from t_ods_detail where daystr=’19/Sep/2013’;

    更多工作流及hql脚本定义详见项目工程

    工作流单元测试
    1、工作流定义配置上传
    [hadoop@hdp-node-01 wf-oozie] hadoopfsputhive2etl/user/hadoop/oozie/myapps/[hadoop@hdpnode01wfoozie] hadoop fs -put hive2-dw /user/hadoop/oozie/myapps/
    [hadoop@hdp-node-01 wf-oozie] lltotal12drwxrwxrx.2hadoophadoop4096Nov2316:32hive2dwdrwxrwxrx.2hadoophadoop4096Nov2316:32hive2etldrwxrwxrx.3hadoophadoop4096Nov2311:24weblog[hadoop@hdpnode01wfoozie] export OOZIE_URL=http://localhost:11000/oozie

    2、工作流单元提交启动
    oozie job -D inpath=/weblog/input -D outpath=/weblog/outpre -config weblog/job.properties -run

    启动etl的hive工作流
    oozie job -config hive2-etl/job.properties -run
    启动pvs统计的hive工作流
    oozie job -config hive2-dw/job.properties -run

    3、工作流coordinator配置(片段)
    多个工作流job用coordinator组织协调:
    [hadoop@hdp-node-01 hive2-etl]$ ll
    total 28
    -rw-rw-r–. 1 hadoop hadoop 265 Nov 13 16:39 config-default.xml
    -rw-rw-r–. 1 hadoop hadoop 512 Nov 26 16:43 coordinator.xml
    -rw-rw-r–. 1 hadoop hadoop 382 Nov 26 16:49 job.properties
    drwxrwxr-x. 2 hadoop hadoop 4096 Nov 27 11:26 lib
    -rw-rw-r–. 1 hadoop hadoop 1910 Nov 23 17:49 script.q
    -rw-rw-r–. 1 hadoop hadoop 687 Nov 23 16:32 workflow.xml

     config-default.xml


    jobTracker
    hdp-node-01:8032


    nameNode
    hdfs://hdp-node-01:9000


    queueName
    default

     job.properties
    user.name=hadoop
    oozie.use.system.libpath=true
    oozie.libpath=hdfs://hdp-node-01:9000/user/hadoop/share/lib
    oozie.wf.application.path=hdfs://hdp-node-01:9000/user/hadoop/oozie/myapps/hive2-etl/

     workflow.xml



    jobTracker {nameNode}


    mapred.job.queue.name
    ${queueName}


    jdbc:hive2://hdp-node-01:10000

    input=/weblog/outpre2




    Hive2 (Beeline) action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]


     coordinator.xml



    workflowAppUrijobTracker {jobTracker}


    nameNode
    nameNodequeueName {queueName}




    10 模块开发——数据展示
    在企业的数据分析系统中,前端展现工具有很多,
     独立部署专门系统的方式:以Business Objects(BO,Crystal Report),Heperion(Brio),Cognos等国外产品为代表的,它们的服务器是单独部署的,与应用程序之间通过某种协议沟通信息

     有WEB程序展现方式:通过独立的或者嵌入式的java web系统来读取报表统计结果,以网页的形式对结果进行展现,如,100%纯Java的润乾报表

    本日志分析项目采用自己开发web程序展现的方式
     Web展现程序采用的技术框架:
    Jquery + Echarts + springmvc + spring + mybatis + mysql
     展现的流程:
    1. 使用ssh从mysql中读取要展现的数据
    2. 使用json格式将读取到的数据返回给页面
    3. 在页面上用echarts对json解析并形成图标

    Web程序工程结构
    采用maven管理工程,引入SSH框架依赖及jquery+echarts的js库

    Web程序的实现代码
    采用典型的MVC架构实现
    页面 HTML + JQUERY + ECHARTS
    Controller SpringMVC
    Service Service
    DAO Mybatis
    数据库 Mysql
    代码详情见项目工程

    代码示例:ChartServiceImpl
    @Service(“chartService”)
    public class ChartServiceImpl implements IChartService {
    @Autowired
    IEchartsDao iEchartsDao;

    public EchartsData getChartsData() {
        List<Integer> xAxiesList = iEchartsDao.getXAxiesList("");
        List<Integer> pointsDataList = iEchartsDao.getPointsDataList("");
    
    
        EchartsData data = new EchartsData();
        ToolBox toolBox = EchartsOptionUtil.getToolBox();
        Serie serie = EchartsOptionUtil.getSerie(pointsDataList);
        ArrayList<Serie> series = new ArrayList<Serie>();
        series.add(serie);
    
    
        List<XAxi> xAxis = EchartsOptionUtil.getXAxis(xAxiesList);
        List<YAxi> yAxis = EchartsOptionUtil.getYAxis();
    
        HashMap<String, String> title = new HashMap<String, String>();
        title.put("text", "pvs");
        title.put("subtext", "超级pvs");
        HashMap<String, String> tooltip = new HashMap<String, String>();
        tooltip.put("trigger", "axis");
    
        HashMap<String, String[]> legend = new HashMap<String, String[]>();
        legend.put("data", new String[]{"pv统计"});
    
    
        data.setTitle(title);
        data.setTooltip(tooltip);
        data.setLegend(legend);
        data.setToolbox(toolBox);
        data.setCalculable(true);
        data.setxAxis(xAxis);
        data.setyAxis(yAxis);
        data.setSeries(series);
        return data;
    }
    
    public List<HashMap<String, Integer>> getGaiKuangList(String date) throws ParseException{
    
        HashMap<String, Integer> gaiKuangToday = iEchartsDao.getGaiKuang(date);
        SimpleDateFormat sf = new SimpleDateFormat("MMdd");
        Date parse = sf.parse(date);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parse);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date before = calendar.getTime();
        String beforeString = sf.format(before);
        System.out.println(beforeString);
    
        HashMap<String, Integer> gaiKuangBefore = iEchartsDao.getGaiKuang(beforeString);
    
        ArrayList<HashMap<String, Integer>> gaiKuangList = new ArrayList<HashMap<String, Integer>>();
        gaiKuangList.add(gaiKuangToday);
        gaiKuangList.add(gaiKuangBefore);
    
        return gaiKuangList;
    
    }
    
    public static void main(String[] args) {
        ChartServiceImpl chartServiceImpl = new ChartServiceImpl();
        EchartsData chartsData = chartServiceImpl.getChartsData();
        Gson gson = new Gson();
        String json = gson.toJson(chartsData);
        System.out.println(json);
    
    }
    

    }

    Web程序的展现效果
    网站概况

    流量分析

    来源分析

    访客分析

    展开全文
  • 1、什么是点击流数据 1.1、WEB访问日志 即指用户访问网站时的所有访问、浏览、点击行为数据。比如点击了哪一个链接,在哪个网页停留时间最多,采用了哪个搜索项、总体浏览时间等。而所有这些信息都可被保存在网站...

    1、什么是点击流数据

    1.1、WEB访问日志

    即指用户访问网站时的所有访问、浏览、点击行为数据。比如点击了哪一个链接,在哪个网页停留时间最多,采用了哪个搜索项、总体浏览时间等。而所有这些信息都可被保存在网站日志中。通过分析这些数据,可以获知许多对网站运营至关重要的信息。采集的数据越全面,分析就能越精准。

    • 日志的生成渠道:

    1)是网站的web服务器所记录的web访问日志;

    2)是通过在页面嵌入自定义的js代码来获取用户的所有访问行为(比如鼠标悬停的位置,点击的页面组件等),然后通过ajax请求到后台记录日志;这种方式所能采集的信息最全面;

    3)通过在页面上埋点1像素的图片,将相关页面访问信息请求到后台记录日志;

    • 日志数据内容详述:

    在实际操作中,有以下几个方面的数据可以被采集:

    1. 访客的系统属性特征。比如所采用的操作系统、浏览器、域名和访问速度等。
    2. 访问特征。包括停留时间、点击的URL等。
    3. 来源特征。包括网络内容信息类型、内容分类和来访URL等。
    4. 产品特征。包括所访问的产品编号、产品类别、产品颜色、产品价格、产品利润、产品数量和特价等级等。

    以电商某东为例,其点击日志格式如下:

    GET /log.gif?t=item.010001&m=UA-J2011-1&pin=-&uid=1679790178&sid=1679790178|12&v=je=1$sc=24-bit$sr=1600x900$ul=zh-cn$cs=GBK$dt=【云南白药套装】云南白药 牙膏 180g×3 (留兰香型)【行情 报价 价格 评测】-京东$hn=item.jd.com$fl=16.0 r0$os=win$br=chrome$bv=39.0.2171.95$wb=1437269412$xb=1449548587$yb=1456186252$zb=12$cb=4$usc=direct$ucp=-$umd=none$uct=-$ct=1456186505411$lt=0$tad=-$sku=1326523$cid1=1316$cid2=1384$cid3=1405$brand=20583$pinid=-&ref=&rm=1456186505411 HTTP/1.1

    1.2、点击流数据模型

    点击流概念

    点击流这个概念更注重用户浏览网站的整个流程,网站日志中记录的用户点击就像是图上的“点”,而点击流更像是将这些“点”串起来形成的“线”。也可以把“点”认为是网站的Page,而“线”则是访问网站的Session。所以点击流数据是由网站日志中整理得到的,它可以比网站日志包含更多的信息,从而使基于点击流数据统计得到的结果更加丰富和高效。

    点击流模型生成

    点击流数据在具体操作上是由散点状的点击日志数据梳理所得,从而,点击数据在数据建模时应该存在两张模型表(Pageviews和visits):

    用于生成点击流的访问日志表

    时间戳

    IP地址

    Cookie

    Session

    请求URL

    Referal

    2012-01-01 12:31:12

    101.0.0.1

    User01

    S001

    /a/...

    somesite.com

    2012-01-01 12:31:16

    201.0.0.2

    User02

    S002

    /a/...

    -

    2012-01-01 12:33:06

    101.0.0.2

    User03

    S002

    /b/...

    baidu.com

    2012-01-01 15:16:39

    234.0.0.3

    User01

    S003

    /c/...

    google.com

    2012-01-01 15:17:11

    101.0.0.1

    User01

    S004

    /d/...

    /c/...

    2012-01-01 15:19:23

    101.0.0.1

    User01

    S004

    /e/...

    /d/....

    页面点击流模型Pageviews表(按session聚集的访问页面信息)

    Session

    userid

    时间

    访问页面URL

    停留时长

    第几步

    S001

    User01

    2012-01-01 12:31:12

    /a/....

    30

    1

    S002

    User02

    2012-01-01 12:31:16

    /a/....

    10

    1

    S002

    User02

    2012-01-01 12:33:06

    /b/....

    110

    2

    S002

    User02

    2012-01-01 12:35:06

    /e/....

    30

    3

    点击流模型Visits

    Session

    起始时间

    结束时间

    进入页面

    离开页面

    访问页面数

    IP

    cookie

    referal

    S001

    2012-01-01 12:31:12

    2012-01-01 12:31:12

    /a/...

    /a/...

    1

    101.0.0.1

    User01

    somesite.com

    S002

    2012-01-01 12:31:16

    2012-01-01 12:35:06

    /a/...

    /e/...

    3

    201.0.0.2

    User02

    -

    S003

    2012-01-01 12:35:42

    2012-01-01 12:35:42

    /c/...

    /c/...

    1

    234.0.0.3

    User03

    baidu.com

    S003

    2012-01-01 15:16:39

    2012-01-01 15:19:23

    /c/...

    /e/...

    3

    101.0.0.1

    User01

    google.com

    ……

    ……

    ……

    ……

    ……

    ……

    ……

    ……

    ……

    这就是点击流模型。当WEB日志转化成点击流数据的时候,很多网站分析度量的计算变得简单了,这就是点击流的“魔力”所在。基于点击流数据我们可以统计出许多常见的网站分析度量。

    2、网站流量数据分析的意义

    网站流量统计分析,可以帮助网站管理员、运营人员、推广人员等实时获取网站流量信息,并从流量来源、网站内容、网站访客特性等多方面提供网站分析的数据依据。从而帮助提高网站流量,提升网站用户体验,让访客更多的沉淀下来变成会员或客户,通过更少的投入获取最大化的收入。

    如下表:

    网站的眼睛

    网站的神经

    网站的大脑

    访问者来自哪里?

    访问者在寻找什么?

    哪些页面最受欢迎?

    访问者从哪里进入?

     

    网页布局合理吗?

    网站导航清晰吗?

    哪些功能存在问题

    网站内容有效吗

    转化路径靠谱吗?

    如何分解目标?

    如何分配广告预算?

    如何衡量产品表现?

    哪些产品需要优化?

    哪些指标需要关注?

    点击流分析的意义可分为两大方面:

    1、技术上

    1. 可以合理修改网站结构及适度分配资源,构建后台服务器群组,比如
    2. 辅助改进网络的拓扑设计,提高性能
    3. 在有高度相关性的节点之间安排快速有效的访问路径
    4. 帮助企业更好地设计网站主页和安排网页内容

    2、业务上

    1. 帮助企业改善市场营销决策,如把广告放在适当的Web页面上。
    2. 优化页面及业务流程设计,提高流量转化率。
    3. 帮助企业更好地根据客户的兴趣来安排内容。
    4. 帮助企业对客户群进行细分,针对不同客户制定个性化的促销策略等。

    终极目标是:改善网站(电商、社交、电影、小说)的运营,获取更高投资回报率(ROI)。

    3、如何进行网站流量分析

    流量分析整体来说是一个内涵非常丰富的体系,其整体过程是一个金字塔结构:

    3.1、流量分析模型举例

    通常有以下几大类的分析需求:

    1)网站流量质量分析

    流量对于每个网站来说都是很重要,但流量并不是越多越好,应该更加看重流量的质量,换句话来说就是流量可以为我们带来多少收入。

    2)网站流量多维度细分

    细分是指通过不同维度对指标进行分割,查看同一个指标在不同维度下的表现,进而找出有问题的那部分指标,对这部分指标进行优化。

    3)网站内容及导航分析

    对于所有网站来说,页面都可以被划分为三个类别:

    1. 导航页
    2. 功能页
    3. 内容页

    首页和列表页都是典型的导航页;

    站内搜索页面、注册表单页面和购物车页面都是典型的功能页,

    而产品详情页、新闻和文章页都是典型的内容页。

    比如从内容导航分析中,以下两类行为就是网站运营者不希望看到的行为:

    第一个问题:访问者从导航页进入,在还没有看到内容页面之前就从导航页离开网站,需要分析导航页造成访问者中途离开的原因。

    第二个问题:访问者从导航页进入内容页后,又返回到导航页,说明需要分析内容页的最初设计,并考虑中内容页提供交叉的信息推荐

    4)网站转化及漏斗分析

    所谓转化,即网站业务流程中的一个封闭渠道,引导用户按照流程最终实现业务目标(比如商品成交);而漏斗模型则是指进入渠道的用户在各环节递进过程中逐渐流失的形象描述;

    对于转化渠道,主要进行两部分的分析:访问者的流失和迷失

    1、阻力和流失

    造成流失的原因很多,如:不恰当的商品或活动推荐、对支付环节中专业名词的解释、帮助信息等内容不当。

    2、迷失

    造成迷失的主要原因是转化流量设计不合理,访问者在特定阶段得不到需要的信息,并且不能根据现有的信息作出决策。

    3.2、流量分析常见指标

    项目中涉及的分析指标主要位于以下几大方面:

    3.2.1、基础分析(PV,IP,UV)

    • 趋势分析:根据选定的时段,提供网站流量数据,通过流量趋势变化形态,为您分析网站访客的访问规律、网站发展状况提供参考。
    • 对比分析:根据选定的两个对比时段,提供网站流量在时间上的纵向对比报表,帮您发现网站发展状况、发展规律、流量变化率等。
    • 当前在线:提供当前时刻站点上的访客量,以及最近15分钟流量、来源、受访、访客变化情况等,方便用户及时了解当前网站流量状况。
    • 访问明细:提供最近7日的访客访问记录,可按每个PV或每次访问行为(访客的每次会话)显示,并可按照来源、搜索词等条件进行筛选。 通过访问明细,用户可以详细了解网站流量的累计过程,从而为用户快速找出流量变动原因提供最原始、最准确的依据。

    3.2.2、来源分析

    • 来源分类:提供不同来源形式(直接输入、搜索引擎、其他外部链接、站内来源)、不同来源项引入流量的比例情况。通过精确的量化数据,帮助用户分析什么类型的来路产生的流量多、效果好,进而合理优化推广方案。
    • 搜索引擎:提供各搜索引擎以及搜索引擎子产品引入流量的比例情况。从搜索引擎引入流量的的角度,帮助用户了解网站的SEO、SEM效果,从而为制定下一步SEO、SEM计划提供依据。
    • 搜索词:提供访客通过搜索引擎进入网站所使用的搜索词,以及各搜索词引入流量的特征和分布。帮助用户了解各搜索词引入流量的质量,进而了解访客的兴趣关注点、网站与访客兴趣点的匹配度,为优化SEO方案及SEM提词方案提供详细依据。
    • 最近7日的访客搜索记录,可按每个PV或每次访问行为(访客的每次会话)显示,并可按照访客类型、地区等条件进行筛选。为您搜索引擎优化提供最详细的原始数据。
    • 来路域名:提供具体来路域名引入流量的分布情况,并可按“社会化媒体”、“搜索引擎”、“邮箱”等网站类型对来源域名进行分类。 帮助用户了解哪类推广渠道产生的流量多、效果好,进而合理优化网站推广方案。
    • 来路页面:提供具体来路页面引入流量的分布情况。 尤其对于通过流量置换、包广告位等方式从其他网站引入流量的用户,该功能可以方便、清晰地展现广告引入的流量及效果,为优化推广方案提供依据。
    • 来源升降榜:提供开通统计后任意两日的TOP10000搜索词、来路域名引入流量的对比情况,并按照变化的剧烈程度提供排行榜。 用户可通过此功能快速找到哪些来路对网站流量的影响比较大,从而及时排查相应来路问题。

    3.2.3、受访分析

    • 受访域名:提供访客对网站中各个域名的访问情况。 一般情况下,网站不同域名提供的产品、内容各有差异,通过此功能用户可以了解不同内容的受欢迎程度以及网站运营成效。
    • 受访页面:提供访客对网站中各个页面的访问情况。 站内入口页面为访客进入网站时浏览的第一个页面,如果入口页面的跳出率较高则需要关注并优化;站内出口页面为访客访问网站的最后一个页面,对于离开率较高的页面需要关注并优化。
    • 受访升降榜:提供开通统计后任意两日的TOP10000受访页面的浏览情况对比,并按照变化的剧烈程度提供排行榜。 可通过此功能验证经过改版的页面是否有流量提升或哪些页面有巨大流量波动,从而及时排查相应问题。
    • 热点图:记录访客在页面上的鼠标点击行为,通过颜色区分不同区域的点击热度;支持将一组页面设置为"关注范围",并可按来路细分点击热度。 通过访客在页面上的点击量统计,可以了解页面设计是否合理、广告位的安排能否获取更多佣金等。
    • 用户视点:提供受访页面对页面上链接的其他站内页面的输出流量,并通过输出流量的高低绘制热度图,与热点图不同的是,所有记录都是实际打开了下一页面产生了浏览次数(PV)的数据,而不仅仅是拥有鼠标点击行为。
    • 访问轨迹:提供观察焦点页面的上下游页面,了解访客从哪些途径进入页面,又流向了哪里。 通过上游页面列表比较出不同流量引入渠道的效果;通过下游页面列表了解用户的浏览习惯,哪些页面元素、内容更吸引访客点击。

    3.2.4、访客分析

    • 地区运营商:提供各地区访客、各网络运营商访客的访问情况分布。 地方网站、下载站等与地域性、网络链路等结合较为紧密的网站,可以参考此功能数据,合理优化推广运营方案。
    • 终端详情:提供网站访客所使用的浏览终端的配置情况。 参考此数据进行网页设计、开发,可更好地提高网站兼容性,以达到良好的用户交互体验。
    • 新老访客:当日访客中,历史上第一次访问该网站的访客记为当日新访客;历史上已经访问过该网站的访客记为老访客。 新访客与老访客进入网站的途径和浏览行为往往存在差异。该功能可以辅助分析不同访客的行为习惯,针对不同访客优化网站,例如为制作新手导航提供数据支持等。
    • 忠诚度:从访客一天内回访网站的次数(日访问频度)与访客上次访问网站的时间两个角度,分析访客对网站的访问粘性、忠诚度、吸引程度。 由于提升网站内容的更新频率、增强用户体验与用户价值可以有更高的忠诚度,因此该功能在网站内容更新及用户体验方面提供了重要参考。
    • 活跃度:从访客单次访问浏览网站的时间与网页数两个角度,分析访客在网站上的活跃程度。 由于提升网站内容的质量与数量可以获得更高的活跃度,因此该功能是网站内容分析的关键指标之一。

    3.2.5、转化路径分析

    转化定义:访客在您的网站完成了某项您期望的活动,记为一次转化,如注册或下载。

    目标示例

    • 获得用户目标:在线注册、创建账号等。
    • 咨询目标:咨询、留言、电话等。
    • 互动目标:视频播放、加入购物车、分享等。
    • 收入目标:在线订单、付款等。

    转化数据的应用

    • 在报告的自定义指标中勾选转化指标,实时掌握网站的推广及运营情况。
    • 结合“全部来源”、“转化路径”、“页面上下游”等报告分析访问漏斗,提高转化率。
    • 对“转化目标”设置价值,预估转化收益,衡量ROI。

    路径分析:根据设置的特定路线,监测某一流程的完成转化情况,算出每步的转换率和流失率数据,如注册流程,购买流程等。

    转化类型:

    页面

    事件

     

    展开全文
  • 网站点击流数据分析

    千次阅读 2018-03-25 17:44:54
    网站点击流数据分析项目业务背景1.1 什么是点击流数据1.1.1 WEB访问日志即指用户访问网站时的所有访问、浏览、点击行为数据。比如点击了哪一个链接,在哪个网页停留时间最多,采用了哪个搜索项、总体浏览时间等。而...

    网站点击流数据分析

    原创  2017年09月19日 18:22:26
    • 2292

    1. 网站点击流数据分析项目业务背景

    1.1 什么是点击流数据

    1.1.1 WEB访问日志

    即指用户访问网站时的所有访问、浏览、点击行为数据。比如点击了哪一个链接,在哪个网页停留时间最多,采用了哪个搜索项、总体浏览时间等。而所有这些信息都可被保存在网站日志中。通过分析这些数据,可以获知许多对网站运营至关重要的信息。采集的数据越全面,分析就能越精准。

    日志的生成渠道:

    1)是网站的web服务器所记录的web访问日志;

    2)是通过在页面嵌入自定义的js代码来获取用户的所有访问行为(比如鼠标悬停的位置,点击的页面组件等),然后通过ajax请求到后台记录日志;这种方式所能采集的信息最全面;

    3)通过在页面上埋点1像素的图片,将相关页面访问信息请求到后台记录日志;

    日志数据内容详述:

    在实际操作中,有以下几个方面的数据可以被采集:

    1) 访客的系统属性特征。比如所采用的操作系统、浏览器、域名和访问速度等。

    2) 访问特征。包括停留时间、点击的URL等。

    3) 来源特征。包括网络内容信息类型、内容分类和来访URL等。

    4) 产品特征。包括所访问的产品编号、产品类别、产品颜色、产品价格、产品利润、产品数量和特价等级等。

    以电商某东为例,其点击日志格式如下:

    GET /log.gif?t=item.010001&m=UA-J2011-1&pin=-&uid=1679790178&sid=1679790178|12&v=je=1$sc=24-bit$sr=1600x900$ul=zh-cn$cs=GBK$dt=【云南白药套装】云南白药 牙膏 1803 (留兰香型)【行情 报价 价格 评测】-京东$hn=item.jd.com$fl=16.0 r0$os=win$br=chrome$bv=39.0.2171.95$wb=1437269412$xb=1449548587$yb=1456186252$zb=12$cb=4$usc=direct$ucp=-$umd=none$uct=-$ct=1456186505411$lt=0$tad=-$sku=1326523$cid1=1316$cid2=1384$cid3=1405$brand=20583$pinid=-&ref=&rm=1456186505411 HTTP/1.1
    • 1

    1.1.2 点击流数据模型

    点击流概念

    点击流这个概念更注重用户浏览网站的整个流程,网站日志中记录的用户点击就像是图上的“点”,而点击流更像是将这些“点”串起来形成的“线”。也可以把“点”认为是网站的Page,而“线”则是访问网站的Session。所以点击流数据是由网站日志中整理得到的,它可以比网站日志包含更多的信息,从而使基于点击流数据统计得到的结果更加丰富和高效。

    点击流模型生成

    点击流数据在具体操作上是由散点状的点击日志数据梳理所得,从而,点击数据在数据建模时应该存在两张模型表(Pageviews和visits):

    1、用于生成点击流的访问日志表

    时间戳IP地址CookieSession请求URLReferal
    2012-01-01 12:31:12101.0.0.1User01S001/a/…somesite.com
    2012-01-01 12:31:16201.0.0.2User02S002/a/…-
    2012-01-01 12:33:06101.0.0.2User03S002/b/…baidu.com
    2012-01-01 15:16:39234.0.0.3User01S003/c/…google.com
    2012-01-01 15:17:11101.0.0.1User01S004/d/…/c/…
    2012-01-01 15:19:23101.0.0.1User01S004/e/…/d/….

    2、页面点击流模型Pageviews表

    Sessionuserid时间访问页面URL停留时长第几步
    S001User012012-01-01 12:31:12/a/….301
    S002User022012-01-01 12:31:16/a/….101
    S002User022012-01-01 12:33:06/b/….1102
    S002User022012-01-01 12:35:06/e/….303

    3、点击流模型Visits表

    Session起始时间结束时间进入页面离开页面访问页面数IPcookiereferal
    S0012012-01-01 12:31:122012-01-01 12:31:12/a/…/a/…1101.0.0.1User01somesite.com
    S0022012-01-01 12:31:162012-01-01 12:35:06/a/…/e/…3201.0.0.2User02-
    S0032012-01-01 12:35:422012-01-01 12:35:42/c/…/c/…1234.0.0.3User03baidu.com
    S0032012-01-01 15:16:392012-01-01 15:19:23/c/…/e/…3101.0.0.1User01google.com
    ………………………………………………

    这就是点击流模型。当WEB日志转化成点击流数据的时候,很多网站分析度量的计算变得简单了,这就是点击流的“魔力”所在。基于点击流数据我们可以统计出许多常见的网站分析度量

    1.2网站流量数据分析的意义

    网站流量统计分析,可以帮助网站管理员、运营人员、推广人员等实时获取网站流量信息,并从流量来源、网站内容、网站访客特性等多方面提供网站分析的数据依据。从而帮助提高网站流量,提升网站用户体验,让访客更多的沉淀下来变成会员或客户,通过更少的投入获取最大化的收入。

    如下表:

    网站的眼睛网站的神经网站的大脑
    访问者来自哪里?访问者在寻找什么?哪些页面最受欢迎?访问者从哪里进入?网页布局合理吗?网站导航清晰吗?哪些功能存在问题网站内容有效吗转化路径靠谱吗?如何分解目标?如何分配广告预算?如何衡量产品表现?哪些产品需要优化?哪些指标需要关注?

    点击流分析的意义可分为两大方面:

    1、技术上

    可以合理修改网站结构及适度分配资源,构建后台服务器群组,比如

    辅助改进网络的拓扑设计,提高性能

    在有高度相关性的节点之间安排快速有效的访问路径

    帮助企业更好地设计网站主页和安排网页内容

    2、业务上

    1) 帮助企业改善市场营销决策,如把广告放在适当的Web页面上。

    2) 优化页面及业务流程设计,提高流量转化率。

    3) 帮助企业更好地根据客户的兴趣来安排内容。

    4) 帮助企业对客户群进行细分,针对不同客户制定个性化的促销策略等。

    终极目标是:改善网站(电商、社交、电影、小说)的运营,获取更高投资回报率(ROI)

    1.3 如何进行网站流量分析**

    流量分析整体来说是一个内涵非常丰富的体系,其整体过程是一个金字塔结构:

    1.3.1 流量分析模型举例

    通常有以下几大类的分析需求:

    1)网站流量质量分析

    流量对于每个网站来说都是很重要,但流量并不是越多越好,应该更加看重流量的质量,换句话来说就是流量可以为我们带来多少收入。

    2)网站流量多维度细分

    细分是指通过不同维度对指标进行分割,查看同一个指标在不同维度下的表现,进而找出有问题的那部分指标,对这部分指标进行优化。

    3)网站内容及导航分析

    对于所有网站来说,页面都可以被划分为三个类别:

    ​ 导航页

    ​ 功能页

    ​ 内容页

    首页和列表页都是典型的导航页;

    站内搜索页面、注册表单页面和购物车页面都是典型的功能页,

    而产品详情页、新闻和文章页都是典型的内容页。

    比如从内容导航分析中,以下两类行为就是网站运营者不希望看到的行为:

    第一个问题:访问者从导航页进入,在还没有看到内容页面之前就从导航页离开网站,需要分析导航页造成访问者中途离开的原因。

    第二个问题:访问者从导航页进入内容页后,又返回到导航页,说明需要分析内容页的最初设计,并考虑中内容页提供交叉的信息推荐

    4)网站转化及漏斗分析

    所谓转化,即网站业务流程中的一个封闭渠道,引导用户按照流程最终实现业务目标(比如商品成交);而漏斗模型则是指进入渠道的用户在各环节递进过程中逐渐流失的形象描述;

    对于转化渠道,主要进行两部分的分析:

    访问者的流失和迷失

    1、阻力和流失

    造成流失的原因很多,如:

    不恰当的商品或活动推荐

    对支付环节中专业名词的解释、帮助信息等内容不当

    2、迷失

    造成迷失的主要原因是转化流量设计不合理,访问者在特定阶段得不到需要的信息,并且不能根据现有的信息作出决策

    总之,网站流量分析是一门内容非常丰富的学科,本课程中主要关注网站分析过程中的技术运用,更多关于网站流量分析的业务知识可学习推荐资料。

    1.3.2 流量分析常见指标

    课程中涉及的分析指标主要位于以下几大方面:

    1)基础分析(PV,IP,UV)

    趋势分析:根据选定的时段,提供网站流量数据,通过流量趋势变化形态,为您分析网站访客的访问规律、网站发展状况提供参考。

    对比分析:根据选定的两个对比时段,提供网站流量在时间上的纵向对比报表,帮您发现网站发展状况、发展规律、流量变化率等。

    当前在线:提供当前时刻站点上的访客量,以及最近15分钟流量、来源、受访、访客变化情况等,方便用户及时了解当前网站流量状况。

    访问明细:提供最近7日的访客访问记录,可按每个PV或每次访问行为(访客的每次会话)显示,并可按照来源、搜索词等条件进行筛选。 通过访问明细,用户可以详细了解网站流量的累计过程,从而为用户快速找出流量变动原因提供最原始、最准确的依据。

    2)来源分析

    来源分类:提供不同来源形式(直接输入、搜索引擎、其他外部链接、站内来源)、不同来源项引入流量的比例情况。通过精确的量化数据,帮助用户分析什么类型的来路产生的流量多、效果好,进而合理优化推广方案。

    搜索引擎:提供各搜索引擎以及搜索引擎子产品引入流量的比例情况。从搜索引擎引入流量的的角度,帮助用户了解网站的SEO、SEM效果,从而为制定下一步SEO、SEM计划提供依据。

    搜索词:提供访客通过搜索引擎进入网站所使用的搜索词,以及各搜索词引入流量的特征和分布。帮助用户了解各搜索词引入流量的质量,进而了解访客的兴趣关注点、网站与访客兴趣点的匹配度,为优化SEO方案及SEM提词方案提供详细依据。

    最近7日的访客搜索记录,可按每个PV或每次访问行为(访客的每次会话)显示,并可按照访客类型、地区等条件进行筛选。为您搜索引擎优化提供最详细的原始数据。

    来路域名:提供具体来路域名引入流量的分布情况,并可按“社会化媒体”、“搜索引擎”、“邮箱”等网站类型对来源域名进行分类。 帮助用户了解哪类推广渠道产生的流量多、效果好,进而合理优化网站推广方案。

    来路页面:提供具体来路页面引入流量的分布情况。 尤其对于通过流量置换、包广告位等方式从其他网站引入流量的用户,该功能可以方便、清晰地展现广告引入的流量及效果,为优化推广方案提供依据。

    来源升降榜:提供开通统计后任意两日的TOP10000搜索词、来路域名引入流量的对比情况,并按照变化的剧烈程度提供排行榜。 用户可通过此功能快速找到哪些来路对网站流量的影响比较大,从而及时排查相应来路问题。

    3)受访分析

    受访域名:提供访客对网站中各个域名的访问情况。 一般情况下,网站不同域名提供的产品、内容各有差异,通过此功能用户可以了解不同内容的受欢迎程度以及网站运营成效。

    受访页面:提供访客对网站中各个页面的访问情况。 站内入口页面为访客进入网站时浏览的第一个页面,如果入口页面的跳出率较高则需要关注并优化;站内出口页面为访客访问网站的最后一个页面,对于离开率较高的页面需要关注并优化。

    受访升降榜:提供开通统计后任意两日的TOP10000受访页面的浏览情况对比,并按照变化的剧烈程度提供排行榜。 可通过此功能验证经过改版的页面是否有流量提升或哪些页面有巨大流量波动,从而及时排查相应问题。

    热点图:记录访客在页面上的鼠标点击行为,通过颜色区分不同区域的点击热度;支持将一组页面设置为”关注范围”,并可按来路细分点击热度。 通过访客在页面上的点击量统计,可以了解页面设计是否合理、广告位的安排能否获取更多佣金等。

    用户视点:提供受访页面对页面上链接的其他站内页面的输出流量,并通过输出流量的高低绘制热度图,与热点图不同的是,所有记录都是实际打开了下一页面产生了浏览次数(PV)的数据,而不仅仅是拥有鼠标点击行为。

    访问轨迹:提供观察焦点页面的上下游页面,了解访客从哪些途径进入页面,又流向了哪里。 通过上游页面列表比较出不同流量引入渠道的效果;通过下游页面列表了解用户的浏览习惯,哪些页面元素、内容更吸引访客点击。

    4)访客分析

    地区运营商:提供各地区访客、各网络运营商访客的访问情况分布。 地方网站、下载站等与地域性、网络链路等结合较为紧密的网站,可以参考此功能数据,合理优化推广运营方案。

    终端详情:提供网站访客所使用的浏览终端的配置情况。 参考此数据进行网页设计、开发,可更好地提高网站兼容性,以达到良好的用户交互体验。

    新老访客:当日访客中,历史上第一次访问该网站的访客记为当日新访客;历史上已经访问过该网站的访客记为老访客。 新访客与老访客进入网站的途径和浏览行为往往存在差异。该功能可以辅助分析不同访客的行为习惯,针对不同访客优化网站,例如为制作新手导航提供数据支持等。

    忠诚度:从访客一天内回访网站的次数(日访问频度)与访客上次访问网站的时间两个角度,分析访客对网站的访问粘性、忠诚度、吸引程度。 由于提升网站内容的更新频率、增强用户体验与用户价值可以有更高的忠诚度,因此该功能在网站内容更新及用户体验方面提供了重要参考。

    活跃度:从访客单次访问浏览网站的时间与网页数两个角度,分析访客在网站上的活跃程度。 由于提升网站内容的质量与数量可以获得更高的活跃度,因此该功能是网站内容分析的关键指标之一。

    5)转化路径分析

    转化定义

    ·访客在您的网站完成了某项您期望的活动,记为一次转化,如注册或下载。

    目标示例

    ·获得用户目标:在线注册、创建账号等。

    ·咨询目标:咨询、留言、电话等。

    ·互动目标:视频播放、加入购物车、分享等。

    ·收入目标:在线订单、付款等。

    转化数据的应用

    ·在报告的自定义指标中勾选转化指标,实时掌握网站的推广及运营情况。

    ·结合“全部来源”、“转化路径”、“页面上下游”等报告分析访问漏斗,提高转化率。

    ·对“转化目标”设置价值,预估转化收益,衡量ROI。


    路径分析:根据设置的特定路线,监测某一流程的完成转化情况,算出每步的转换率和流失率数据,如注册流程,购买流程等。

    转化类型:

    1、页面

    2、事件

    2 整体技术流程及架构

    2.1 数据处理流程

    该项目是一个纯粹的数据分析项目,其整体流程基本上就是依据数据的处理流程进行,依此有以下几个大的步骤:

    1) 数据采集

    首先,通过页面嵌入JS代码的方式获取用户访问行为,并发送到web服务的后台记录日志

    然后,将各服务器上生成的点击流日志通过实时或批量的方式汇聚到HDFS文件系统中

    当然,一个综合分析系统,数据源可能不仅包含点击流数据,还有数据库中的业务数据(如用户信息、商品信息、订单信息等)及对分析有益的外部数据

    2) 数据预处理

    通过mapreduce程序对采集到的点击流数据进行预处理,比如清洗,格式整理,滤除脏数据等

    3) 数据入库

    将预处理之后的数据导入到HIVE仓库中相应的库和表中

    4) 数据分析

    项目的核心内容,即根据需求开发ETL分析语句,得出各种统计结果

    5) 数据展现

    将分析所得数据进行可视化

    2.2 项目结构

    由于本项目是一个纯粹数据分析项目,其整体结构亦跟分析流程匹配,并没有特别复杂的结构,如下图:

    其中,需要强调的是:

    系统的数据分析不是一次性的,而是按照一定的时间频率反复计算,因而整个处理链条中的各个环节需要按照一定的先后依赖关系紧密衔接,即涉及到大量任务单元的管理调度,所以,项目中需要添加一个任务调度模块

    2.3 数据展现

    数据展现的目的是将分析所得的数据进行可视化,以便运营决策人员能更方便地获取数据,更快更简单地理解数据

    3 模块开发——数据采集

    3.1 需求

    数据采集的需求广义上来说分为两大部分。

    1)是在页面采集用户的访问行为,具体开发工作:

    ​ 1、开发页面埋点js,采集用户访问行为

    ​ 2、后台接受页面js请求记录日志

    此部分工作也可以归属为“数据源”,其开发工作通常由web开发团队负责

    2)是从web服务器上汇聚日志到HDFS,是数据分析系统的数据采集,此部分工作由数据分析平台建设团队负责,具体的技术实现有很多方式:

    ​ Shell脚本

    ​ 优点:轻量级,开发简单

    ​ 缺点:对日志采集过程中的容错处理不便控制

    ​ Java采集程序

    ​ 优点:可对采集过程实现精细控制

    ​ 缺点:开发工作量大

    ​ Flume日志采集框架

    ​ 成熟的开源日志采集系统,且本身就是hadoop生态体系中的一员,与hadoop体系中的各种框架组件具有天生的亲和力,可扩展性强

    3.2 技术选型

    在点击流日志分析这种场景中,对数据采集部分的可靠性、容错能力要求通常不会非常严苛,因此使用通用的flume日志采集框架完全可以满足需求。

    本项目即使用flume来实现日志采集。

    3.3 Flume日志采集系统搭建

    1、数据源信息

    本项目分析的数据用nginx服务器所生成的流量日志,存放在各台nginx服务器上,如:

    /var/log/httpd/access_log.3-00.log

    /var/log/httpd/access_log.4-00.log

    /var/log/httpd/access_log.5-00.log

    /var/log/httpd/access_log.6-00.log

    2、数据内容样例

    数据的具体内容在采集阶段其实不用太关心。

    58.215.204.118 - - [18/Sep/2013:06:51:35 +0000] "GET /wp-includes/js/jquery/jquery.js?ver=1.10.2 HTTP/1.1" 304 0 "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"
    • 1

    字段解析:

    1、访客ip地址: 58.215.204.118

    2、访客用户信息: - -

    3、请求时间:[18/Sep/2013:06:51:35 +0000]

    4、请求方式:GET

    5、请求的url:/wp-includes/js/jquery/jquery.js?ver=1.10.2

    6、请求所用协议:HTTP/1.1

    7、响应码:304

    8、返回的数据流量:0

    9、访客的来源url:http://blog.fens.me/nodejs-socketio-chat/

    10、访客所用浏览器:Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0

    3、日志文件生成规律

    基本规律为:

    当前正在写的文件为access_log;

    文件体积达到64M,或时间间隔达到60分钟,即滚动重命名切换成历史日志文件;

    形如: access_log.2015-11-10-13-00.log

    当然,每个公司的web服务器日志策略不同,可在web程序的log4j.properties中定义,如下:

    log4j.appender.logDailyFile = org.apache.log4j.DailyRollingFileAppender 
    log4j.appender.logDailyFile.layout = org.apache.log4j.PatternLayout 
    log4j.appender.logDailyFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
    log4j.appender.logDailyFile.Threshold = DEBUG 
    log4j.appender.logDailyFile.ImmediateFlush = TRUE 
    log4j.appender.logDailyFile.Append = TRUE 
    log4j.appender.logDailyFile.File = /var/logs/access_log 
    log4j.appender.logDailyFile.DatePattern = '.'yyyy-MM-dd-HH-mm'.log' 
    log4j.appender.logDailyFile.Encoding = UTF-8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4、Flume采集实现

    Flume采集系统的搭建相对简单:

    ​ 1、在多个web服务器上部署agent节点,修改配置文件

    ​ 2、启动agent节点,将采集到的数据汇聚到指定的HDFS目录中

    如下图:

    ​ 版本选择:apache-flume-1.6.0

    ​ 采集规则设计:

    ​ 1、 采集源:nginx服务器日志目录

    ​ 2、 存放地:hdfs目录/home/hadoop/weblogs/

    ² 采集规则配置详情

    agent1.sources = source1
    agent1.sinks = sink1
    agent1.channels = channel1
    
    # Describe/configure spooldir source1
    #agent1.sources.source1.type = spooldir
    #agent1.sources.source1.spoolDir = /var/logs/nginx/
    #agent1.sources.source1.fileHeader = false
    
    # Describe/configure tail -F source1
    #使用exec作为数据源source组件
    agent1.sources.source1.type = exec 
    #使用tail -F命令实时收集新产生的日志数据
    agent1.sources.source1.command = tail -F /var/logs/nginx/access_log
    agent1.sources.source1.channels = channel1
    
    #configure host for source
    #配置一个拦截器插件
    agent1.sources.source1.interceptors = i1
    agent1.sources.source1.interceptors.i1.type = host
    #使用拦截器插件获取agent所在服务器的主机名
    agent1.sources.source1.interceptors.i1.hostHeader = hostname
    
    #配置sink组件为hdfs
    agent1.sinks.sink1.type = hdfs
    #a1.sinks.k1.channel = c1
    #agent1.sinks.sink1.hdfs.path=hdfs://hdp-node-01:9000/weblog/flume-collection/%y-%m-%d/%H%M%S
    #指定文件sink到hdfs上的路径
    agent1.sinks.sink1.hdfs.path=
    hdfs://hdp-node-01:9000/weblog/flume-collection/%y-%m-%d/%H-%M_%hostname
    #指定文件名前缀
    agent1.sinks.sink1.hdfs.filePrefix = access_log
    agent1.sinks.sink1.hdfs.maxOpenFiles = 5000 
    #指定每批下沉数据的记录条数
    agent1.sinks.sink1.hdfs.batchSize= 100
    agent1.sinks.sink1.hdfs.fileType = DataStream
    agent1.sinks.sink1.hdfs.writeFormat =Text
    #指定下沉文件按1G大小滚动
    agent1.sinks.sink1.hdfs.rollSize = 1024*1024*1024
    #指定下沉文件按1000000条数滚动
    agent1.sinks.sink1.hdfs.rollCount = 1000000
    #指定下沉文件按30分钟滚动
    agent1.sinks.sink1.hdfs.rollInterval = 30
    #agent1.sinks.sink1.hdfs.round = true
    #agent1.sinks.sink1.hdfs.roundValue = 10
    #agent1.sinks.sink1.hdfs.roundUnit = minute
    agent1.sinks.sink1.hdfs.useLocalTimeStamp = true
    
    # Use a channel which buffers events in memory
    #使用memory类型channel
    agent1.channels.channel1.type = memory
    agent1.channels.channel1.keep-alive = 120
    agent1.channels.channel1.capacity = 500000
    agent1.channels.channel1.transactionCapacity = 600
    
    # Bind the source and sink to the channel
    agent1.sources.source1.channels = channel1
    agent1.sinks.sink1.channel = channel1
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    启动采集

    在部署了flume的nginx服务器上,启动flume的agent,命令如下:

    bin/flume-ng agent --conf ./conf -f ./conf/weblog.properties.2 -n agent
    • 1

    注意:启动命令中的 -n 参数要给配置文件中配置的agent名称

    4 模块开发——数据预处理

    4.1 主要目的:

    过滤“不合规”数据

    格式转换和规整

    根据后续的统计需求,过滤分离出各种不同主题的基础数据

    4.2 实现方式:

    开发一个mr程序WeblogPreProcess(内容太长,见工程代码)

    public class WeblogPreProcess {
        static class WeblogPreProcessMapper extends Mapper<LongWritable, Text, Text, NullWritable> {
            Text k = new Text();
            NullWritable v = NullWritable.get();
            @Override
            protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
                String line = value.toString();
                WebLogBean webLogBean = WebLogParser.parser(line);
    //          WebLogBean productWebLog = WebLogParser.parser2(line);
    //          WebLogBean bbsWebLog = WebLogParser.parser3(line);
    //          WebLogBean cuxiaoBean = WebLogParser.parser4(line);
                if (!webLogBean.isValid())
                    return;
                k.set(webLogBean.toString());
                context.write(k, v);
    //          k.set(productWebLog);
    //          context.write(k, v);
            }
        }
        public static void main(String[] args) throws Exception {
    
            Configuration conf = new Configuration();
            Job job = Job.getInstance(conf);
            job.setJarByClass(WeblogPreProcess.class);
            job.setMapperClass(WeblogPreProcessMapper.class);
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(NullWritable.class);
            FileInputFormat.setInputPaths(job, new Path(args[0]));
            FileOutputFormat.setOutputPath(job, new Path(args[1]));
            job.waitForCompletion(true);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    ​ 运行mr对数据进行预处理

    hadoop jar weblog.jar  cn.it.bigdata.hive.mr.WeblogPreProcess /weblog/input /weblog/preout
    • 1

    4.3 点击流模型数据梳理

    由于大量的指标统计从点击流模型中更容易得出,所以在预处理阶段,可以使用mr程序来生成点击流模型的数据

    4.3.1 点击流模型pageviews表

    Pageviews表模型数据生成

    代码见工程
    hadoop jar weblogpreprocess.jar  \
    cn.it.bigdata.hive.mr.ClickStreamThree   \
    /user/hive/warehouse/dw_click.db/test_ods_weblog_origin/datestr=2013-09-20/ /test-click/pageviews/
    • 1
    • 2
    • 3
    • 4

    表结构:

    (表定义及数据导入见6.2节)

    4.3.2 点击流模型visit信息表

    注:“一次访问”=“N次连续请求”

    直接从原始数据中用hql语法得出每个人的“次”访问信息比较困难,可先用mapreduce程序分析原始数据得出“次”信息数据,然后再用hql进行更多维度统计

    用MR程序从pageviews数据中,梳理出每一次visit的起止时间、页面信息

    代码见工程
    hadoop jar weblogpreprocess.jar cn.it.bigdata.hive.mr.ClickStreamVisit /weblog/sessionout /weblog/visitout
    • 1
    • 2

    然后,在hive仓库中建点击流visit模型表

    drop table if exist click_stream_visit;
    create table click_stream_visit(
    session     string,
    remote_addr string,
    inTime      string,
    outTime     string,
    inPage      string,
    outPage     string,
    referal     string,
    pageVisits  int)
    partitioned by (datestr string);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后,将MR运算得到的visit数据导入visit模型表

    load data inpath '/weblog/visitout' into table click_stream_visit partition(datestr='2013-09-18');
    • 1

    5 模块开发——数据仓库设计

    注:采用星型模型

    **5.**1事实表

    原始数据表:t_origin_weblog  
    validstring是否有效
    remote_addrstring访客ip
    remote_userstring访客用户信息
    time_localstring请求时间
    requeststring请求url
    statusstring响应码
    body_bytes_sentstring响应字节数
    http_refererstring来源url
    http_user_agentstring访客终端信息
       
    ETL中间表:t_etl_referurl  
    validstring是否有效
    remote_addrstring访客ip
    remote_userstring访客用户信息
    time_localstring请求时间
    requeststring请求url
    request_hoststring请求的域名
    statusstring响应码
    body_bytes_sentstring响应字节数
    http_refererstring来源url
    http_user_agentstring访客终端信息
    validstring是否有效
    remote_addrstring访客ip
    remote_userstring访客用户信息
    time_localstring请求时间
    requeststring请求url
    statusstring响应码
    body_bytes_sentstring响应字节数
    http_refererstring外链url
    http_user_agentstring访客终端信息
    hoststring外链url的域名
    pathstring外链url的路径
    querystring外链url的参数
    query_idstring外链url的参数值
       
       
    访问日志明细宽表:t_ods_access_detail  
    validstring是否有效
    remote_addrstring访客ip
    remote_userstring访客用户信息
    time_localstring请求时间
    requeststring请求url整串
    request_level1string请求的一级栏目
    request_level2string请求的二级栏目
    request_level3string请求的三级栏目
    statusstring响应码
    body_bytes_sentstring响应字节数
    http_refererstring来源url
    http_user_agentstring访客终端信息
    validstring是否有效
    remote_addrstring访客ip
    remote_userstring访客用户信息
    time_localstring请求时间
    requeststring请求url
    statusstring响应码
    body_bytes_sentstring响应字节数
    http_refererstring外链url
    http_user_agentstring访客终端信息整串
    http_user_agent_browserstring访客终端浏览器
    http_user_agent_sysstring访客终端操作系统
    http_user_agent_devstring访客终端设备
    hoststring外链url的域名
    pathstring外链url的路径
    querystring外链url的参数
    query_idstring外链url的参数值
    daystrstring日期整串
    tmstrstring时间整串
    monthstring月份
    daystring
    hourstring
    minutestring
    ###
    mmstring分区字段–月
    ddstring分区字段–日

    **5.**2维度表

    **时间维度 **v_year_month_date
    year
    month
    day
    hour
    minute
    访客地域维度t_dim_area
    北京
    上海
    广州
    深圳*
    河北*
    河南
    终端类型维度t_dim_termination
    uc
    firefox
    chrome
    safari
    ios
    android
    网站栏目维度 t_dim_****section
    跳蚤市场
    房租信息
    休闲娱乐
    建材装修
    本地服务
    人才市场

    6 模块开发——ETL

    该项目的数据分析过程在hadoop集群上实现,主要应用hive数据仓库工具,因此,采集并经过预处理后的数据,需要加载到hive数据仓库中,以进行后续的挖掘分析。

    6.1创建原始数据表

    –在hive仓库中建贴源数据表

    drop table if exists ods_weblog_origin;
    create table ods_weblog_origin(
    valid string,
    remote_addr string,
    remote_user string,
    time_local string,
    request string,
    status string,
    body_bytes_sent string,
    http_referer string,
    http_user_agent string)
    partitioned by (datestr string)
    row format delimited
    fields terminated by '\001';
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    点击流模型pageviews表

    drop table if exists ods_click_pageviews;
    create table ods_click_pageviews(
    Session string,
    remote_addr string,
    time_local string,
    request string,
    visit_step string,
    page_staylong string,
    http_referer string,
    http_user_agent string,
    body_bytes_sent string,
    status string)
    partitioned by (datestr string)
    row format delimited
    fields terminated by '\001';
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    时间维表创建

    drop table dim_time if exists ods_click_pageviews;
    create table dim_time(
    year string,
    month string,
    day string,
    hour string)
    row format delimited
    fields terminated by ',';
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    6.2导入数据

    导入清洗结果数据到贴源数据表ods_weblog_origin
    load data inpath '/weblog/preprocessed/16-02-24-16/' overwrite into table ods_weblog_origin partition(datestr='2013-09-18');
    
    0: jdbc:hive2://localhost:10000> show partitions ods_weblog_origin;
    +-------------------+--+
    |     partition     |
    +-------------------+--+
    | timestr=20151203  |
    +-------------------+--+
    
    0: jdbc:hive2://localhost:10000> select count(*) from ods_origin_weblog;
    +--------+--+
    |  _c0   |
    +--------+--+
    | 11347  |
    +--------+--+
    
    导入点击流模型pageviews数据到ods_click_pageviews表
    0: jdbc:hive2://hdp-node-01:10000> load data inpath '/weblog/clickstream/pageviews' overwrite into table ods_click_pageviews partition(datestr='2013-09-18');
    
    0: jdbc:hive2://hdp-node-01:10000> select count(1) from ods_click_pageviews;
    +------+--+
    | _c0  |
    +------+--+
    | 66   |
    +------+--+
    
    
    导入点击流模型visit数据到ods_click_visit表
    
    导入时间维表:
    load data inpath '/dim_time.txt' into table dim_time;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    6.3 生成ODS层明细宽表

    6.3.1 需求概述

    整个数据分析的过程是按照数据仓库的层次分层进行的,总体来说,是从ODS原始数据中整理出一些中间表(比如,为后续分析方便,将原始数据中的时间、url等非结构化数据作结构化抽取,将各种字段信息进行细化,形成明细表),然后再在中间表的基础之上统计出各种指标数据

    6.3.2 ETL实现

    建表——明细表 (源:ods_weblog_origin) (目标:ods_weblog_detail)

    drop table ods_weblog_detail;
    create table ods_weblog_detail(
    valid           string, --有效标识
    remote_addr     string, --来源IP
    remote_user     string, --用户标识
    time_local      string, --访问完整时间
    daystr          string, --访问日期
    timestr         string, --访问时间
    month           string, --访问月
    day             string, --访问日
    hour            string, --访问时
    request         string, --请求的url
    status          string, --响应码
    body_bytes_sent string, --传输字节数
    http_referer    string, --来源url[
    http://www.baidu.com/aapath?sousuoci=’angel’
    
    parse_url_tuple(url,’HOST’,’PATH’,’QUERY’,’QUERY:id’)
    
    
    ]
    ref_host        string, --来源的host
    ref_path        string, --来源的路径
    ref_query       string, --来源参数query
    ref_query_id    string, --来源参数query的值
    http_user_agent string --客户终端标识
    )
    partitioned by(datestr string);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    –抽取refer_url到中间表 “t_ods_tmp_referurl”

    –将来访url分离出host path query query id

    drop table if exists t_ods_tmp_referurl;
    create table t_ ods _tmp_referurl as
    SELECT a.*,b.*
    FROM ods_origin_weblog a LATERAL VIEW parse_url_tuple(regexp_replace(http_referer, "\"", ""), 'HOST', 'PATH','QUERY', 'QUERY:id') b as host, path, query, query_id; 
    • 1
    • 2
    • 3
    • 4

    –抽取转换time_local字段到中间表明细表 ”t_ ods _detail”

    drop table if exists t_ods_tmp_detail;
    create table t_ods_tmp_detail as 
    select b.*,substring(time_local,0,10) as daystr,
    substring(time_local,11) as tmstr,
    substring(time_local,5,2) as month,
    substring(time_local,8,2) as day,
    substring(time_local,11,2) as hour
    From t_ ods _tmp_referurl b;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    以上语句可以改写成:

    insert into table zs.ods_weblog_detail partition(datestr='$day_01')
    select c.valid,c.remote_addr,c.remote_user,c.time_local,
    substring(c.time_local,0,10) as daystr,
    substring(c.time_local,12) as tmstr,
    substring(c.time_local,6,2) as month,
    substring(c.time_local,9,2) as day,
    substring(c.time_local,11,3) as hour,
    c.request,c.status,c.body_bytes_sent,c.http_referer,c.ref_host,c.ref_path,c.ref_query,c.ref_query_id,c.http_user_agent
    from
    (SELECT 
    a.valid,a.remote_addr,a.remote_user,a.time_local,
    a.request,a.status,a.body_bytes_sent,a.http_referer,a.http_user_agent,b.ref_host,b.ref_path,b.ref_query,b.ref_query_id 
    FROM zs.ods_weblog_origin a LATERAL VIEW parse_url_tuple(regexp_replace(http_referer, "\"", ""), 'HOST', 'PATH','QUERY', 'QUERY:id') b as ref_host, ref_path, ref_query, ref_query_id) c
    "
    0: jdbc:hive2://localhost:10000> show partitions ods_weblog_detail;
    +---------------------+--+
    |      partition      |
    +---------------------+--+
    | dd=18%2FSep%2F2013  |
    +---------------------+--+
    1 row selected (0.134 seconds)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    7 模块开发——统计分析

    注:每一种统计指标都可以跟各维度表进行叉乘,从而得出各个维度的统计结果

    篇幅限制,叉乘的代码及注释信息详见项目工程代码文件

    为了在前端展示时速度更快,每一个指标都事先算出各维度结果存入mysql

    提前准备好维表数据,在hive仓库中创建相应维表,如:

    时间维表:

    create table v_time(year string,month string,day string,hour string)
    row format delimited
    fields terminated by ',';
    load data local inpath '/home/hadoop/v_time.txt' into table v_time;
    • 1
    • 2
    • 3
    • 4

    在实际生产中,究竟需要哪些统计指标通常由相关数据需求部门人员提出,而且会不断有新的统计需求产生,以下为网站流量分析中的一些典型指标示例。

    1. PV统计

    1.1 多维度统计PV总量

    1. 时间维度

    --计算指定的某个小时pvs
    select count(*),month,day,hour from dw_click.ods_weblog_detail group by month,day,hour;
    
    
    --计算该处理批次(一天)中的各小时pvs
    drop table dw_pvs_hour;
    create table dw_pvs_hour(month string,day string,hour string,pvs bigint) partitioned by(datestr string);
    
    insert into table dw_pvs_hour partition(datestr='2016-03-18')
    select a.month as month,a.day as day,a.hour as hour,count(1) as pvs from ods_weblog_detail a
    where  a.datestr='2016-03-18'  group by a.month,a.day,a.hour;
    
    或者用时间维表关联
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    维度:日

    drop table dw_pvs_day;
    create table dw_pvs_day(pvs bigint,month string,day string);
    
    insert into table dw_pvs_day
    select count(1) as pvs,a.month as month,a.day as day  from dim_time a
    join ods_weblog_detail b 
    on b.dd='18/Sep/2013' and a.month=b.month and a.day=b.day
    group by a.month,a.day;
    
    --或者,从之前算好的小时结果中统计
    Insert into table dw_pvs_day
    Select sum(pvs) as pvs,month,day from dw_pvs_hour group by month,day having day='18';
    结果如下:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    维度:月

    drop table t_display_pv_month;
    create table t_display_pv_month (pvs bigint,month string);
    insert into table t_display_pv_month
    select count(*) as pvs,a.month from t_dim_time a
    join t_ods_detail_prt b on a.month=b.month group by a.month;
    • 1
    • 2
    • 3
    • 4
    • 5

    2. 按终端维度统计pv总量

    注:探索数据中的终端类型

    select distinct(http_user_agent) from ods_weblog_detail where http_user_agent like '%Mozilla%' limit 200;
    • 1

    终端维度:uc

    drop table t_display_pv_terminal_uc;
    create table t_display_pv_ terminal_uc (pvs bigint,mm string,dd string,hh string);
    • 1
    • 2

    终端维度:chrome

    drop table t_display_pv_terminal_chrome;
    create table t_display_pv_ terminal_ chrome (pvs bigint,mm string,dd string,hh string);
    • 1
    • 2

    终端维度:safari

    drop table t_display_pv_terminal_safari;
    create table t_display_pv_ terminal_ safari (pvs bigint,mm string,dd string,hh string);
    • 1
    • 2
    1. 按栏目维度统计pv总量

    栏目维度:job

    栏目维度:news

    栏目维度:bargin

    栏目维度:lane

    1.2 人均浏览页数**

    需求描述:比如,今日所有来访者,平均请求的页面数

    –总页面请求数/去重总人数

    drop table dw_avgpv_user_d;
    create table dw_avgpv_user_d(
    day string,
    avgpv string);
    
    insert into table dw_avgpv_user_d
    select '2013-09-18',sum(b.pvs)/count(b.remote_addr) from
    (select remote_addr,count(1) as pvs from ods_weblog_detail where datestr='2013-09-18' group by remote_addr) b;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.3 按referer维度统计pv总量

    需求:按照来源及时间维度统计PVS,并按照PV大小倒序排序

    – 按照小时粒度统计,查询结果存入:( “dw_pvs_referer_h” )

    drop table dw_pvs_referer_h;
    create table dw_pvs_referer_h(referer_url string,referer_host string,month string,day string,hour string,pv_referer_cnt bigint) partitioned by(datestr string);
    
    insert into table dw_pvs_referer_h partition(datestr='2016-03-18')
    select http_referer,ref_host,month,day,hour,count(1) as pv_referer_cnt
    from ods_weblog_detail 
    group by http_referer,ref_host,month,day,hour 
    having ref_host is not null
    order by hour asc,day asc,month asc,pv_referer_cnt desc;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    按天粒度统计各来访域名的访问次数并排序

    drop table dw_ref_host_visit_cnts_h;
    create table dw_ref_host_visit_cnts_h(ref_host string,month string,day string,hour string,ref_host_cnts bigint) partitioned by(datestr string);
    
    insert into table dw_ref_host_visit_cnts_h partition(datestr='2016-03-18')
    select ref_host,month,day,hour,count(1) as ref_host_cnts
    from ods_weblog_detail 
    group by ref_host,month,day,hour 
    having ref_host is not null
    order by hour asc,day asc,month asc,ref_host_cnts desc;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注:还可以按来源地域维度、访客终端维度等计算

    1.4 统计pv总量最大的来源TOPN

    需求描述:按照时间维度,比如,统计一天内产生最多pvs的来源topN

    需要用到row_number函数

    以下语句对每个小时内的来访host次数倒序排序标号,

    select ref_host,ref_host_cnts,concat(month,hour,day),

    row_number() over (partition by concat(month,hour,day) order by ref_host_cnts desc) as od

    from dw_ref_host_visit_cnts_h

    效果如下:

    根据上述row_number的功能,可编写Hql取各小时的ref_host访问次数topn

    drop table dw_pvs_refhost_topn_h;
    create table dw_pvs_refhost_topn_h(
    hour string,
    toporder string,
    ref_host string,
    ref_host_cnts string
    ) partitioned by(datestr string);
    
    insert into table zs.dw_pvs_refhost_topn_h partition(datestr='2016-03-18')
    select t.hour,t.od,t.ref_host,t.ref_host_cnts from
     (select ref_host,ref_host_cnts,concat(month,day,hour) as hour,
    row_number() over (partition by concat(month,day,hour) order by ref_host_cnts desc) as od 
    from zs.dw_ref_host_visit_cnts_h) t where od<=3;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果如下:

    * *

    注:还可以按来源地域维度、访客终端维度等计算

    2. 受访分析

    统计每日最热门的页面top10

    drop table dw_pvs_d;
    create table dw_pvs_d(day string,url string,pvs string);
    
    insert into table dw_pvs_d
    select '2013-09-18',a.request,a.request_counts from
    (select request as request,count(request) as request_counts from ods_weblog_detail where datestr='2013-09-18' group by request having request is not null) a
    order by a.request_counts desc limit 10;
    
    结果如下:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    注:还可继续得出各维度交叉结果

    3. 访客分析

    3.1 独立访客

    需求描述:按照时间维度比如小时来统计独立访客及其产生的pvCnts

    对于独立访客的识别,如果在原始日志中有用户标识,则根据用户标识即很好实现;

    此处,由于原始日志中并没有用户标识,以访客IP来模拟,技术上是一样的,只是精确度相对较低

    时间维度:时

    drop table dw_user_dstc_ip_h;
    create table dw_user_dstc_ip_h(
    remote_addr string,
    pvs      bigint,
    hour     string);
    
    insert into table dw_user_dstc_ip_h 
    select remote_addr,count(1) as pvs,concat(month,day,hour) as hour 
    from ods_weblog_detail
    Where datestr='2013-09-18'
    group by concat(month,day,hour),remote_addr;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在此结果表之上,可以进一步统计出,每小时独立访客总数,每小时请求次数topn访客等

    select count(1) as dstc_ip_cnts,hour from dw_user_dstc_ip_h group by hour;
    • 1

    如每小时独立访客总数:

    时间维度:月

    select remote_addr,count(1) as counts,month 
    from ods_weblog_detail
    group by month,remote_addr;
    • 1
    • 2
    • 3

    时间维度:日

    select remote_addr,count(1) as counts,concat(month,day) as day
    from ods_weblog_detail
    Where dd='18/Sep/2013'
    group by concat(month,day),remote_addr;
    • 1
    • 2
    • 3
    • 4

    注:还可以按来源地域维度、访客终端维度等计算

    3.2 每日新访客

    需求描述:将每天的新访客统计出来

    实现思路:创建一个去重访客累积表,然后将每日访客对比累积表

    时间维度:日

    --历日去重访客累积表
    drop table dw_user_dsct_history;
    create table dw_user_dsct_history(
    day string,
    ip string
    ) 
    partitioned by(datestr string);
    
    --每日新用户追加到累计表
    drop table dw_user_dsct_history;
    create table dw_user_dsct_history(
    day string,
    ip string
    ) 
    partitioned by(datestr string);
    
    --每日新用户追加到累计表
    insert into table dw_user_dsct_history partition(datestr='2013-09-19')
    select tmp.day as day,tmp.today_addr as new_ip from
    (
    select today.day as day,today.remote_addr as today_addr,old.ip as old_addr 
    from 
    (select distinct remote_addr as remote_addr,"2013-09-19" as day from ods_weblog_detail where datestr="2013-09-19") today
    left outer join 
    dw_user_dsct_history old
    on today.remote_addr=old.ip
    ) tmp
    where tmp.old_addr is null;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    验证:

    select count(distinct remote_addr) from ods_weblog_detail;
    -- 1005
    
    select count(1) from dw_user_dsct_history where prtflag_day='18/Sep/2013';
    --845
    
    select count(1) from dw_user_dsct_history where prtflag_day='19/Sep/2013';
    --160
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    时间维度:月

    类似日粒度算法
    • 1

    注:还可以按来源地域维度、访客终端维度等计算

    4. Visit分析(点击流模型)

    4.2 回头/单次访客统计

    需求描述:查询今日所有回头访客及其访问次数

    实现思路:上表中出现次数>1的访客,即回头访客;反之,则为单次访客

    drop table dw_user_returning;
    create table dw_user_returning(
    day string,
    remote_addr string,
    acc_cnt string)
    partitioned by (datestr string);
    
    insert overwrite table dw_user_returning partition(datestr='2013-09-18')
    
    select tmp.day,tmp.remote_addr,tmp.acc_cnt
    from
    (select '2013-09-18' as day,remote_addr,count(session) as acc_cnt from click_stream_visit group by remote_addr) tmp
    where tmp.acc_cnt>1;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.3 人均访问频次

    需求:统计出每天所有用户访问网站的平均次数(visit)

    总visit数/去重总用户数

    select sum(pagevisits)/count(distinct remote_addr) from click_stream_visit partition(datestr='2013-09-18');
    • 1

    5. Visit分析另一种实现方式**

    5.1mr程序识别出访客的每次访问

    a.) 首先开发MAPREDUCE程序:UserStayTime

    注:代码略长,见项目工程代码                                                   
    • 1

    b.) 提交MAPREDUCE程序进行运算

    [hadoop@hdp-node-01 ~]$ hadoop jar weblog.jar cn.it.bigdata.hive.mr.UserStayTime /weblog/input /weblog/stayout4
    --导入hive表("t_display_access_info")中
    drop table ods_access_info;
    create table ods_access_info(remote_addr string,firt_req_time string,last_req_time string,stay_long string)
    partitioned by(prtflag_day string)
    row format delimited
    fields terminated by '\t';
    
    load data inpath '/weblog/stayout4' into table ods_access_info partition(prtflag_day='18/Sep/2013');
    创建表时stay_long使用的string类型,但是在后续过程中发现还是用bigint更好,进行表修改
    alter table ods_access_info change column stay_long stay_long bigint;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5.2 将mr结果导入访客访问信息表 “t_display_access_info”

    由于有一些访问记录是单条记录,mr程序处理处的结果给的时长是0,所以考虑给单次请求的停留时间一个默认市场30秒

    drop table dw_access_info;
    create table dw_access_info(remote_addr string,firt_req_time string,last_req_time string,stay_long string)
    partitioned by(prtflag_day string);
    
    insert into table dw_access_info partition(prtflag_day='19/Sep/2013')
    select remote_addr,firt_req_time,last_req_time,
    case stay_long
    when 0 then 30000
    else stay_long
    end as stay_long
    from ods_access_info
    where prtflag_day='18/Sep/2013';
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在访问信息表的基础之上,可以实现更多指标统计,如:

    统计所有用户停留时间平均值,观察用户在站点停留时长的变化走势

    select prtflag_day as dt,avg(stay_long) as avg_staylong

    from dw_access_info group by prtflag_day;

    5.3 回头/单次访客统计

    注:从上一步骤得到的访问信息统计表“**dw**_access_info”中查询

    –回头访客访问信息表 “dw_access_info_htip”

    drop table dw_access_info_htip;
    create table dw_access_info_htip(remote_addr string, firt_req_time string, last_req_time string, stay_long string,acc_counts string)
    partitioned by(prtflag_day string);
    
    insert into table dw_access_info_htip partition(prtflag_day='18/Sep/2013')
    select b.remote_addr,b.firt_req_time,b.last_req_time,b.stay_long,a.acc_counts from 
    (select remote_addr,count(remote_addr) as acc_counts from dw_access_info where prtflag_day='18/Sep/2013' group by remote_addr having acc_counts>1) a
    join 
    dw_access_info b
    on a.remote_addr = b.remote_addr;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    –单次访客访问信息表 “dw_access_info_dcip”

    drop table dw_access_info_dcip;
    create table dw_access_info_dcip(remote_addr string, firt_req_time string, last_req_time string, stay_long string,acc_counts string)
    partitioned by(prtflag_day string);
    
    insert into table dw_access_dcip partition(prtflag_day='18/Sep/2013')
    select b.remote_addr,b.firt_req_time,b.last_req_time,b.stay_long,a.acc_counts from 
    (select remote_addr,count(remote_addr) as acc_counts from dw_access_info where prtflag_day='18/Sep/2013' group by remote_addr having acc_counts<2) a
    join 
    dw_access_info b
    on a.remote_addr = b.remote_addr;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在回头/单词访客信息表的基础之上,可以实现更多统计指标,如:

    –当日回头客占比

    drop table dw_htpercent_d;
    create table dw_htpercent_d(day string,ht_percent float);
    
    Insert into table dw_htpercent_d
    select '18/Sep/2013',(tmp_ht.ht/tmp_all.amount)*100 from 
    (select count( distinct a.remote_addr) as ht from dw_access_info_htip a where prtflag_day='18/Sep/2013') tmp_ht 
    Join 
    (select count(distinct b.remote_addr) as amount from dw_access_info b where prtflag_day='18/Sep/2013') tmp_all;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.4 人均访问频度**

    –总访问次数/去重总人数,从访客次数汇总表中查询

    select avg(user_times.counts) as user_access_freq
    from
    (select remote_addr,counts from t_display_htip 
    union all
    select remote_addr,counts from t_display_access_dcip) user_times;
    
    --或直接从 访问信息表 t_display_access_info 中查询
    select avg(a.acc_cts) from 
    (select remote_addr,count(*) as acc_cts from dw_access_info group by remote_addr) a; 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    6.关键路径转化率分析——漏斗模型

    转化:在一条指定的业务流程中,各个步骤的完成人数及相对上一个步骤的百分比

    6.1 需求分析

    6.2 模型设计

    定义好业务流程中的页面标识,下例中的步骤为:

    Step1、 /item%

    Step2、 /category

    Step3、 /order

    Step4、 /index

    6.3 开发实现

    分步骤开发:

    1、查询每一个步骤的总访问人数

    create table route_numbs as 
    select 'step1' as step,count(distinct remote_addr)  as numbs from ods_click_pageviews where request like '/item%'
    union
    select 'step2' as step,count(distinct remote_addr) as numbs from ods_click_pageviews where request like '/category%'
    union
    select 'step3' as step,count(distinct remote_addr) as numbs from ods_click_pageviews where request like '/order%'
    union
    select 'step4' as step,count(distinct remote_addr)  as numbs from ods_click_pageviews where request like '/index%';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、查询每一步骤相对于路径起点人数的比例

    思路:利用join

    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs  from route_num rn
    inner join 
    route_num rr
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    select tmp.rnstep,tmp.rnnumbs/tmp.rrnumbs as ratio
    from
    (
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs  from route_num rn
    inner join 
    route_num rr) tmp
    where tmp.rrstep='step1';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、查询每一步骤相对于上一步骤的漏出率

    select tmp.rrstep as rrstep,tmp.rrnumbs/tmp.rnnumbs as ration
    from
    (
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs  from route_num rn
    inner join 
    route_num rr) tmp
    where cast(substr(tmp.rnstep,5,1) as int)=cast(substr(tmp.rrstep,5,1) as int)-1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    >

    4、汇总以上两种指标

    select abs.step,abs.numbs,abs.ratio as abs_ratio,rel.ratio as rel_ratio
    from 
    (
    select tmp.rnstep as step,tmp.rnnumbs as numbs,tmp.rnnumbs/tmp.rrnumbs as ratio
    from
    (
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs  from route_num rn
    inner join 
    route_num rr) tmp
    where tmp.rrstep='step1'
    ) abs
    left outer join
    (
    select tmp.rrstep as step,tmp.rrnumbs/tmp.rnnumbs as ratio
    from
    (
    select rn.step as rnstep,rn.numbs as rnnumbs,rr.step as rrstep,rr.numbs as rrnumbs  from route_num rn
    inner join 
    route_num rr) tmp
    where cast(substr(tmp.rnstep,5,1) as int)=cast(substr(tmp.rrstep,5,1) as int)-1
    ) rel
    on abs.step=rel.step
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    8 模块开发——结果导出

    报表统计结果,由sqoop从hive表中导出,示例如下,详见工程代码

    sqoop export \
    --connect jdbc:mysql://hdp-node-01:3306/webdb --username root --password root  \
    --table click_stream_visit  \
    --export-dir /user/hive/warehouse/dw_click.db/click_stream_visit/datestr=2013-09-18 \
    --input-fields-terminated-by '\001'
    • 1
    • 2
    • 3
    • 4
    • 5

    9 模块开发——工作流调度

    *注:将整个项目的数据处理过程,从数据采集到数据分析,再到结果数据的导出,一系列的任务分割成若干个oozie的工作流,并用coordinator进行协调

    工作流定义示例

    Ooize配置片段示例,详见项目工程

    1、日志预处理mr程序工作流定义

    <workflow-app name="weblogpreprocess" xmlns="uri:oozie:workflow:0.4">
    <start to="firstjob"/>
    <action name="firstjob">
    <map-reduce>
    <job-tracker>${jobTracker}</job-tracker>
    <name-node>${nameNode}</name-node>
    <prepare>
    <delete path="${nameNode}/${outpath}"/>
    </prepare>
    <configuration>
    <property>
    <name>mapreduce.job.map.class</name>
    <value>cn.it.bigdata.hive.mr.WeblogPreProcess$WeblogPreProcessMapper</value>
    </property>
    
    <property>
    <name>mapreduce.job.output.key.class</name>
    <value>org.apache.hadoop.io.Text</value>
    </property>
    <property>
    <name>mapreduce.job.output.value.class</name>
    <value>org.apache.hadoop.io.NullWritable</value>
    </property>
    
    <property>
    <name>mapreduce.input.fileinputformat.inputdir</name>
    <value>${inpath}</value>
    </property>
    <property>
    <name>mapreduce.output.fileoutputformat.outputdir</name>
    <value>${outpath}</value>
    </property>
    <property>
    <name>mapred.mapper.new-api</name>
    <value>true</value>
    </property>
    <property>
    <name>mapred.reducer.new-api</name>
    <value>true</value>
    </property>
    
    </configuration>
    </map-reduce>
    <ok to="end"/>
    <error to="kill"/>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    2、数据加载etl工作流定义:

    <workflow-app xmlns="uri:oozie:workflow:0.5" name="hive2-wf">
    <start to="hive2-node"/>
    
    <action name="hive2-node">
    <hive2 xmlns="uri:oozie:hive2-action:0.1">
    <job-tracker>${jobTracker}</job-tracker>
    <name-node>${nameNode}</name-node>
    <configuration>
    <property>
    <name>mapred.job.queue.name</name>
    <value>${queueName}</value>
    </property>
    </configuration>
    <jdbc-url>jdbc:hive2://hdp-node-01:10000</jdbc-url>
    <script>script.q</script>
    <param>input=/weblog/outpre2</param>
    </hive2>
    <ok to="end"/>
    <error to="fail"/>
    </action>
    
    <kill name="fail">
    <message>Hive2 (Beeline) action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>
    <end name="end"/>
    </workflow-app>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3、数据加载工作流所用hive脚本:

    create database if not exists dw_weblog;
    use dw_weblog;
    drop table if exists t_orgin_weblog;
    create table t_orgin_weblog(valid string,remote_addr string,
    remote_user string,
    time_local string,
    request string,
    status string,
    body_bytes_sent string,
    http_referer string,
    http_user_agent string)
    row format delimited
    fields terminated by '\001';
    load data inpath '/weblog/preout' overwrite into table t_orgin_weblog;
    
    drop table if exists t_ods_detail_tmp_referurl;
    create table t_ods_detail_tmp_referurl as
    SELECT a.*,b.*
    FROM t_orgin_weblog a 
    LATERAL VIEW parse_url_tuple(regexp_replace(http_referer, "\"", ""), 'HOST', 'PATH','QUERY', 'QUERY:id') b as host, path, query, query_id;
    
    drop table if exists t_ods_detail;
    create table t_ods_detail as 
    select b.*,substring(time_local,0,11) as daystr,
    substring(time_local,13) as tmstr,
    substring(time_local,4,3) as month,
    substring(time_local,0,2) as day,
    substring(time_local,13,2) as hour
    from t_ods_detail_tmp_referurl b;
    
    drop table t_ods_detail_prt;
    create table t_ods_detail_prt(
    valid                  string,
    remote_addr            string,
    remote_user            string,
    time_local             string,
    request                string,
    status                 string,
    body_bytes_sent        string,
    http_referer           string,
    http_user_agent        string,
    host                   string,
    path                   string,
    query                  string,
    query_id               string,
    daystr                 string,
    tmstr                  string,
    month                  string,
    day                    string,
    hour                   string) 
    partitioned by (mm string,dd string);
    
    
    insert into table t_ods_detail_prt partition(mm='Sep',dd='18')
    select * from t_ods_detail where daystr='18/Sep/2013';
    insert into table t_ods_detail_prt partition(mm='Sep',dd='19')
    select * from t_ods_detail where daystr='19/Sep/2013';
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    更多工作流及hql脚本定义详见项目工程

    工作流单元测试

    1、工作流定义配置上传

    [hadoop@hdp-node-01 wf-oozie]$ hadoop fs -put hive2-etl /user/hadoop/oozie/myapps/
    [hadoop@hdp-node-01 wf-oozie]$ hadoop fs -put hive2-dw /user/hadoop/oozie/myapps/ 
    [hadoop@hdp-node-01 wf-oozie]$ ll
    total 12
    drwxrwxr-x. 2 hadoop hadoop 4096 Nov 23 16:32 hive2-dw
    drwxrwxr-x. 2 hadoop hadoop 4096 Nov 23 16:32 hive2-etl
    drwxrwxr-x. 3 hadoop hadoop 4096 Nov 23 11:24 weblog
    [hadoop@hdp-node-01 wf-oozie]$ export OOZIE_URL=http://localhost:11000/oozie
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、工作流单元提交启动

    oozie job -D inpath=/weblog/input -D outpath=/weblog/outpre -config weblog/job.properties  -run
    
    启动etl的hive工作流
    
    oozie job -config hive2-etl/job.properties  -run
    
    启动pvs统计的hive工作流
    
    oozie job -config hive2-dw/job.properties  -run
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、工作流coordinator配置(片段)

    多个工作流job用coordinator组织协调:

    [hadoop@hdp-node-01 hive2-etl]$ ll
    total 28
    -rw-rw-r--. 1 hadoop hadoop  265 Nov 13 16:39 config-default.xml
    -rw-rw-r--. 1 hadoop hadoop  512 Nov 26 16:43 coordinator.xml
    -rw-rw-r--. 1 hadoop hadoop  382 Nov 26 16:49 job.properties
    drwxrwxr-x. 2 hadoop hadoop 4096 Nov 27 11:26 lib
    -rw-rw-r--. 1 hadoop hadoop 1910 Nov 23 17:49 script.q
    -rw-rw-r--. 1 hadoop hadoop  687 Nov 23 16:32 workflow.xml
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    l config-default.xml

    <configuration>
    <property>
    <name>jobTracker</name>
    <value>hdp-node-01:8032</value>
    </property>
    <property>
    <name>nameNode</name>
    <value>hdfs://hdp-node-01:9000</value>
    </property>
    <property>
    <name>queueName</name>
    <value>default</value>
    </property>
    </configuration>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    l job.properties

    user.name=hadoop
    oozie.use.system.libpath=true
    oozie.libpath=hdfs://hdp-node-01:9000/user/hadoop/share/lib
    oozie.wf.application.path=hdfs://hdp-node-01:9000/user/hadoop/oozie/myapps/hive2-etl/
    • 1
    • 2
    • 3
    • 4

    l workflow.xml

    <workflow-app xmlns="uri:oozie:workflow:0.5" name="hive2-wf">
    <start to="hive2-node"/>
    
    <action name="hive2-node">
    <hive2 xmlns="uri:oozie:hive2-action:0.1">
    <job-tracker>${jobTracker}</job-tracker>
    <name-node>${nameNode}</name-node>
    <configuration>
    <property>
    <name>mapred.job.queue.name</name>
    <value>${queueName}</value>
    </property>
    </configuration>
    <jdbc-url>jdbc:hive2://hdp-node-01:10000</jdbc-url>
    <script>script.q</script>
    <param>input=/weblog/outpre2</param>
    </hive2>
    <ok to="end"/>
    <error to="fail"/>
    </action>
    
    <kill name="fail">
    <message>Hive2 (Beeline) action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>
    <end name="end"/>
    </workflow-app>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    l coordinator.xml

    <coordinator-app name="cron-coord" frequency="${coord:minutes(5)}" start="${start}" end="${end}" timezone="Asia/Shanghai" xmlns="uri:oozie:coordinator:0.2">
    <action>
    <workflow>
    <app-path>${workflowAppUri}</app-path>
    <configuration>
    <property>
    <name>jobTracker</name>
    <value>${jobTracker}</value>
    </property>
    <property>
    <name>nameNode</name>
    <value>${nameNode}</value>
    </property>
    <property>
    <name>queueName</name>
    <value>${queueName}</value>
    </property>
    </configuration>
    </workflow>
    </action>
    </coordinator-app>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    10 模块开发——数据展示

    在企业的数据分析系统中,前端展现工具有很多,

    l 独立部署专门系统的方式:以Business Objects(BO,Crystal Report),Heperion(Brio),Cognos等国外产品为代表的,它们的服务器是单独部署的,与应用程序之间通过某种协议沟通信息

    l 有WEB程序展现方式:通过独立的或者嵌入式的java web系统来读取报表统计结果,以网页的形式对结果进行展现,如,100%纯Java的润乾报表

    本日志分析项目采用自己开发web程序展现的方式

    Web展现程序采用的技术框架:

    Jquery + Echarts + springmvc + spring + mybatis + mysql

    展现的流程:

    1. 使用ssh从mysql中读取要展现的数据

    2. 使用json格式将读取到的数据返回给页面

    3. 在页面上用echarts对json解析并形成图标

    **W**eb程序工程结构

    采用maven管理工程,引入SSH框架依赖及jquery+echarts的js库

    **W**eb程序的实现代码

    采用典型的MVC架构实现

    页面HTML + JQUERY + ECHARTS
    ControllerSpringMVC
    ServiceService
    DAOMybatis
    数据库Mysql

    代码详情见项目工程

    **代码示例:**ChartServiceImpl

    **W**eb程序的展现效果

    网站概况

    流量分析

    来源分析

    访客分析

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35559756/article/details/78033111
     

    网站点击流数据分析项目

    • u014033218
    • u014033218
    • 2017年08月07日 15:05
    • 4801
    什么是点击流数据 1.1.1 WEB访问日志 即指用户访问网站时的所有访问、浏览、点击行为数据。比如点击了哪一个链接,在哪个网页停留时间最多,采用了哪个搜索项、总体浏览时间等。而所有这些信息都可被...

    电子商务网站点击流分析

    • luyafei_89430
    • luyafei_89430
    • 2013年07月09日 09:18
    • 2982
    电子商务网站点击流分析 [导读]在用户查看网页时,通过利用点击流(Clickstream)数据仓库手段,构建点击流数据仓库维模型,分析了网站用户的消费行为、兴趣偏好,从而进一步优化网站的内容和...

    网站点击流数据分析项目

    • 2017年12月15日 18:30
    • 1.52MB
    • 下载

    实战hadoop海量数据处理系列05 : 实现点击流日志的数据清洗模块

    实战hadoop海量数据处理系列05 : 实现点击流日志的数据清洗模块之前已经实现结构化数据的清洗,下一步我们将实现半结构化(非结构化)数据的清洗。在阅读本文前,强烈建议阅读原书“实现点击流日志的数据...
    • titer1
    • titer1
    • 2017年06月10日 21:02
    • 1930

    点击流数据仓库

    • 2008年07月24日 09:47
    • 15.16MB
    • 下载

    一秒创造无法计算的价值

    每满2000返200,最高返5000元代金券

    (3)Storm实时日志分析实战--编码实现

    • fjse51
    • fjse51
    • 2016年12月27日 11:08
    • 1372
    LogParserBolt类package com.ibeifeng.bigdata.storm.weglog;import backtype.storm.task.OutputCollector; ...

    storm用来做实时日志分析的浅显使用

    • fenglvming
    • fenglvming
    • 2016年07月11日 22:54
    • 3217
    公司的nginx日志的主要使用者是BI部门。他们可以通过日志进行一些数据方面的统计和分析。 而我们基础架构对nginx的日志分析,主要是考虑以下几点: 1. 有针对的进行日志收集和分析,比如针对核心业...

    查看storm运行日志

    • asdfsadfasdfsa
    • asdfsadfasdfsa
    • 2017年03月07日 20:24
    • 5745
    submit日志在nimbus.log生成work命令行的日志输出在supervisor.log 程序运行时的日志在work-xxx.log 用storm jar ...将项目提交...

    (1)Storm实时日志分析实战--项目准备

    • fjse51
    • fjse51
    • 2016年12月23日 16:55
    • 1471
    流程图Flume收集Nginx的日志,然后存在Kafka队列中,由storm读取Kafka中的日志信息,经过相关处理后,保存到HBase和MySQL中安装步骤Kafka 从官网下载安装包, 解压到安装...

    storm 实时日志分析导图

    • lm709409753
    • lm709409753
    • 2016年12月28日 21:24
    • 248

    实时收集Storm日志到ELK集群

    • u010454030
    • u010454030
    • 2016年11月22日 19:01
    • 934
    背景 我们的storm实时流计算项目已经上线几个月了,由于各种原因迟迟没有进行监控,每次出现问题都要登录好几台机器,然后使用sed,shell,awk,vi等各种命令来查询原因,效率非常低下,而...

    JS实现点击事件统计

    • sugang_ximi
    • sugang_ximi
    • 2016年06月15日 09:53
    • 2721
    JS实现网站点击事件的统计功能。 /** * 点击事件上报,分为立即上报和延时上报,延时上报通过cookie存储。 * * 一、配置参数,主要用于定义上报的一些配置信息。通过在外部定...

    电子商务网站的数据仓库BI项目之点击流数据仓库

    • gsnidi2002
    • gsnidi2002
    • 2008年09月26日 11:43
    • 849
          如今,网络已经成为很多人必不可少的对外窗口,特别是电子商务网站比如(淘宝,携程等等),大家会经常在这些网站的网页上进行浏览。然而,你的这些看似浏览的行为,确把你内心中的商业目标暴露了出来。...

    基于SparkStreaming的实时数据清洗

    • weixin_39911113
    • weixin_39911113
    • 2017年11月22日 11:46
    • 433
    数据清洗, 是整个数据分析过程中不可缺少的一个环节,其结果质量直接关系到模型效果和最终结论。在实际操作中,数据清洗通常会占据分析过程的50%—80%的时间。实时数据清洗则对于代码的性能更加的苛求。...

    网站日志分析项目案例(一)项目介绍

    • u011007180
    • u011007180
    • 2016年11月28日 20:35
    • 782
    一、数据情况分析 1.1 数据情况回顾   该论坛数据有两部分:   (1)历史数据约56GB,统计到2012-05-29。这也说明,在2012-05-29之前,日志文件都在一个文件...

    网站日志统计案例分析与实现

    • LW_GHY
    • LW_GHY
    • 2016年03月11日 23:31
    • 1969
    一、Web日志包含着网站最重要的信息,通过日志分析,我们可以知道网站的访问量,哪个网页访问人数最多,哪个网页最有价值等。一般中型的网站(10w的PV以上),每天会产生1G以上的Web日志文件。大型或超...

    大数据Web日志分析 用Hadoop统计KPI指标实例

    可以带着下面问题来阅读文章 问题: 1.MapReduce在日志分析的作用 思考: 该如何架构kpi系统,需要考虑什么问题。 kpi:关键绩效指标法,即KPI绩效考核,是企业绩效...
    • u011007180
    • u011007180
    • 2016年11月28日 21:09
    • 4432

    从日志统计到大数据分析

    • dajiangtai007
    • dajiangtai007
    • 2016年12月22日 16:44
    • 1532
    桑文锋,神策数据创始人&CEO,前百度大数据部技术经理。2007年浙大研究生毕业后加入百度,从2008年开始从事数据方向,从零构建了百度的用户日志大数据处理平台。2015年4月从百度离职,创建神策数据...

    hive常用UDF and UDTF函数介绍-lateral view explode()

    前言: Hive是基于Hadoop中的MapReduce,提供HQL查询的数据仓库。这里只大概说下Hive常用到的UDF函数,全面详细介绍推荐官网wiki:https://cwiki.apache.o...
    • zeb_perfect
    • zeb_perfect
    • 2016年11月23日 14:13
    • 4063

    点击流日志分析项目实战开发流程

    • u014033218
    • u014033218
    • 2017年08月10日 12:55
    • 174
    step-1: 使用flume采集数据到 /flume/events/%y-%m-%d/下面 flume配置 tail-hdfs.conf用tail命令获取数据,下沉到hdfs 启动命令: bi...
    等级: 
    3级,点击查看等级说明
    访问量:  3万+
    积分:  985
    排名:  5万+

    文章分类

    展开

    文章存档

    展开
    展开全文
  • 用机器学习检测异常点击流

    千次阅读 2017-09-14 20:50:39
    项目的目标是从点击流数据中找出恶意用户的请求。点击流数据长下图这样子,包括请求时间、IP、平台等特征: 该项目从开始做到阶段性完成,大致可分为两个阶段:算法选择和工程优化。算法选择阶段挑选合适的...

    本文内容是我学习ML时做的一个练手项目,描述应用机器学习的一般步骤。该项目的目标是从点击流数据中找出恶意用户的请求。点击流数据长下图这样子,包括请求时间、IP、平台等特征:

    该项目从开始做到阶段性完成,大致可分为两个阶段:算法选择和工程优化。算法选择阶段挑选合适的ML模型,尝试了神经网络、高斯分布、Isolation Forest等三个模型。由于点击流数据本身的特性,导致神经网络和高斯分布并不适用于该场景,最终选择了Isolation Forest。工程优化阶段,最初使用单机训练模型和预测结果,但随着数据量的增加,最初的单机系统出现了性能瓶颈;然后开始优化性能,尝试了分布化训练,最终通过单机异步化达到了性能要求。

    1 算法选择

    1.1 神经网络

    刚开始没经验,受TensorFlow热潮影响,先尝试了神经网络。选用的神经网络是MLP(Multilayer Perceptron,多层感知器),一种全连接的多层网络。MLP是有监督学习,需要带标签的样本,这里“带标签”的意思是样本数据标注了哪些用户请求是恶意的、哪些是正常的。但后台并没有现成带标签的恶意用户样本数据。后来通过安全侧的一些数据“间接”给用户请求打上了标签,然后选择IP、平台、版本号、操作码等数据作为MLP的输入数据。结果当然是失败,想了下原因有两个:

    1, 样本的标签质量非常差,用这些样本训练出来的模型性能当然也很差;

    2, 输入的特征不足以刻画恶意用户。

    数据的质量问题目前很难解决,所以只能弃用MLP。

    1.2 高斯分布

    然后尝试其他模型。通过搜索发现,有一类ML模型专门用于异常检测,找到了Andrew Ng介绍的基于高斯分布的异常检测算法:https://www.coursera.org/learn/machine-learning/home/week/9 。高斯分布如下图所示:

    这个算法的思想比较简单:与大部分样本不一致的样本就是异常;通过概率密度量化“不一致”。具体做法是:选择符合高斯分布或能转换为高斯分布的特征,利用收集到的数据对高斯分布做参数估计,把概率密度函数值小于某个阈值的点判定为异常。

    所谓的参数估计是指,给定分布数据,求分布的参数。对高斯分布来说,就是求μ和σ。用极大似然估计可以得到高斯分布参数的解析解:

    得到高斯分布参数后,用下式计算概率密度:

    X表示一个特征输入。若有多个特征x0、x1、…、xn,一种简单的处理方法是将其结果连乘起来即可:f(x) = f(x0)f(x1)…f(xn)。

    然后选定一个阈值ε,把f(x) < ε的样本判定为异常。ε值需根据实际情况动态调整,默认可设定ε = f(μ- 3σ)。

    把这个模型初步应用于点击流异常检测时,效果还不错,但在进一步实施过程中碰到一个棘手问题:样本中最重要的一个特征是操作码,当前操作码在微信后台的取值范围是[101, 1000],每个操作码的请求次数是模型的基础输入,对900个特征计算概率密度再相乘,非常容易导致结果下溢出,以致无法计算出精度合适的概率密度值。这个现象被称为维度灾难(Dimension Disaster)。

    解决维度灾难的一个常见做法是降维,降维的手段有多种,这里不展开讨论了。在点击流分析的实践中,降维的效果并不好,主要原因有两个:

    1, 正常用户和恶意用户的访问模式并不固定,导致很难分解出有效的特征矩阵或特征向量;

    2, 降维的本质是有损压缩,有损压缩必定导致信息丢失。但在本例中每一维的信息都是关键信息,有损压缩会极大破坏样本的有效性。

    高斯分布模型的维度灾难在本例中较难解决,只能再尝试其他模型了。

    1.3 Isolation Forest

    Isolation Forest,可翻译为孤异森林,该算法的基本思想是:随机选择样本的一个特征,再随机选择该特征取值范围中的一个值,对样本集做拆分,迭代该过程,生成一颗Isolation Tree;树上叶子节点离根节点越近,其异常值越高。迭代生成多颗Isolation Tree,生成Isolation Forest,预测时,融合多颗树的结果形成最终预测结果。Isolation Forest的基础结构有点类似经典的随机森林(Random Forest)。算法的细节见这里:http://cs.nju.edu.cn/zhouzh/zhouzh.files/publication/icdm08b.pdf。

    这个异常检测模型有效利用了异常样本“量少”和“与正常样本表现不一样”的两个特点,不依赖概率密度因此不会导致高维输入的下溢出问题。提取少量点击流样本测试,它在900维输入的情况下也表现良好,最终选择它作为系统的模型。

    2 工程优化

    工程实现经历了单机训练、分布式训练、单机异步化训练3个方案,下面内容介绍实现过程中碰到的问题和解决方法。

    2.1 单机训练

    整个系统主要包括收集数据、训练模型、预测异常、上报结果四个部分。

    2.1.1 收集数据

    刚开始尝试该模型时,是通过手工方式从mmstreamstorage获取样本的:

    1,通过logid 11357,得到手工登录成功用户的uin和登录时间;

    2,利用mmstreamstorage提供的接口,得到用户登录后10分钟的点击流;

    但这样做有两个缺点:

    1,上述步骤1是离线手工操作的,需要做成自动化;

    2,mmstreamstorage的接口性能较差,只能提供2万/min的查询性能,上海IDC登录的峰值有9万/min。

    改进办法是复用点击流上报模块mmstreamstorage,增加一个旁路数据的逻辑:

    1,手工登录时在presence中记录手工登录时间,mmstreamstorage基于该时间旁路一份数据给mmguardstore。由于mmstreamstorage每次只能提供单挑点击流数据,所以需要在mmguardstore中缓存;

    2,mmguardstore做完数据清洗和特征提取,然后把样本数据落地,最后利用crontab定期将该数据同步到Hadoop集群中。

    最终的数据收集模块结构图如下所示:

    点击流数据提供了IP、平台、版本号、操作码等特征,经过多次试验,选定用户手工登录后一段时间内操作码的访问次数作为模型的输入。

    上面我们提到过点击流的操作码有900个有效取值,所以一个显然的处理方法是,在mmguardstore中把用户的点击流数据转化为一个900维的向量,key是cgi id,value是对应cgi的访问次数。该向量刻画了用户的行为,可称为行为特征向量。

    2.1.2 训练模型

    初起为了控制不确定性,只输入1万/分钟的样本给模型训练和预测。系统的工作流程是先从Hadoop加载上一分钟的样本数据,然后用数据训练Isolation Forest模型,最后用训练好的模型做异常检测,并将检测结果同步到tdw。

    在1万/分钟输入下取得较好的检测结果后,开始导入全量数据,全量数据数据的峰值为20万/分钟左右。出现的第一个问题是,一分钟内无法完成加载数据、训练模型、预测结果,单加载数据就耗时10分钟左右。这里先解释下为什么有“一分钟”的时间周期限制,主要原因有两个:

    1, 想尽快获取检测结果;

    2, 由于点击流异常检测场景的特殊性,模型性能有时效性,需要经常用最新数据训练新的模型。

    解决性能问题的第一步是要知道性能瓶颈在哪里,抽样发现主要是加载数据和训练模型耗时较多,预测异常和上报结果的耗时并没有随数据量的增加而快速上涨。

    加载数据的耗时主要消耗在网络通信上:样本文件太大了,导致系统从Hadoop同步样本数据时碰到网络带宽瓶颈。但由于样本是文本类数据,对数据先压缩再传输可极大减少通信量,这里的耗时比较容易优化。

    训练模型的耗时增加源于输入数据量的增加。下图是1万样本/min的输入下,系统个阶段的耗时:

    其中:
    加载程序: 2s
    加载数据: 6s
    训练模型:11s
    分类异常: 2s
    保存结果: 4s
    单轮总耗时:25s
    需处理全量数据时,按线性关系换算,“训练模型”耗时为:11s * 24 = 264s,约为4.4分钟,单机下无法在1分钟内完成计算。
    最先想到的优化训练模型耗时的办法是分布式训练。

    2.2 分布式训练

    由于scikit-learn只提供单机版的Isolation Forest实现,所以只能自己实现它的分布式版本。了解了下目前最常用的分布式训练方法是参数服务器(Parameter Server,PS)模式,其想法比较简单:训练模型并行跑在多机上,训练结果在PS合并。示意图如下所示:

    分布式训练对算法有一定要求,而Isolation Forest正好适用于分布式训练。

    然后尝试在TensorFlow上实现Isolation Forest的分布式训练版本。选择TensorFlow的原因有主要两个:

    1, TensorFlow已经实现了一个分布式训练框架;

    2, TensorFlow的tf.contrib.learn包已经实现的Random Forest可作参考(Isolation Forest在结构上与Random Forest类似),只需对Isolation Forest定制一个Operation即可(Op的细节看这里:https://www.tensorflow.org/how_tos/adding_an_op/)。

    写完代码测试时,发现了个巨坑的问题:TenforFlow内部的序列化操作非常频繁、性能十分差。构造了110个测试样本,scikit-learn耗时只有0.340秒,29万次函数调用;而TensorFlow耗时达207.831秒,有2.48亿次函数调用。

    TensorFlow性能抽样:

    Scikit-learn性能抽样:

    从TensorFlow的性能抽样数据可以看到,耗时排前排的函数都不是实现Isolation Forest算法的函数,其原因应该与TensorFlow基于Graph、Session的实现方式有关。感觉这里坑比较深,遂放弃填坑。

    也了解了下基于Spark的spark-sklearn,该项目暂时还未支持Isolation Forest,也因为坑太深,一时半会搞不定而放弃了。

    2.3 单机异步化训练

    没搞定分布式训练,只能回到单机场景再想办法。单机优化有两个着力点:优化算法实现和优化系统结构。

    首先看了下scikit-learn中Isoaltion Forest的实现,底层专门用Cython优化了,再加上Joblib库的多CPU并行,算法实现上的优化空间已经很小了,只能从系统结构上想办法。

    系统结构上的优化有两个利器:并行化和异步化。之前的单机模型,加载数据、训练模型、预测异常、上报结果在单进程中串行执行,由此想到的办法是启动4个工作进程分别处理相应的四个任务:异步训练模型、预测异常和上报结果,并行加载数据。工作进程之间用队列通信,队列的一个优势是容易实现流量控制。

    写完代码测试,却发现YARD环境中的Python HDFS库在多进程并发下直接抛异常。尝试多个方法发现这个问题较难解决,暂时只能想办法规避。经测试发现,直接从Hadoop同步所有压缩过的样本数据只需2秒左右,由此想到规避方法是:先单进程同步所有样本数据,再多进程并发解压、加载和预测。

    按上述想法修改代码测试,效果较好,处理所有样本只需20秒左右,达到了1分钟处理完所有样本的要求。然后提交YARD作业线上跑,处理所有样本耗时却达到200~400秒:

    咨询YARD侧同学,得知YARD对提交的离线作业有CPU配额的硬限制,分时段配额如下表:

    00:00~09:00 80%
    09:00~19:00 50%
    19:00~23:00 15%
    23:00~24:00 50%

    晚高峰时段的配额只有15%。

    与YARD侧同学沟通,他们答应后续会支持scikit-learn库的在线服务。目前通过手工方式在一台有scikit-learn的mmguardstore机器上运行在线服务,晚高峰时段处理全量数据耗时为20秒左右。

    最终的系统结构图如下图所示:

    模型训练进程定期训练最新的模型,并把模型通过队列传给预测进程。预测进程每分钟运行一次,检查模型队列上是否有新模型可使用,然后加载数据、检测异常,将检测结果通过上报队列传给上报进程。上报进程block在上报队列上,一旦发现有新数据,就根据数据类型执行上报监控、上报tdw等操作。

    2.4 评估性能

    安全侧将异常用户分为以下几类:盗号、LBS/加好友、养号、欺诈、外挂/多开等。由于这些分类的异常打击是由不同同学负责,不便于对Isolation Forest的分类结果做评估,因此需要在Isolation Forest的基础上,再加一个分类器,标记“异常样本”的小类。利用操作码实现了该分类器。

    接入全量数据后,每天准实时分析1亿量级的样本,检测出500万左右的异常,精确分类出15万左右的恶意请求。恶意请求的uin、类型、发生时间通过tdw中转给安全侧。安全侧通过线下人工分析和线上打击,从结果看检测效果较好。

    2.5 持续优化

    再回过头观察点击流数据,我们使用的Isolation Forest模型只利用了操作码的统计数据。可以明显看到,点击流是一个具备时间序列信息的时序数据。而自然语言处理(Natural Language Processing,NLP)领域已经积累了非常多的处理时序数据的理论和实战经验,如LSTM、word2vec等模型。后续期望能引入NLP的相关工具挖掘出更多恶意用户。

    转自:https://www.qcloud.com/community/article/177890

    展开全文
  • 网站/APP 流量分析、点击流分析、用户访问分析 网站埋点+网站日志自定义采集系统+nginx的相关安装 1.点击流数据模型 1.点击流概念 点击流(Click Stream)是指用户在网站上持续访问的轨迹。这个概念更注重...
  • 解决了问题的办法: 在这个项目上面右键->configure->add php support 。...接下来就是各种刷新啊什么的,然后就解决了这个Zend Studio代码无法自动提示以及代码跟踪函数和变量的问题了!
  • 最近项目中需要用到工作,所以又临时对Activiti工作进行突击补习,再参考网上各大牛的技术博客,总算对Activiti有了一丢丢的了解及应用技巧。 开始做之前,我们要先学会制作工作流程图,网上都有介绍制图工具,...
  • 笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值,找寻数据的秘密,笔者认为,数据的价值...网站点击流数据分析,业务知识,推荐书籍: 《网站分析实战——如何以数据驱动决策...
  • 在码市上看到了一个价值 1000 RMB 的项目:耐克官网模拟登录,唯一要求是纯代码模拟登录。 原本觉得不会有多难,抱着试一试的想法搞了一天,没想到的是,真的是刷新了我对网站 Cookie 使用的认知,Cookie 还可以...
  • 视频会议及媒体十大开源项目

    千次阅读 2018-08-29 10:45:54
    在视频会议领域,有许多可以值得参考的开源项目,这些开源项目有的是协议栈、有的是编码器或者是传输协议,由于视频会议系统是一个综合性的应用系统,里面包含功能较多,如能把这些开源项目选择性的加入我们的视频...
  • Java局域网通信——飞鸽传书源代码 28个目标文件 内容索引:JAVA源码,媒体网络,飞鸽传书 Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java...
  • 使用OSChina代码托管管理项目(一)

    万次阅读 2014-08-01 17:23:08
    1、Git是什么  Git在Wikipedia上的定义:它是一个免费的、...每一个Git的工作目录都是一个完全独立的代码库,并拥有完整的历史记录和版本追踪能力,不依赖 于网络和中心服务器。  Git的出现减轻了许多开发者和开源
  • 第1章 什么是工作 1.1工作介绍 工作(Workflow),就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者 之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而实现某个预期的...
  • 一个强大的拉动刷新开源项目,支持各种控件下拉刷新,ListView、ViewPager、WevView、ExpandableListView、GridView、ScrollView、Horizontal ScrollView、Fragment上下左右拉动刷新,比下面johannilsson那个只支持...
  • 基于OpenCV的网络实时视频传输

    千次阅读 多人点赞 2020-11-12 10:08:00
    点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达很多小伙伴都不会在家里或者办公室安装网络摄像头或监视摄像头。但是有时,大家又希望能够随时随地观看视频...
  • 第一次面对如此浩大的工程代码,真的不知如何下手。拜读HEVC_CJL大神的博客,受益匪浅。以下将记录个人学习过程,有不对的地方请谅解指正,十分感谢。更新·2016.10.10:对HM使用方法进行了描述。·2018.01.23:对原...
  • CSDN开发者周刊:只为传递“有趣/有用”的开发者内容,点击Star(Github)! 本周热门项目 1、TabNine:支持23种语言及5种主流编辑器AI补代码工具问世 一位来自加拿大的大四学霸,开发了一款”Deep TabNine“(Github ...
  • 这是作者的系列网络安全自学教程,主要是关于网安工具和实践操作的在线笔记,特分享出来与博友共勉,希望您们喜欢,一起进步。前文分享了Wireshark安装入门和一个抓取网站用户名和密码的案例,本篇文章将继续深入...
  • 文章目录工作概述属性触发器条件验证器后处理功能工作类型主任务子任务Bug默认工作设计主任务后处理功能主任务总结子任务后处理功能待办到处理中日期规则解决结果责任人主任务流程推进处理中到完成主任务流程...
  • 项目需要在web上播放rtsp视频,之前一直都是用chrome作为最终应用的浏览器,但发现常规操作下rtsp数据需要插件,(rtsp视频的播放依赖于多年前的NPAPI,而自2015年以后,chrome取消了对此功能的支持),并且在...
  • 瀑布StaggeredGridView 下拉刷新

    千次阅读 2015-07-13 19:59:21
    1.项目中用到了瀑布,之前用的是PinterestLikeAdapterView这个控件 然后上拉加载更多跟下拉刷新用的是XListView ,但是加载更多或者下拉刷新的时候闪屏,对用户体验很不好, 于是又从网上找了一些demo,最后决定用...
  • 全球10大开放源代码项目

    千次阅读 2007-02-06 10:38:00
    作者:随风而行 编译下 面是The Blog Joint.com 评选出的10大开放源代码项目。我打赌你们当中的绝大多数人对这些软件都并不陌生,也许曾经使用过,也许现在正在使用。噢,老天!请不要告诉我你从来都没 有听说过这些...
  • Android代码-GankDaily

    2019-08-06 06:54:51
    GankDaily 每日提供技术干货的 App 下载 fir ...原项目使用 Retrofit RxJava 的组合获取网络数据,再加上使用Lambda表达式,代码已经变得很精简,所以把获取数据的代码放在 Activity 中也不显得混
  • python实现飞机大战源代码+素材+项目分析

    万次阅读 多人点赞 2020-01-15 16:54:12
    项目分析 Python程序设计项目 题 目 飞机大战 院 系 信息科学与技术学院 专 业 计算机科学与技术 姓 名 星空 班级学号 37 指导教师 xxx 二O一九年十二月 一.系统研究的背景及意义 当今社会是一个信息社会,一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 80,746
精华内容 32,298
关键字:

网络点击流项目代码