目的: 分析每一个调研需求需要计算什么指标, 以及计算这个指标需要通过那些维度,而且还包括计算这个需求涉及
到那些表和那些字段
指标: 访问量 维度: 时间维度: 年 季度 月 天 小时 涉及到哪些表: web_chat_ems_2019_12 涉及到哪些字段: 时间维度: create_time 说明: 发现create_time字段中包含有年 月 天 小时这些数据, 此时可以认为一个字段中涵盖了多个字段的数据 处理方式: 后期需要对此字段进行转换处理工作 将create_time 转换为: yearinfo monthinfo dayinfo hourinfo .... 指标字段: sid 说明: 指标计算的逻辑 先对sid进行去重操作, 然后统计个数过程
指标: 访问量 维度: 时间维度: 年 季度 月 天 小时 区域维度: 涉及到哪些表: web_chat_ems_2019_12 涉及到哪些字段: 时间维度: create_time 区域维度: area 指标字段: sid
指标: 访问量 和 咨询量 维度: 时间维度: 年 季度 月 天 小时 区域维度 说明: 访问量的统计可以直接复用需求2的结果即可, 此处可以省略 涉及到哪些表: web_chat_ems_2019_12 涉及到哪些字段: 时间维度: create_time 区域维度: area 咨询量判断: msg_count >= 1 即可 指标字段: sid 咨询量指标计算: 先对数据进行过滤得出咨询数据, 然后通过先去重 在求个数过程
指标: 访问量 和 咨询量 维度: 时间维度: 年 季度 月 天 小时 说明: 访问量的统计可以直接复用需求1的结果即可 涉及到哪些字段: 时间维度: create_time 说明: 发现create_time字段中包含有年 月 天 小时这些数据, 此时可以认为一个字段中涵盖了多个字段的数据 处理方式: 后期需要对此字段进行转换处理工作 将create_time 转换为: yearinfo monthinfo dayinfo hourinfo .... 指标字段: sid 说明: 指标计算的逻辑 先对sid进行去重操作, 然后统计个数过程 添加一个咨询数据过滤的条件: msg_count >= 1 即可
指标: 访问量 维度: 时间维度 : .... 此需求的结果 在需求1中 已经涵盖了, 不需要再次分析
指标: 访问量 和 咨询量 维度: 时间维度: 年 季度 月 天 小时 来源渠道维度 涉及到哪些表: web_chat_ems_2019_12 涉及到哪些字段: 时间维度: create_time 来源渠道维度: origin_channel 指标字段: sid
指标: 访问量 维度: 时间维度 : 年 季度 月 天 小时 搜索来源渠道维度 涉及到哪些表: web_chat_ems_2019_12 涉及到那些字段: 时间维度: create_time 搜索来源维度字段: seo_source 指标字段: sid
指标: 访问量 维度: 时间维度: 年 季度 月 天 小时 受访页面维度: 涉及到哪些表: web_chat_text_ems_2019_12 涉及到哪些字段: 时间维度: 暂不知道 受访页面维度: from_url 指标计算: 直接计算总数量
总结:
指标: 访问量 维度: 固有维度: 时间维度: 年 季度 月 天 小时 产品属性维度: 总访问量 地区维度 来源渠道维度 搜索来源维度 受访页面维度 ------------------------------------- 指标: 咨询量 维度: 固有维度: 时间维度: 年 季度 月 天 小时 产品属性维度: 总咨询量 地区维度 来源渠道维度 发现点: 不管计算咨询量还是访问量 都使用的同一个表, 至少咨询量比访问量在计算的时候多个一个条件: msg_count >=1 涉及到表: web_chat_ems_2019_12 和 web_chat_text_ems_2019_12 涉及到字段: web_chat_ems_2019_12: 指标: sid (咨询量 和 访问量) 说明: 先去重, 在统计个数过程 时间维度: create_time 地区维度: area 来源渠道维度: origin_channel 搜索来源维度: seo_source web_chat_text_ems_2019_12: 受访页面维度: from_url 需求转换的点: create_time字段 后期需要进行转换操作
create database nev default character set utf8mb4 collate utf8mb4_unicode_ci;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-woZPswrz-1626155328752)(day24_教育项目.assets/image-20210227173652033.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mY0NbrW7-1626155328760)(day24_教育项目.assets/image-20210227173718662.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y1sATB8g-1626155328761)(day24_教育项目.assets/image-20210227173759354.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ZyCmF2v-1626155328762)(day24_教育项目.assets/image-20210227173827962.png)]
目的: 要计算此主题, 需要如何构建数仓分层, 每一层需要有那些表, 表中有那些字段
ODS层: 源数据层
1) 在ODS层, 可以放置两张表(在业务端有二张跟此主题相关的事实表) web_chat_ems 和 web_chat_text_ems 2) ODS层的两个表中字段 和 业务库中对应表的字段保持一致(业务库中表有几个字段, 此ODS层表中也应该有几个字段) 注意: 在后期执行操作的时候, 先进行全量分析过程, 然后后期都是增量分析,此时需要从ODS层拿到增量数据, 如何区分增量数据呢? 核心点: 通过时间 所以: 在ODS层建表的时候, 比业务库的表多一个字段,此字段主要作用用于标识抽取时间: start_time
DW层: 数据仓库层
DWD层: 明细层
清洗什么内容? 没有清洗的工作 , 因为数据来源于mysql, 数据结构是完整, 同时所有数据都是需要的, 所以也不需要处理 转换什么内容? 1. create_time : (需求必须要转换) 原始数据: 2019-07-02 00:00:00 发现: 一个字段里面糅杂了太多字段数据, 需要对其进行转换 转换为: yearinfo quarterInfo monthinfo dayinfo hourinfo 2. 将create_time转换为时间戳的操作(为了讲解时间函数)
,create_time, hourinfo,yearinfo, quarterInfo, monthinfo, dayinfo 注意: 以上字段, 是需要进行清洗和转换后, 保留的字段 此时DWD层表: 将上述的字段 和 ODS层中事实表所有的字段汇总在一起, 构建成DWD层表 实际在生产中,具体操作: 1) 第一种, 如果事实表中字段比较多, 一般做法 可以只将需要的字段抽取出来即可 2) 第二种, 如果表中字段比较少, 一般做法, 全部都获取出来 最终形成的表字段: sid,session_id,ip ,create_time,area,origin_channel,seo_source,referrer,from_url, landing_page_url,url_title,platform_description,other_params,history,msg_count hourinfo,yearinfo, quarterInfo, monthinfo, dayinfo
DWM层: 中间层
1) 维度退化操作: 此功能在此主题中不存在, 因为没有维度表 2) 做提前聚合操作: 比如说: 要分别按照 年 月 日 小时进行统计总访问量, 此时可以先按照小时统计总访问量 , 后的日 月 年可以在小时的基础上进行累加统计即可, 这样效率比较高 思考, 访问咨询主题中, 是否可以进行提前聚合呢? 不能 在此看板中, 计算指标的 先 去重 在统计个数 小案例: 2020-10-10 15 s01 2020-10-10 15 s02 2020-10-10 16 s01 2020-10-10 16 s03 2020-10-11 10 s02 2020-10-11 11 s04 统计, 每个小时有几个用户数据呢? 2020-10-10 15 2 2020-10-10 16 2 2020-10-11 10 1 2020-10-11 11 1 统计, 每天有几个用户呢? 正确结果: 2020-10-10 3 2020-10-11 2 但是, 如果使用每个小时的统计结果, 来计算: 2020-10-10 4 2020-10-11 2 此时, 会发现有问题了....
DWS层: 业务层
指标: 访问量 维度: 固有维度: 时间维度: 年 季度 月 天 小时 产品属性维度: 总访问量 地区维度 来源渠道维度 搜索来源维度 受访页面维度 开发需求: 共计有 25个开发需求 1) 统计每年 的总访问量 2) 统计 每年 每季度的总访问量 3) 统计 每年 每季度 每月的总访问量 ..... 1) 统计每年 各个地区的总访问量 2) 统计每年每季度 各个地区总访问量 .... 1) 统计每年各个来源渠道的总访问量数据 2) 统计每年每季度各个来源渠道的总访问量数据 .... .... 在DWS层, 需要将每一个需求的结果统计出来, 然后存储在DWS层 , 针对每一个指标, 构建一个结果表, 存储其所有的结果 DWS层表: 组成部分: 指标统计结果字段 + 维度字段 + 业务查询字段(time_type,group_type,time_str) 最终组合下DWS层字段: sid_total,sessionid_total,ip_total,area,origin_channel,seo_source from_url, hourinfo,time_type,group_type,time_str yearinfo, quarterinfo,monthinfo,dayinfo, ------------------------------------- 指标: 咨询量 维度: 固有维度: 时间维度: 年 季度 月 天 小时 产品属性维度: 总咨询量 地区维度 来源渠道维度 DWS层表: 组成部分: 指标统计结果字段 + 维度字段 + 业务查询字段(time_type,group_type,time_str) 最终组合下DWS层字段: sid_total,sessionid_total,ip_total,area,origin_channel hourinfo,time_type,group_type,time_str yearinfo, quarterinfo,monthinfo,dayinfo,
APP层: 数据应用层
思考: 是否还需要对DWS层数据进行统计? ---> 是否在DWS层以及将需要的结果统计出来了?此时发现, 需要要求安装各个维度统计结果此时在DWS层以及统计完成了, 此时不需要在继续统计了, 所以不需要app层如果说, 需要计算比率 , 咨询率 此时可能需要app层
DIM层: 维表层
在项目中:
ODS层: ZLIB+ORC
其他层次: SNAPPY + ORC
说明: 如果存储空间比较宽裕的, 建议在hive中建表时都可以采用snappy压缩方案
分区表的作用: 提升查询的性能
原因: 分区表可以将数据按照分区字段将其划分到多个文件夹中, 在查询的时候, 根据分区字段查询, 此时hive回到指定分区目录下查询数据, 不需要在查询其他目录, 从而可以减少查询数据的扫描量, 从而提升效率 所以说 在hive中构建表的时候, 一般都是构建分区表
思考: 构建分区表, 如何向分区表添加数据
方案一: 静态分区(人为指定分区的值) 格式: 1) load data [local] inpath '路径' into|overwrite table 表名 partition(分区字段1=值1, 分区字段2=值2,...) 2) insert into|overwrite table 表名 partition(分区字段1=值1,分区字段2=值2....) +select .... 方案二: 动态分区(一次性向表中添加多个分区) 格式: insert into|overwrite table 表名 partition(分区字段1,分区字段2....) +select .... 注意: 如果使用动态分区, 必须满足以下条件 1) 必须配置以下参数: set hive.exec.dynamic.partition=true; 开启动态分区支持 set hive.exec.dynamic.partition.mode=nonstrict; 开启非严格模式 2) select查询语句结果最后面必须是分区字段,而且要保证顺序 方案三: 动静混合 格式: insert into|overwrite table 表名 partition(分区字段1=值1,分区字段2,分区字段3....) +select .... 注意: 如果使用动静混合分区, 必须满足以下条件 1) 必须配置以下参数: set hive.exec.dynamic.partition=true; 开启动态分区支持 set hive.exec.dynamic.partition.mode=nonstrict; 开启非严格模式 2) select查询语句结果最后面必须是动态分区字段,而且要保证顺序
优化动态分区配置:
主要作用: 当电脑内存资源不足时候, 可以开启此参数, 一旦开启, 整个hive翻译MR只会保持一个输出reduce, 从而降低资源的占用情况, 保证正常执行 弊端: 执行效率会降低
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DgdiApNK-1626155328764)(day24_教育项目.assets/image-20210227203656672.png)]
-- 构建ODS的库 CREATE DATABASE IF NOT EXISTS `itcast_ods`; --写入时压缩生效 set hive.exec.orc.compression.strategy=COMPRESSION; CREATE EXTERNAL TABLE IF NOT EXISTS itcast_ods.web_chat_ems ( id INT comment '主键', create_date_time STRING comment '数据创建时间', session_id STRING comment '七陌sessionId', sid STRING comment '访客id', create_time STRING comment '会话创建时间', seo_source STRING comment '搜索来源', seo_keywords STRING comment '关键字', ip STRING comment 'IP地址', area STRING comment '地域', country STRING comment '所在国家', province STRING comment '省', city STRING comment '城市', origin_channel STRING comment '投放渠道', user_match STRING comment '所属坐席', manual_time STRING comment '人工开始时间', begin_time STRING comment '坐席领取时间 ', end_time STRING comment '会话结束时间', last_customer_msg_time_stamp STRING comment '客户最后一条消息的时间', last_agent_msg_time_stamp STRING comment '坐席最后一下回复的时间', reply_msg_count INT comment '客服回复消息数', msg_count INT comment '客户发送消息数', browser_name STRING comment '浏览器名称', os_info STRING comment '系统名称') comment '访问会话信息表' PARTITIONED BY(starts_time STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' stored as orc location '/user/hive/warehouse/itcast_ods.db/web_chat_ems_ods' TBLPROPERTIES ('orc.compress'='ZLIB'); CREATE EXTERNAL TABLE IF NOT EXISTS itcast_ods.web_chat_text_ems ( id INT COMMENT '主键来自MySQL', referrer STRING comment '上级来源页面', from_url STRING comment '会话来源页面', landing_page_url STRING comment '访客着陆页面', url_title STRING comment '咨询页面title', platform_description STRING comment '客户平台信息', other_params STRING comment '扩展字段中数据', history STRING comment '历史访问记录' ) comment 'EMS-PV测试表' PARTITIONED BY(start_time STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' stored as orc location '/user/hive/warehouse/itcast_ods.db/web_chat_text_ems_ods' TBLPROPERTIES ('orc.compress'='ZLIB');
-- 构建DWD的库 CREATE DATABASE IF NOT EXISTS `itcast_dwd`; create table if not exists itcast_dwd.visit_consult_dwd( session_id STRING comment '七陌sessionId', sid STRING comment '访客id', create_time bigint comment '会话创建时间', seo_source STRING comment '搜索来源', ip STRING comment 'IP地址', area STRING comment '地域', msg_count int comment '客户发送消息数', origin_channel STRING COMMENT '来源渠道', referrer STRING comment '上级来源页面', from_url STRING comment '会话来源页面', landing_page_url STRING comment '访客着陆页面', url_title STRING comment '咨询页面title', platform_description STRING comment '客户平台信息', other_params STRING comment '扩展字段中数据', history STRING comment '历史访问记录', hourinfo string comment '小时', quarterinfo string comment '季度' ) comment '访问咨询DWD表' partitioned by(yearinfo String, monthinfo String, dayinfo string) row format delimited fields terminated by '\t' stored as orc location '/user/hive/warehouse/itcast_dwd.db/visit_consult_dwd' tblproperties ('orc.compress'='SNAPPY');
-- 构建DWS的库 CREATE DATABASE IF NOT EXISTS `itcast_dws`; CREATE TABLE IF NOT EXISTS itcast_dws.visit_dws ( sid_total INT COMMENT '根据sid去重求count', sessionid_total INT COMMENT '根据sessionid去重求count', ip_total INT COMMENT '根据IP去重求count', area STRING COMMENT '区域信息', seo_source STRING COMMENT '搜索来源', origin_channel STRING COMMENT '来源渠道', hourinfo STRING COMMENT '创建时间,统计至小时', quarterinfo STRING COMMENT '季度', time_str STRING COMMENT '时间明细', from_url STRING comment '会话来源页面', groupType STRING COMMENT '产品属性类型:1.地区;2.搜索来源;3.来源渠道;4.会话来源页面;5.总访问量', time_type STRING COMMENT '时间聚合类型:1、按小时聚合;2、按天聚合;3、按月聚合;4、按季度聚合;5、按年聚合;') comment 'EMS访客日志dws表' PARTITIONED BY(yearinfo STRING,monthinfo STRING,dayinfo STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' stored as orc location '/user/hive/warehouse/itcast_dws.db/visit_dws' TBLPROPERTIES ('orc.compress'='SNAPPY'); CREATE TABLE IF NOT EXISTS itcast_dws.consult_dws ( sid_total INT COMMENT '根据sid去重求count', sessionid_total INT COMMENT '根据sessionid去重求count', ip_total INT COMMENT '根据IP去重求count', area STRING COMMENT '区域信息', origin_channel STRING COMMENT '来源渠道', hourinfo STRING COMMENT '创建时间,统计至小时', quarterinfo STRING COMMENT '季度', time_str STRING COMMENT '时间明细', groupType STRING COMMENT '产品属性类型:1.地区;2.来源渠道', time_type STRING COMMENT '时间聚合类型:1、按小时聚合;2、按天聚合;3、按月聚合;4、按季度聚合;5、按年聚合;' ) COMMENT '咨询量DWS宽表' PARTITIONED BY (yearinfo string, monthinfo STRING, dayinfo string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS ORC LOCATION '/user/hive/warehouse/itcast_dws.db/consult_dws' TBLPROPERTIES ('orc.compress'='SNAPPY');
一般情况下, HDFS的副本数量选择为 3 如果数据不是特别重要 可以设置副本数量为2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C1CMspY9-1626155328764)(day24_教育项目.assets/image-20210227205306900.png)]
cpu配置
配置项:yarn.nodemanager.resource.cpu-vcores
默认值: 8
表示: 每一个nodemanager对应服务器的cpu核心数为 8
推荐配置: 和nodemanager对应服务器的cpu核心保持一致即可
如何查询服务器的cpu的核心数呢?
grep 'processor' /proc/cpuinfo | sort -u | wc -l
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j6yq0m3t-1626155328765)(day24_教育项目.assets/image-20210227205547341.png)]
如何配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rkNmUOng-1626155328765)(day24_教育项目.assets/image-20210227205631773.png)]
内存配置
配置项: yarn.nodemanager.resource.memory-mb | yarn.scheduler.maximum-allocation-mb | yarn.app.mapreduce.am.command-opts
说明: yarn.nodemanager.resource.memory-mb | yarn.scheduler.maximum-allocation-mb : 内存大小配置一致 yarn.app.mapreduce.am.command-opts : 略小于 上面的配置 0.9 左右
默认值: 8GB
推荐配置: 当前服务器剩余内存 * 0.8
如何查看电脑剩余内存呢?
shell命令查询: free -m
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fztgkj0i-1626155328766)(day24_教育项目.assets/image-20210227210020714.png)]
通过CM查看:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jgvd0vJZ-1626155328767)(day24_教育项目.assets/image-20210227210051940.png)]
如何配置:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CYVtjedl-1626155328767)(day24_教育项目.assets/image-20210227210125896.png)]
特殊注意点: 这些内容, 不需要在当前项目中进行修改, 项目中相关配置, 提前配置完成, 不要乱动, 否则会出现不可预估的错误
MR的内存配置
mapreduce.map.memory.mb : MR的map程序内存大小配置 mapreduce.reduce.memory.mb : MR的reduce程序内存大小配置 mapreduce.map.java.opts : MR的map程序的jvm 内存大小配置 mapreduce.reduce.java.opts: MR的reduce程序的jvm 内存大小配置 原则: 每一个配置, 最大值不能超过nodemanager的内存配置大小
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MHTEfkzp-1626155328768)(day24_教育项目.assets/image-20210227210849797.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zacicbpE-1626155328768)(day24_教育项目.assets/image-20210227212221682.png)]
hiveserver2异常退出错误
一般出现的原因:
hiveserver2内存溢出错误, 导致hiveserver2宕机
解决方案: 调整hiveserver2内存大小 , 后期会调整为 2GB
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IioA20Dl-1626155328769)(day24_教育项目.assets/image-20210227212354263.png)]
mapreduce.map.output.compress : 是否开启MR中map阶段的压缩配置 默认值为: true mapreduce.map.output.compress.codec : map阶段压缩采用合并压缩算法 推荐配置: org.apache.hadoop.io.compress.SnappyCodec mapreduce.output.fileoutputformat.compress : 是否开启reduce端压缩配置 默认为:false mapreduce.output.fileoutputformat.compress.codec : reduce端采用何种压缩算法 推荐配置: org.apache.hadoop.io.compress.SnappyCodec mapreduce.output.fileoutputformat.compress.type : reduce端采用压缩方式 默认值: RECORD(行压缩) 可选值: BLOCK(块压缩) 推荐配置: BLOCK set hive.exec.compress.intermediate=true; : hive是否开启中间结果压缩配置 默认为 true set hive.exec.compress.output=true; hive是否开启最终结果压缩配置 默认为 false
hive可选引擎: MR 和 spark
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dZWdlFqg-1626155328770)(day24_教育项目.assets/image-20210227213513711.png)]
目的: 将数据源中数据导入到ODS层对应表
要求: 将mysql的数据 导入 hive中, 请思考, 需要使用什么技术来解决呢? sqoop
思考: 使用sqoop导入到hive中, sqoop支持两种方式导入hive: 原生方式 和 hcatalog方式, 使用那种? 为什么
使用hcatalog 因为 表的数据格式为ORC, 而原生方式仅支持 textFile
-- 第一种 sqoop import \ --connect jdbc:mysql://192.168.52.150:3306/test \ --username root \ --password 123456 \ --table emp \ --fields-terminated-by '\t' \ --hcatalog-database sqooptohive \ --hcatalog-table emp_hive \ -m 1 -- 第二种 sqoop import \ --connect jdbc:mysql://192.168.52.150:3306/test \ --username root \ --password 123456 \ --query "select * from emp where id>1205 and \$CONDITIONS" \ --fields-terminated-by '\t' \ --hcatalog-database sqooptohive \ --hcatalog-table emp_hive \ -m 1 请问: 在此处选择第几种呢? 为什么 只能使用第二种方式, 因为 ods中表的user字段和数据源中user字段不相同, 如果使用第一种,要求两端字段, 必须完全一致, 否则导入不成功
第一个表: SELECT id,create_date_time,session_id,sid, create_time,seo_source,seo_keywords,ip,AREA,country, province,city,origin_channel,USER AS user_match,manual_time,begin_time, end_time,last_customer_msg_time_stamp,last_agent_msg_time_stamp, reply_msg_count,msg_count,browser_name,os_info,'2021-02-27' AS starts_time FROM web_chat_ems_2019_07 ; 第二个表: SELECT id,referrer,from_url,landing_page_url, url_title,platform_description,other_params, history,'2021-02-27' AS start_time FROM web_chat_text_ems_2019_07 ;
# 第一个表 sqoop import \ --connect jdbc:mysql://192.168.52.150:3306/nev \ --username root \ --password 123456 \ --query "SELECT id,create_date_time,session_id,sid, create_time,seo_source,seo_keywords,ip,AREA,country, province,city,origin_channel,USER AS user_match,manual_time,begin_time, end_time,last_customer_msg_time_stamp,last_agent_msg_time_stamp, reply_msg_count,msg_count,browser_name,os_info,'2021-02-27' AS starts_time FROM web_chat_ems_2019_07 where 1=1 and \$CONDITIONS" \ --fields-terminated-by '\t' \ --hcatalog-database itcast_ods \ --hcatalog-table web_chat_ems \ -m 1 # 第二个表 sqoop import \ --connect jdbc:mysql://192.168.52.150:3306/nev \ --username root \ --password 123456 \ --query "SELECT id,referrer,from_url,landing_page_url, url_title,platform_description,other_params, history,'2021-02-27' AS start_time FROM web_chat_text_ems_2019_07 where 1=1 and \$CONDITIONS" \ --fields-terminated-by '\t' \ --hcatalog-database itcast_ods \ --hcatalog-table web_chat_text_ems \ -m 1
1) 分别在mysql和 hive中查询数据的条数, 如果一致, 说明导入成功了 select count(1) from 表 ; 2) 查询表中某一条数据, 观察数据是否导入成功 select * from itcast_ods.web_chat_ems limit 1; 3) 在HDFS中查看是否构建对应分区数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8EGApwne-1626155328770)(day24_教育项目.assets/image-20210227215653638.png)]
目的: ODS层 --> DWD层 过程
思考:
清洗什么内容: 在第一个模块中并不需要进行清洗. 此功能没有 转换什么内容: 1) create_time 时间字段 需要转换为: yearinfo quarterinfo monthinfo dayinfo hourinfo 2) 将create_time 时间字段, 转换为时间戳:
select wce.session_id, wce.sid, wce.create_time , -- 说明: 此处需要转换为时间戳 wce.seo_source, wce.ip, wce.area, wce.msg_count, wce.origin_channel, wcte.referrer, wcte.from_url, wcte.landing_page_url, wcte.url_title, wcte.platform_description, wcte.other_params, wcte.history, wce.create_time as hourinfo , -- 此处需要转换 wce.create_time as quarterinfo, -- 此处需要转换 wce.create_time as yearinfo, -- 此处需要转换 wce.create_time as monthinfo, -- 此处需要转换 wce.create_time as dayinfo -- 此处需要转换 from itcast_ods.web_chat_ems wce join itcast_ods.web_chat_text_ems wcte on wce.id = wcte.id ; 注意: 此SQL 还没有完成 转换工作
1) 转换: 将 create_time 转换为时间戳 create_time 原始值: 2019-07-02 00:00:00 如何实现转换呢? 需要使用与时间相关的函数 unix_timestamp(string date, string pattern) 案例操作: -- unix_timestamp(string date, string pattern) select unix_timestamp('2019-07-02 00:00:00', 'yyyy-MM-dd HH:mm:ss'); 日期转换时间戳 -- from_unixtime(1323308943,'yyyyMMdd') select from_unixtime(1561996800,'yyyy-MM-dd HH:mm:ss') 时间戳转日期 2) 转换: 将 create_time 转换为 yearinfo quarterinfo monthinfo dayinfo hourinfo create_time 原始值: 2019-07-02 00:00:00 如何转换呢? 方式一: 采用日期函数来解决 year() quarter() month() day() hour() 案例: select year('2019-07-02 00:00:00'); -- 2019 select quarter('2019-07-02 00:00:00'); -- 3 select month('2019-07-02 00:00:00'); -- 7 select day('2019-07-02 00:00:00'); -- 2 select hour('2019-07-02 00:00:00'); -- 0 说明. 结果要求 月份 小时 天 必须为二位数, 不能写单值, 如果是单值前面必须加 0 方式二: 采用字符串截取的方式来获取 相关的函数:substr(string A, int start, int len),substring(string A, int start, int len) 案例: select substr('2019-07-02 00:00:00',1,4 ); -- 2019 select substr('2019-07-02 00:00:00',6,2 ) ; -- 07 select substr('2019-07-02 00:00:00',9,2 ) ; -- 02 select substr('2019-07-02 00:00:00',12,2 ) ; -- 00
select wce.session_id, wce.sid, unix_timestamp(wce.create_time,'yyyy-MM-dd HH:mm:ss') as create_time, wce.seo_source, wce.ip, wce.area, wce.msg_count, wce.origin_channel, wcte.referrer, wcte.from_url, wcte.landing_page_url, wcte.url_title, wcte.platform_description, wcte.other_params, wcte.history, substr(wce.create_time,12,2) as hourinfo , quarter(wce.create_time) as quarterinfo, substr(wce.create_time,1,4) as yearinfo, substr(wce.create_time,6,2) as monthinfo, substr(wce.create_time,9,2) as dayinfo from itcast_ods.web_chat_ems wce join itcast_ods.web_chat_text_ems wcte on wce.id = wcte.id ;
--动态分区配置 set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; --hive压缩 set hive.exec.compress.intermediate=true; set hive.exec.compress.output=true; --写入时压缩生效 set hive.exec.orc.compression.strategy=COMPRESSION; insert into table itcast_dwd.visit_consult_dwd partition(yearinfo,monthinfo,dayinfo) select wce.session_id, wce.sid, unix_timestamp(wce.create_time,'yyyy-MM-dd HH:mm:ss') as create_time, wce.seo_source, wce.ip, wce.area, wce.msg_count, wce.origin_channel, wcte.referrer, wcte.from_url, wcte.landing_page_url, wcte.url_title, wcte.platform_description, wcte.other_params, wcte.history, substr(wce.create_time,12,2) as hourinfo , quarter(wce.create_time) as quarterinfo, substr(wce.create_time,1,4) as yearinfo, substr(wce.create_time,6,2) as monthinfo, substr(wce.create_time,9,2) as dayinfo from itcast_ods.web_chat_ems wce join itcast_ods.web_chat_text_ems wcte on wce.id = wcte.id ;
可能报出的错误:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YDmO0TI7-1626155328771)(day24_教育项目.assets/image-20210302205243821.png)]
原因:
可能是由于服务器内存不足引起的, 在进行mapJoin时候, 内存不足以放下小表中的数据
解决方案:
set hive.auto.convert.join= false;
目的: DWD --> DWS
dws的目的 是将要统计的指标, 根据各个维度进行细化统计
指标: 访问量 维度: 固有维度: 时间维度: 年 季度 月 天 小时 产品属性维度: 总访问量 地区维度 来源渠道维度 搜索来源维度 受访页面维度 相关的需求: 1) 统计每年的总访问量数据 2) 统计每年 每季度的总访问量数据 3) 统计每年 每季度 每月的总访问量数据 ...... 1) 统计 每年 各个地区的访问量数据 2) 统计每年 每季度 各个地区访问量数据 ..... 1) 统计 每年 各个来源渠道的访问量数据 ..... ...... 指标的计算: 先去重 在统计操作, 需要通过三个字段分别计算 (sid session_id ip)
-- 1) 统计每年的总访问量数据 insert into table itcast_dws.visit_dws partition(yearinfo,monthinfo,dayinfo) select count( distinct sid ) as sid_total, count( distinct session_id ) as sessionid_total, count( distinct ip) as ip_total, '-1' as area, '-1' as seo_source, '-1' as origin_channel, '-1' as hourinfo, '-1' as quarterinfo, yearinfo as time_str, '-1' as from_url, '5' as grouptype, '5' as time_type, yearinfo, '-1' as monthinfo, '-1' as dayinfo from itcast_dwd.visit_consult_dwd group by yearinfo ; -- 2) 统计每年 每季度的总访问量数据 insert into table itcast_dws.visit_dws partition(yearinfo,monthinfo,dayinfo) select count( distinct sid ) as sid_total, count( distinct session_id ) as sessionid_total, count( distinct ip) as ip_total, '-1' as area, '-1' as seo_source, '-1' as origin_channel, '-1' as hourinfo, quarterinfo, concat(yearinfo,'_',quarterinfo) as time_str, '-1' as from_url, '5' as grouptype, '4' as time_type, yearinfo, '-1' as monthinfo, '-1' as dayinfo from itcast_dwd.visit_consult_dwd group by yearinfo,quarterinfo ; -- 3) 统计每年 每季度 每月的总访问量数据 insert into table itcast_dws.visit_dws partition(yearinfo,monthinfo,dayinfo) select count( distinct sid ) as sid_total, count( distinct session_id ) as sessionid_total, count( distinct ip) as ip_total, '-1' as area, '-1' as seo_source, '-1' as origin_channel, '-1' as hourinfo, quarterinfo, concat(yearinfo,'-',monthinfo) as time_str, '-1' as from_url, '5' as grouptype, '3' as time_type, yearinfo, monthinfo, '-1' as dayinfo from itcast_dwd.visit_consult_dwd group by yearinfo,quarterinfo,monthinfo ; -- 4) 统计每年 每季度 每月 每天的总访问量数据 -- 5) 统计每年 每季度 每月 每天 每小时的总访问量数据
-- 1) 统计每年 各个受访页面 的总访问量数据insert into table itcast_dws.visit_dws partition(yearinfo,monthinfo,dayinfo)select count( distinct sid ) as sid_total,count( distinct session_id ) as sessionid_total,count( distinct ip) as ip_total,'-1' as area,'-1' as seo_source,'-1' as origin_channel,'-1' as hourinfo,'-1' as quarterinfo,yearinfo as time_str,from_url,'4' as grouptype,'5' as time_type,yearinfo,'-1' as monthinfo,'-1' as dayinfofrom itcast_dwd.visit_consult_dwdgroup by yearinfo ,from_url;-- 2) 统计每年 每季度 各个受访页面 的总访问量数据-- 3) 统计每年 每季度 每月 各个受访页面 的总访问量数据-- 4) 统计每年 每季度 每月 每天 各个受访页面 的总访问量数据-- 5) 统计每年 每季度 每月 每天 每小时 各个受访页面 的总访问量数据insert into table itcast_dws.visit_dws partition(yearinfo,monthinfo,dayinfo)select count( distinct sid ) as sid_total,count( distinct session_id ) as sessionid_total,count( distinct ip) as ip_total,'-1' as area,'-1' as seo_source,'-1' as origin_channel,hourinfo,quarterinfo,concat(yearinfo,'-',monthinfo,'-',dayinfo,' ',hourinfo) as time_str,from_url,'4' as grouptype,'1' as time_type,yearinfo,monthinfo,dayinfofrom itcast_dwd.visit_consult_dwdgroup by yearinfo ,quarterinfo,monthinfo,dayinfo,hourinfo, from_url;
统计咨询量数据
访问量和咨询量的区别: 咨询量多了一个条件: msg_count >=1 指标: 咨询量维度: 固有维度: 时间维度: 年 季度 月 天 小时 产品属性维度: 总咨询量 地区维度 来源渠道维度
-- 1) 统计每年 的总咨询量数据insert into table itcast_dws.consult_dws partition(yearinfo,monthinfo,dayinfo)selectcount( distinct sid ) as sid_total,count( distinct session_id ) as sessionid_total,count( distinct ip) as ip_total,'-1' as area,'-1' as origin_channel,'-1' as hourinfo,'-1' as quarterinfo,yearinfo as time_str,'3' as grouptype,'5' as time_type,yearinfo,'-1' as monthinfo,'-1' as dayinfofrom itcast_dwd.visit_consult_dwd where msg_count >=1group by yearinfo;-- 2) 统计每年 每季度 的总咨询量数据insert into table itcast_dws.consult_dws partition(yearinfo,monthinfo,dayinfo)selectcount( distinct sid ) as sid_total,count( distinct session_id ) as sessionid_total,count( distinct ip) as ip_total,'-1' as area,'-1' as origin_channel,'-1' as hourinfo,quarterinfo,concat(yearinfo,'_',quarterinfo) as time_str,'3' as grouptype,'4' as time_type,yearinfo,'-1' as monthinfo,'-1' as dayinfofrom itcast_dwd.visit_consult_dwd where msg_count >=1group by yearinfo,quarterinfo;-- 3) 统计每年 每季度 每月 的总咨询量数据-- 4) 统计每年 每季度 每月 每天 的总咨询量数据-- 5) 统计每年 每季度 每月 每天 每小时 的总咨询量数据
目的: DWS层 --> mysql中
操作: sqoop
-- 第一步; 在mysql中构建目标表CREATE DATABASE scrm_bi DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;USE scrm_bi ;CREATE TABLE `itcast_visit` ( sid_total INT(11) COMMENT '根据sid去重求count', sessionid_total INT(11) COMMENT '根据sessionid去重求count', ip_total INT(11) COMMENT '根据IP去重求count', AREA VARCHAR(32) COMMENT '区域信息', seo_source VARCHAR(32) COMMENT '搜索来源', origin_channel VARCHAR(32) COMMENT '来源渠道', hourinfo VARCHAR(32) COMMENT '小时信息', quarterinfo VARCHAR(32) COMMENT '季度', time_str VARCHAR(32) COMMENT '时间明细', from_url VARCHAR(32) COMMENT '会话来源页面', groupType VARCHAR(32) COMMENT '产品属性类型:1.地区;2.搜索来源;3.来源渠道;4.会话来源页面;5.总访问量', time_type VARCHAR(32) COMMENT '时间聚合类型:1、按小时聚合;2、按天聚合;3、按月聚合;4、按季度聚合;5、按年聚合;', yearinfo VARCHAR(32) COMMENT '年信息', monthinfo VARCHAR(32) COMMENT '月信息', dayinfo VARCHAR(32) COMMENT '日信息');CREATE TABLE `itcast_consult` ( sid_total INT(11) COMMENT '去重并聚合sid', sessionid_total INT(11) COMMENT '去重并聚合sessionid', ip_total INT(11) COMMENT '去重并聚合ip', AREA VARCHAR(32) COMMENT '区域信息', origin_channel VARCHAR(32) COMMENT '来源渠道', hourinfo VARCHAR(5) COMMENT '创建时间,统计至小时', quarterinfo VARCHAR(5) COMMENT '季度', time_str VARCHAR(32) COMMENT '时间明细', groupType VARCHAR(5) COMMENT '产品属性类型:1.地区;2.来源渠道', time_type VARCHAR(5) COMMENT '时间聚合类型:1、按小时聚合;2、按天聚合;3、按月聚合;4、按季度聚合;5、按年聚合;', yearinfo VARCHAR(5) COMMENT '创建时间,统计至年', monthinfo VARCHAR(5) COMMENT '创建时间,统计至月', dayinfo VARCHAR(5) COMMENT '创建时间,统计至天') COMMENT='客户咨询统计数据';--第二步: 编写sqoop命令执行导出即可sqoop export \--connect "jdbc:mysql://192.168.52.150:3306/scrm_bi?useUnicode=true&characterEncoding=utf-8" \--username root \--password '123456' \--table itcast_visit \--hcatalog-database itcast_dws \--hcatalog-table visit_dws \-m 1sqoop export \--connect "jdbc:mysql://192.168.52.150:3306/scrm_bi?useUnicode=true&characterEncoding=utf-8" \--username root \--password '123456' \--table itcast_consult \--hcatalog-database itcast_dws \--hcatalog-table consult_dws \-m 1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7TmsyWsV-1626155328771)(day24_教育项目.assets/image-20210302211817290.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJmc9Xa2-1626155328772)(day24_教育项目.assets/image-20210302212028803.png)]
增量流程: T+1模式
每天都需要对上一天的数据进行增量操作
CREATE TABLE web_chat_ems_2021_03 ASSELECT * FROM web_chat_ems_2019_07 WHERE create_time BETWEEN '2019-07-01 00:00:00' AND '2019-07-01 23:59:59' ;UPDATE web_chat_ems_2021_03 SET create_time = CONCAT('2021-03-01 ',SUBSTRING(create_time,12));CREATE TABLE web_chat_text_ems_2021_03 AS SELECT * FROM web_chat_text_ems_2019_07 ;
-- 第一张表SELECT id,create_date_time,session_id,sid,create_time,seo_source,seo_keywords,ip,AREA,country,province,city,origin_channel,USER AS user_match,manual_time,begin_time,end_time,last_customer_msg_time_stamp,last_agent_msg_time_stamp,reply_msg_count,msg_count,browser_name,os_info,'2021-03-01' AS starts_timeFROM web_chat_ems_2021_03 WHERE create_time BETWEEN '2021-03-01 00:00:00' AND '2021-03-01 23:59:59' ; --第二张表:SELECT wcte.id,wcte.referrer,wcte.from_url,wcte.landing_page_url,wcte.url_title,wcte.platform_description,wcte.other_params,wcte.history,'2021-03-01' AS start_timeFROM web_chat_text_ems_2021_03 wcte JOIN (SELECT id FROM web_chat_ems_2021_03 WHERE create_time BETWEEN '2021-03-01 00:00:00' AND '2021-03-01 23:59:59') AS wce ON wce.id = wcte.id ;
# 第一个表sqoop import \--connect jdbc:mysql://192.168.52.150:3306/nev \--username root \--password 123456 \--query "SELECT id,create_date_time,session_id,sid,create_time,seo_source,seo_keywords,ip,AREA,country,province,city,origin_channel,USER AS user_match,manual_time,begin_time,end_time,last_customer_msg_time_stamp,last_agent_msg_time_stamp,reply_msg_count,msg_count,browser_name,os_info,'2021-03-01' AS starts_timeFROM web_chat_ems_2021_03 WHERE create_time BETWEEN '2021-03-01 00:00:00' AND '2021-03-01 23:59:59' and \$CONDITIONS" \--fields-terminated-by '\t' \--hcatalog-database itcast_ods \--hcatalog-table web_chat_ems \--hive-partition-key starts_time \--hive-partition-value 2021-03-01 \-m 1# 第二个表sqoop import \--connect jdbc:mysql://192.168.52.150:3306/nev \--username root \--password 123456 \--query "SELECT wcte.id,wcte.referrer,wcte.from_url,wcte.landing_page_url,wcte.url_title,wcte.platform_description,wcte.other_params,wcte.history,'2021-03-01' AS start_timeFROM web_chat_text_ems_2021_03 wcte JOIN (SELECT id FROM web_chat_ems_2021_03 WHERE create_time BETWEEN '2021-03-01 00:00:00' AND '2021-03-01 23:59:59') AS wce ON wce.id = wcte.id where 1=1 and \$CONDITIONS" \--fields-terminated-by '\t' \--hcatalog-database itcast_ods \--hcatalog-table web_chat_text_ems \--hive-partition-key start_time \--hive-partition-value 2021-03-01 \-m 1
上述的SQL或者sqoop命令, 存在 日期写死的状态, 后期每一天都需要修改这个SQL语句
第一个问题: shell如何获取上一天的日期呢? date +'%Y-%m-%d %H:%M:%S' -- 以特定的格式输出当前的日期 date -d '-1 week' +'%Y-%m-%d %H:%M:%S' date -d '-1 day' +'%Y-%m-%d %H:%M:%S'
#!/bin/bashexport SQOOP_HOME=/usr/bin/sqoopif [ $# -eq 1 ]then timestr=$1 yearAndMonth=`date -d $1 +'%Y_%m'`else timestr=`date -d '-1 day' +'%Y-%m-%d'` yearAndMonth=`date -d '-1 day' +'%Y_%m'`fijdbcUrl='jdbc:mysql://192.168.52.150:3306/nev'username='root'password='123456'${SQOOP_HOME} import \--connect ${jdbcUrl} \--username ${username} \--password ${password} \--query "SELECT id,create_date_time,session_id,sid,create_time,seo_source,seo_keywords,ip,AREA,country,province,city,origin_channel,USER AS user_match,manual_time,begin_time,end_time,last_customer_msg_time_stamp,last_agent_msg_time_stamp,reply_msg_count,msg_count,browser_name,os_info,'${timestr}' AS starts_timeFROM web_chat_ems_${yearAndMonth} WHERE create_time BETWEEN '${timestr} 00:00:00' AND '${timestr} 23:59:59' and \$CONDITIONS" \--fields-terminated-by '\t' \--hcatalog-database itcast_ods \--hcatalog-table web_chat_ems \--hive-partition-key starts_time \--hive-partition-value ${timestr} \-m 1wait${SQOOP_HOME} import \--connect ${jdbcUrl} \--username ${username} \--password ${password} \--query "SELECT wcte.id,wcte.referrer,wcte.from_url,wcte.landing_page_url,wcte.url_title,wcte.platform_description,wcte.other_params,wcte.history,'${timestr}' AS start_timeFROM web_chat_text_ems_${yearAndMonth} wcte JOIN (SELECT id FROM web_chat_ems_${yearAndMonth} WHERE create_time BETWEEN '${timestr} 00:00:00' AND '${timestr} 23:59:59') AS wce ON wce.id = wcte.id where 1=1 and \$CONDITIONS" \--fields-terminated-by '\t' \--hcatalog-database itcast_ods \--hcatalog-table web_chat_text_ems \--hive-partition-key start_time \--hive-partition-value ${timestr} \-m 1
– 执行时间: 20分钟 以上 ~ 40分钟左右