网站流量日志分析系统
网站流量日志分析-01
-
网站流量日志分析的意义
通过分析用户的行为数据 让更多的用户沉淀下来变成会员 赚取更多的钱。
-
如何进行网站分析
-
流量分析
- 质量分析 在看重数量的同时 需要关注流量的质量 所谓的质量指的是流量所能带来产生的价值。
- 多维度细分 维度指的是分析的问题的角度 在不同的维度下 问题所展示的特性是不一样的
-
内容导航分析
从页面的角度分析 用户的访问行为轨迹
-
转化分析(漏斗模型分析)
从转化目标分析 分析所谓的流失率转化率 漏斗模型:层层递减 逐级流失的形象描述
-
-
网站流量日志分析的数据处理流程
按照数据的流转流程进行 通俗概括就是数据从哪里来一直到数据到哪儿去
-
数据采集
- 数据从无到有的过程:通过技术把客观事件量化成为数据(传感器收集 服务器日志收集)
- 数据搬运过程:把数据从一个存储介质传递到另一个存储介质中(Apache Flume)
-
数据预处理
-
目的:保证后续正式处理的数据是格式统一、干净规则的结构化数据
-
技术:任何语言软件只要能够接受数据处理数据并且最终输出数据 都可以用于数据预处理
选择MapReduce
- MR本身是java程序,语言比较熟悉 可以无缝的调用java现有的开源库进行数据处理
- MR是分布式的程序 在预处理中 如果数据量比较大 可以分布式并行计算处理 提高效率
-
-
数据入库
- 库:面向分析的数据仓库 也是就会Apache Hive
- 入库的本质:经过ETL(抽取、转换、加载)把各个不同的数据源集中加载到数仓的分析主题下面。
-
数据分析
- 本质:根据业务需求 使用hive sql计算统计出各种不同的指标 分析是一个持续的过程
-
数据可视化
尽量的使用图形表格的形式 把分析的结果规律展示给别人看 也称之为数据报表
-
-
数据采集
-
数据从无到有的采集 如何把用户的访问行为记录下来变成网站访问日志
-
网站日志文件:网站的web服务器自带日志记录的功能 简单便捷的收集一些基础的属性信息
常见的web服务器(Tomcat nginx apache server(httpd))
优点:简单便捷 自带功能 不需要配置就可以使用
缺点:收集的信息确定 不利于维护 收集的信息不够完整全面
-
埋点JavaScript收集
-
目标:不以影响用户的正常浏览体验作为标准 数据采集分析锦上添花
-
何为埋点
在待采集数据的页面上,预先置入一段JavaScript代码,当用户的某种行为满足JavaScript执行条件,触发JavaScript的执行,在执行的过程中进行数据的采集工作。
-
标准的URL
协议://主机:端口/资源路径?k1=v1&k2=v2
-
好处:可以根据业务需求 定制化收集的属性信息 在不影响用户浏览体验的情况下 进行更多数据的收集
-
-
-
-
埋点js代码实现自定义收集用户数据
-
js和html页面耦合在一起 不利于后续js维护
把js单独提取处理变成一个文件 然后通过src属性引入页面 进行所谓解耦合
-
一台服务器身兼多职 压力过大 降低服务器请求压力
单独的去部署服务器 专门用于采集数据的请求响应 可能会产生跨域问题(限制js跨域的数据发送) 以请求图片的形式 把采集的数据拼接成为图片的参数 发送到指定的服务器上去 绕开js的跨域问题
-
-
确定收集的信息
通常在收集数据之前结合业务需求 分析的需求确定收集哪些信息字段 和收集途径
- 可以通过nginx内置的日志收集功能获取到
- 可以通过页面上内置的对象常见的属性获取到
- 可以自定义编写js代码进行相关属性的收集
-
埋点代码的编写
本来埋点代码的逻辑就是真正进行数据收集的逻辑,但是为了后续维护方便 把真正收集数据的js提取出变成了js文件,在这种情况下,埋点代码的变成了如何把这个js文件引入到页面上。
-
直接通过src属性引入
<script src="www.itcast.cn/collect.js">
-
js匿名函数自调用
创建匿名函数 自己调用自己 并且调用一次 通常用于页面初始化操作
(function() { var ma = document.createElement('script'); ma.type = 'text/javascript'; ma.async = true; ma.src = 'www.itcast.cn/collect.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ma, s); })();
-
-
前端收集数据js
依然是一个匿名函数自调用的格式 保证被引入到页面上之后 自己可以调用自己执行且执行一次
- 通过页面内置的对象获取一些属性信息
- 通过解析全局数据 获取一些信息
- 把收集的属性信息按照url格式进行拼接 并且进行url编码
- 页面创建一个图片标签 把标签的src属性指向后端收集数据的服务器
- 把收集数据拼接的参数放置请求图片的url后面 传递给后端
-
后端脚本
所谓后端就是接受解析前端发送采集数据的服务器
- 接受请求 解析参数 保存数据
- 响应图片 log.gif 1*1
- 响应cookie cookiekey cookievalue path
注意搞清楚nginx 中 location模块的具体职责:用于请求url资源路径的匹配。
-
日志格式
考虑日志中字段之间的分隔符问题 以有利于后续程序处理数据方便为标准
常见的分隔符 制表符 空格 特殊符号 \001
-
日志切分
nginx默认把日志一直写在一个文件中access.log 不利于后续的维护移动操作处理
通过shell脚本给nginx进程发送usr1信号 告知其重载配置文件 在重载配置文件的时候 重新打开一个新的日志文件 在配合crontab定时器 从而完成间接的通过时间控制文件的滚动
网站流量日志分析–02
-
flume 新source taildir
- 监控一个文件的变化 此时相当于exec source :tail -f xxx
- 监控一个文件夹下文件的变化,并且支持正则匹配 此时相当于spooldir source
- 支持断点续传功能 通过文件记录上传的位置 待重启或者出现故障的时候 可以继续工作
-
需求:在使用flume采集数据到hdfs的时候 以文件大小进行控制滚动,大小为:128M
a1.sinks.k1.hdfs.rollInterval = 0 a1.sinks.k1.hdfs.rollSize = 134217728 a1.sinks.k1.hdfs.rollCount = 0
-
当通过flume上传文件至hdfs当中 如果控制文件滚动的条件不满足怎么办?
如果不满足 位于hdfs上的文件将会一直处于临时状态 xxx.tmp
a1.sinks.k1.hdfs.rollInterval = 0 时间间隔 a1.sinks.k1.hdfs.rollSize = 134217728 文件的大小 a1.sinks.k1.hdfs.rollCount = 0 event数量
解决:基于文件空闲时间滚动
hdfs.idleTimeout 默认值是0 如果配置指定的时间 比如30s 意味着如果30s之内 文件没有数据写入 即是其他的滚动条件不满足 此时已然进行文件的滚动 避免文件一致处于所谓的临时状态
-
数据预处理
在正式处理数据之前对收集的数据进行预先处理的操作。
- 原因:不管通过何种手段收集的数据 往往是不利于直接分析的 数据中存在的格式规整的差异。
- 目的:把不干净的数据 格式不规则的数据 通过预处理清洗变成格式统一规整的结构化数据
- 技术:MapReduce
-
预处理的编程思路问题
在使用mr编程的过程中 牢牢把握住key是什么。因为mr中key有很多默认的属性。
分区---->key哈希 % reducetasknums 分组---->key相同分为一组 排序---->按照key的字典序排序
-
MapReduce编程技巧
- 涉及多属性数据传递 通常采用建立javabean携带数据 并且需要实现hadoop的序列化机制 Writable
- 有意识的重写对象toString方法 并且以\001进行字段 的分割,便于后续的数据入库操作
- 针对本次分析无效的数据 通过采用建立标记位的形式进行逻辑删除
-
点击流模型的概述
点击流模式是业务模型 客观并不存在 其模式是由一堆业务指标堆积而成。
点击流模式所描述的是用户在网站持续访问的一条轨迹 是一个线的概念。
-
点击流模式和原始日志数据区别
- 原始访问日志是站在网站的角度看待用户访问行为 数据按照时间追加的 是散点状的数据
- 点击流模型是站在用户的角度看待用户的访问行为 数据一条持续的轨迹线
- 点击流模型数据可以通过原始日志数据梳理而来
-
会话(session)
通常业界以前后两条的记录的时间差是否在30分钟以内作为会话判断的标准
如果小于30分钟 就属于同一个会话
如果大于30分钟 就是一个新的会话开始
所谓点击流模型指的是在一个会话内的持续访问轨迹线。
网站流量日志分析-03
数仓设计
-
维度建模
以维度为标准 开展数据的分析需求
适用于面向分析领域的理论。比如分析型数据库 数据仓库 数据集市(OLAP)
-
事实表
分析主题的客观事件度量 是分析主题的数据聚集 事实表中一条记录往往对应着客观的一个事件 往往是一堆主键的聚集
-
维度表
所谓的维度就是指看待问题的角度 可以通过不同的维度去分析同一个事实表 得出不同的分析结果 维度表可以跟事实表进行关联查询
-
-
多维度数据分析
所谓的多维数据分析就是指通过不同维度的聚集计算出某种度量值。
常见度量值:max min count sum avg topN
举个栗子:统计来自于北京女性24岁未婚的过去三年购物金额最多的前三个。 维度:地域 性别 年龄 婚姻 时间 度量值:sum(订单金额)--->top3
-
维度建模的三种模式
-
星型模式
一个事实表多个维度表 维度表之间没有关系 维度表跟事实表进行关联 企业数仓发展初期常见的模型
-
雪花模式
一个事实表多个维度表 维度表可以继续关联维度表 不利于后期维护 企业中尽量避免演化成该种模型
-
星座模式
多个事实表 多个维度表 某些维度表可以共用 企业数仓发展中后期常见的模型
-
-
本项目模式设计
因为项目中只有一个分析的主题:网站的流量日志情况 因此对应的事实表只有一个:网站流量日志
本项目采用星型模式 事实表:对应着数据预处理完之后的原始网站日志情况 维度表:通常要结合业务决定分析的维度 要和事实表能够关联上 要以能够涵盖事实表为基本标准
Q:问点击流模型数据算什么类型的表?
点击流模型数据既不是事实表 也不是维度表 是一个业务模型数据 可以称之为事实表的业务延伸。
数据入库ETL
-
创建ODS层表
- 表名通常以简短 的英文表示 不用使用汉语拼音甚至中文
- 建表的时候表的字段顺序类型 要和数据保持一致 心细
- 通常企业中采用分区表进行优化 方便后续查询管理
-
导入ODS层表数据
-
原始日志表
load data local inpath '/root/hivedata/part-m-00000' into table ods_weblog_origin partition(datestr = "20181101");
-
点击流模型之pageviews
load data local inpath '/root/hivedata/part-r-00000' into table ods_click_pageviews partition(datestr = "20181101");
-
点击流模型之visit
load data local inpath '/root/hivedata/part-r-00000' into table ods_click_stream_visit partition(datestr = "20181101");
-
时间维度表数据
load data local inpath '/root/hivedata/dim_time.dat' into table t_dim_time;
-
-
宽表窄表的引入
--需求:统计今天每个小时访问量有多少? --需要根据小时hour进行分组 group by 分组之后统计每个组内的个数count --当下:group by(substring(time_local,12,2)) --缺点:每一条记录在分组之前 都需要进行所谓的截取操作 --原因:表中的某些字段看似一个字段 实则糅杂了多个属性在一起 --解决:把糅合在一起的属性拆分出来变成单独独立的新字段 hour group by(hour) --结果:因为表的字段相比较之前变多了 称之为宽表。原来对应的表称之为窄表。又因为变宽之后信息更加详细具体,所以也可以称之为明细表。
-
宽表的实现
-
宽表的数据由何而来
由窄表数据得到 所谓窄表就是原始数据表
insert into 宽 + select from 窄
-
宽表需要扩宽哪些字段
跟业务需求相关,本项目中进行两个字段的扩宽 时间字段:time_local 来访字段:http_referer
-
使用什么技术进行字段的扩宽
insert into 宽 + select from 窄 至于插入什么样的数据完全取决于查询语句返回的结果。 因此在查询的时候就需要使用hive的函数进行字段的扩宽操作。
时间字段的拓宽:substring(time_local) 来源url字段拓宽:hive内置的解析url函数 是一个标准的udtf函数 parse_url_tuple
-
分析指标和模型
-
基础级指标
例子:
张三今天上午来到网站打开3个页面 下午来到网站打开2个页面 晚上又来到网站打开5个页面 问:pv uv vv ip? pv:页面加载总次数 10 uv:独立访客数 1 vv:会话次数 3 ip: 1
-
复合指标
-
平均访问频度:一天之内人均会话数
==总的会话次数(session)/总的独立访客数
==vv/uv
-
平均访问深度:一天之内人均浏览页面数
==总的页面浏览数/总的独立访客数
==pv/uv
-
平均会话时长:平均每次会话停留的时间
=总的会话停留时间/会话次数(vv)
-
首页跳出率=访问网站且访问一个页面且该页面是首页/总的访问次数
-
网站流量日志分析-04
-
基础指标统计分析
-
PageView 浏览次数(pv):一天之内网站页面被加载的总次数
- 数据表: dw_weblog_detail
- 分组字段:时间(day) day比较特殊 还是表的分区字段 通过where分区过滤即可
- 度量值:count(*)
select count(*) as pv from dw_weblog_detail t where t.datestr="20181101"; --不精准 select count(*) as pv from dw_weblog_detail t where t.datestr="20181101" and t.valid = "true"; --精准 过滤了静态资源的请求 贴近实战
-
Unique Visitor 独立访客(UV):一天之内不重复的访客数
计算的关键是对访客的识别。 以ip作为判断标识 不精准 技术上是一样的。
- 数据表:dw_weblog_detail
- 分组字段:时间(day) day比较特殊 还是表的分区字段 通过where分区过滤即可
- 度量值:count(distinct remote_addr)
select count(distinct remote_addr) as uv from dw_weblog_detail t where t.datestr="20181101"; --以ip计算uv 不精准 select count(distinct remote_user) as uv from dw_weblog_detail t where t.datestr="20181101";--以userID计算 准确
-
访问次数(VV):一天之内的会话次数(session数)
- 数据表:ods_click_stream_visit
- 分组字段:时间(day) day比较特殊 还是表的分区字段 通过where分区过滤即可
- 度量值:count(session) 如果使用ods_click_pageviews进行计算 count(distinct session)
select count(t.session) as vv from ods_click_stream_visit t where t.datestr="20181101";
-
IP:一天之内不重复的IP个数。
跟上述的UV计算一样。
select count(distinct remote_addr) as ip from dw_weblog_detail t where t.datestr="20181101";
-
-
复合指标的计算
-
人均访问深度(人均浏览页面数):一天之内平均每个独立访客打开的页面数
=总的页面浏览数/总的独立访客数
=pv/uv
- 数据表:dw_webflow_basic_info(基础指标信息表)
- 分组字段:时间(day) day比较特殊 还是表的分区字段 通过where分区过滤即可
- 度量值:pv/uv
select pv/uv from dw_webflow_basic_info t where t.datestr="20181101";
- 数据表:dw_weblog_detail
- 分组字段:时间(day) day比较特殊 还是表的分区字段 通过where分区过滤即可
- 度量值:先计算每个人的pv 加起来变成总的pv再除以人
select count(*) as pv,t.remote_addr from dw_weblog_detail t where t.datestr="20181101" group by t.remote_addr; select sum(pv)/count(ip) from (select count(*) as pv,t.remote_addr as ip from dw_weblog_detail t where t.datestr="20181101" group by t.remote_addr) a;
-
平均访问频度:一天之内访问访问人均产生的会话次数(session次数)
=总的会话次数/独立的访客人数
=vv/uv
- 数据表:dw_webflow_basic_info(基础指标信息表)
- 分组字段:时间(day) day比较特殊 还是表的分区字段 通过where分区过滤即可
- 度量值:vv/uv
select vv/uv from dw_webflow_basic_info t where t.datestr="20181101";--0.56 --上述指标不符合客观规律 --原因:在计算基础指标的时候 uv使用的宽表的数据 没有进行静态资源的过滤 -- vv使用的点击流模型数据 在数据预处理阶段 进行了静态资源的过滤 -- 一个采用过滤的 一个不采用过滤的 计算的指标出现了谬论 --统计采用 过滤静态资源后的数据进行计算 ods_click_stream_visit select count(t.session)/count(distinct t.remote_addr) from ods_click_stream_visit t where t.datestr="20181101"; --1.075
-
平均访问时长:一天之内用户平均每次会话在网站的停留时间
=总的停留时间/会话的次数(vv)
- 数据表:ods_click_pageviews
- 分组字段:时间(day) day比较特殊 还是表的分区字段 通过where分区过滤即可
- 度量计算:sum(page_staylong)/count(distinct session)
select sum(t.page_staylong)/count(distinct t.session) from ods_click_pageviews t where t.datestr="20181101"; --211.24
-
/hadoop-mahout-roadmap/ 页面跳出率
一天之内只访问一个页面就离开的会话次数与总的会话次数的百分比。
- 数据表:ods_click_stream_visit
- 分组字段:时间(day) day比较特殊 还是表的分区字段 通过where分区过滤即可
- 度量值:count
- 过滤条件:会话的访问页面次数为1,并且该页面是指定的页面
select count(t.session) from ods_click_stream_visit t where t.datestr="20181101" and t.pagevisits =1 and t.inpage ="/hadoop-mahout-roadmap/";
-
多维数据分析
-
多维数据分析
- 维度:指的是看待问题的角度
- 本质:基于多个不同的维度的聚集 计算出某种度量值(count sum max mix topN)
- 重点:确定维度 维度就是sql层面分组的字段
- 技巧:按xxx 每xxx 各xxx
-
时间维度统计
-
计算该处理批次(一天)中的各小时pvs
- 数据表:dw_weblog_detail
- 分组字段:时间(day hour) day字段比较特殊 day是表分区字段 可以通过where过滤
- 度量值:count(*)
select t.hour,count(*) as pvs from dw_weblog_detail t where t.datestr ="20181101" group by t.hour; select t.day,t.hour,count(*) as pvs from dw_weblog_detail t where t.datestr ="20181101" group by t.hour; --直接报错 Invalid column reference 'day' --想一想:sql语句 groupby有什么样的语法限制问题。 出现在groupby语句表达式中的字段:要么是分组的字段 要么是被聚合函数包围应用的字段。 select t.month,t.day,t.hour,count(*) as pvs from dw_weblog_detail t where t.datestr ="20181101" group by t.month,t.day,t.hour;
-
计算每天的pvs
--方式一:dw_pvs_everyhour_oneday 针对每个小时的pv进行sum求和 select sum(pvs) from dw_pvs_everyhour_oneday where datestr ="20181101"; --方式二:dw_weblog_detail 分区和需求一直 基于分区进行count即可 select count(*) from dw_weblog_detail where datestr ="20181101"; --方式三:如果数据不是分区表 直接根据day进行分组 select t.month,t.day,count(*) as pvs from dw_weblog_detail t where t.datestr ="20181101" group by t.month,t.day;
-
事实表(宽表)和维度表进行关联查询
关联查询的重点是确定join字段 跟时间相关的。
- 计算每天的产生的pvs
select count(*) as pvs,a.month as month,a.day as day from (select distinct month, day from t_dim_time) a join dw_weblog_detail b on a.month=b.month and a.day=b.day group by a.month,a.day;
-
拓展:使用与维度表关联的方式计算每个小时的pvs
select count(*) as pvs,a.month as month,a.day as day,a.hour as hour from (select distinct month, day, hour from t_dim_time) a join dw_weblog_detail b on a.month=b.month and a.day=b.day and a.hour=b.hour group by a.month,a.day,a.hour;
-
-
按照来访维度、时间维度分析
-
统计每小时各来访url产生的pv量
- 数据表:dw_weblog_detail
- 分组字段:时间维度、来访referer(url)
- 度量值:count()
select http_referer,ref_host,month,day,hour,count(1) as pv_referer_cnt from dw_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;
-
统计每小时各来访host的产生的pv数并排序
- 数据表:dw_weblog_detail
- 分组字段:时间维度(hour)、来访维度(host)
- 度量值:count()
select ref_host,month,day,hour,count(1) as ref_host_cnts from dw_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;
-
SQL扩展
-
如何编写查看select语句
select count(*) as nums from ( select a.*,b.* from a join b on a.id = b.id where... ) t where t.city = "beijing" group by t.sex having t.sex is not null order by nums desc limit n; --需求:统计来自于北京男女各有多少人(性别为空的排除)并且按照人数的倒数进行排序。 重点:select确定之后 立马去寻找from关键字 因为from后面跟的就是操作的表。 --表可能是真实存在的表 如果是真实的表 直接操作使用 --表也可能不存在 设法通过查询把这个表变出来 基于这个虚拟的表再进行操作 --只有表确定之后 在结合业务确定查询返回的字段或者表达式 --嵌套子查询,先执行里面的查询语句 后执行外部的查询语句
-
group by
出现在表达式中字段要么是分组的字段,要么是被聚合函数包围应用的字段。
–先计算每个用户产生的会话数
select
t.remote_addr,count(t.session) as nums
from ods_click_stream_visit t where t.datestr =“20181101” group by t.remote_addr;
–方式一:采用嵌套查询的思路
select
*
from
(select
t.remote_addr as ip,count(t.session) as nums
from ods_click_stream_visit t where t.datestr =“20181101” group by t.remote_addr) a
where a.nums =1; --单次访客
select
*
from
(select
t.remote_addr as ip,count(t.session) as nums
from ods_click_stream_visit t where t.datestr =“20181101” group by t.remote_addr) a
where a.nums > 1; --回头访客
–方式二:采用having
select
t.remote_addr,count(t.session) as nums
from ods_click_stream_visit t where t.datestr =“20181101” group by t.remote_addr
having nums = 1;–单次访客
select
t.remote_addr,count(t.session) as nums
from ods_click_stream_visit t where t.datestr =“20181101” group by t.remote_addr
having nums > 1;–回头访客
网站流量日志分析–06
-
全量、增量
- 全量数据:所有的数据、全部的数据
- 增量数据:从上次开始到当下中间新增的数据
-
全量数据的导出
-
hive------>HDFS
insert overwrite directory '/weblog/export/dw_pvs_referer_everyhour' row format delimited fields terminated by ',' STORED AS textfile select referer_url,hour,pv_referer_cnt from dw_pvs_referer_everyhour where datestr = "20181101";
-
mysql创建目标表
create database weblog; use weblog; create table dw_pvs_referer_everyhour( hour varchar(10), referer_url text, pv_referer_cnt bigint);
-
hdfs----->mysql
bin/sqoop export \ --connect jdbc:mysql://node-1:3306/weblog \ --username root --password hadoop \ --table dw_pvs_referer_everyhour \ --fields-terminated-by '\001' \ --columns referer_url,hour,pv_referer_cnt \ --export-dir /weblog/export/dw_pvs_referer_everyhour
-
-
增量数据的导出
-
mysql中手动创建目标表
create table dw_webflow_basic_info( monthstr varchar(20), daystr varchar(10), pv bigint, uv bigint, ip bigint, vv bigint )
-
先进行全量导出 把hive中该表的数据全部导出至mysql中
bin/sqoop export \ --connect jdbc:mysql://node-1:3306/weblog \ --username root --password hadoop \ --table dw_webflow_basic_info \ --fields-terminated-by '\001' \ --export-dir /user/hive/warehouse/itheima.db/dw_webflow_basic_info/datestr=20181101/
-
手动模拟在hive新增数据 表示增量数据
insert into table dw_webflow_basic_info partition(datestr="20181103") values("201811","03",14250,1341,1341,96);
-
利用sqoop进行增量导出
bin/sqoop export \ --connect jdbc:mysql://node-1:3306/weblog \ --username root \ --password hadoop \ --table dw_webflow_basic_info \ --fields-terminated-by '\001' \ --update-key monthstr,daystr \ --update-mode allowinsert \ --export-dir /user/hive/warehouse/itheima.db/dw_webflow_basic_info/datestr=20181103/
在sql中 update-key 用于指定更新时检查判断依据 可以多个字段 中间用,分割
如果检查的字段在hive中有更新 mysql目标表中没有 那么sqoop就会执行更新操作
-
-
定时增量数据的导出操作
-
手动导入增量数据
insert into table dw_webflow_basic_info partition(datestr="20181104") values("201811","04",10137,1129,1129,103);
-
编写增量导出的shell脚本
- 导出数据的时间最好不要写死 可以通过传参或者命令方式自动获取时间
- 参数属性值不要写死 集中定义变量 后续引用 方便集中管理
#!/bin/bash export SQOOP_HOME=/export/servers/sqoop if [ $# -eq 1 ] then execute_date=`date --date="${1}" +%Y%m%d` else execute_date=`date -d'-1 day' +%Y%m%d` fi echo "execute_date:"${execute_date} table_name="dw_webflow_basic_info" hdfs_dir=/user/hive/warehouse/itheima.db/dw_webflow_basic_info/datestr=${execute_date} mysql_db_pwd=hadoop mysql_db_name=root echo 'sqoop start' $SQOOP_HOME/bin/sqoop export \ --connect "jdbc:mysql://node-1:3306/weblog" \ --username $mysql_db_name \ --password $mysql_db_pwd \ --table $table_name \ --fields-terminated-by '\001' \ --update-key monthstr,daystr \ --update-mode allowinsert \ --export-dir $hdfs_dir echo 'sqoop end'
-
配合定时调度工具完成周期性定时调度
- linux crontab
- 开源azkaban oozie
-
工作流调度
业务目标完成会包含各个不同的步骤 步骤之间或者步骤内部往往存在着依赖关系,甚至需要周期性重复性执行,这时候就需要设定工作流,指导工作按照设定的流程进行。
简单工作流 使用linux crontab
复杂工作流 自己开发软件 或者使用开源免费的调度软件 azkaban
-
预处理模块的任务调度
-
把预处理阶段的3个mr程序打成可以执行的jar包
注意使用maven插件 需要指定main class 里面的输入输出路径不要写死哦
-
配置azkaban的 job信息
尤其需要注意设置的依赖 和输入输出的路径对应问题
-
把azkaban配置及其依赖的资源打成zip压缩包
-
在azkaban的web页面上创建工程 上传zip压缩包
-
在azkaban上可以进行两种选择 立即执行 配置定时执行的计划
-
-
数据入库的调度
- shell脚本编写
- 导入shell需要软件的环境变量
- 集中定义时间 目录 属性 等常量变量
- 程序主体 结合流程控制编写
- 如何使用azkaban调度hive
- hive -e sql语句
- hive -f sql脚本
- shell脚本编写
数据可视化
-
何谓数据可视化
又称之为数据报表展示,属于数据应用中的一种,尽量使用图形表格的形式把分析的结果展示给被人看。
数据可视化的大量工作属于前端开发 我们需要掌握的是如何把数据分析处理 已经把数据按照要求传递给可视化的软件。
数据可视化是一种锦上添花的事。核心还是数据分析的过程。
-
echarts简单入门
-
在页面上引入echarts.js
<script type="text/javascript" src="js/echarts.js" ></script>
-
在页面创建一个dom容器 有高有宽的范围
<div id="main" style="width: 600px;height:400px;"></div>
-
选择容器使用echarts api创建echarts 实例
var myChart = echarts.init(document.getElementById('main'));
-
根据业务需求去echarts官网寻找对应的图形样式 复制其option
var option = { title: { text: 'ECharts 入门示例' }, tooltip: {}, legend: { data:['销量'] }, xAxis: { data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] }, yAxis: {}, series: [{ name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] }] };
-
把option设置到创建的echarts 实例中
// 使用刚指定的配置项和数据显示图表。 myChart.setOption(option);
对我们来说需要思考如何把数据从后端动态加载返回至前端页面进行可视化展示。
-
-
数据可视化后端web工程
- 职责:把导出在mysql中的数据按照前端需要的格式查询返回给前端
- 技术:php java 本项目中使用javaEE 基于SSM做数据查询
-
mybatis逆向工程
- 可以根据对应的数据库表逆向生成与之对应的javabean mapper sql
- 最重要的是提供了一个所谓的example类 该类用于条件封装 满足于sql的增删改查操作
- 当业务简单 不涉及多表操作的时候 可以直接使用逆向工程 使得dao层代码量降为零。