Hive - 快速入门教程8(案例实操:离线数据统计分析)
作者:hangge | 2024-09-23 08:44
在企业中,Hive 最常见的应用场景是离线数据统计分析。文件将通过样例演示如何进行离线数据统计。
(2)Flume 将这些数据采集到 HDFS 后,需要先按“天”再按“类型”分目录存储,主要是因为后期的需求大部分都需要按天和类型分别统计分析。
(4)由于数据已经被 Flume 采集到 HDFS 中了,所以接下来不需要使用 load 命令,只需要使用 alter 命令添加分区信息即可。
(5)此时即可查到表中的数据:
(2)脚本里的内容如下:
(3)然后给该脚本设置权限:
(4)这个脚本需要配置一个定时任务,可以使用 Crontab 定时器。首先执行如下命令编辑 crontab 配置文件:
(5)里面添加如下内容,这样脚本每天凌晨 1 点便会执行:
(2)接着执行如下命令创建 videolnfo 类型的视图:
(3)最后执行如下命令创建 giftRecord 类型的视图:
(2)查看 2024 年 3 月 1 日这一天的所有直播信息:
八、案例实操:离线数据统计分析
1,需求说明
(1)使用 Flume 按天把直播 App 产生的日志数据采集到 HDFS 中的对应日期目录下,使用 Hive SQL 统计每天数据的相关指标。
(2)使用 Flume 按天把日志数据保存到 HDFS 中的对应日期目录下,此时 Flume 的 Source 可以使用 Exec Source,Channle 可以使用 Memory Channel,Sink 可以使用 HDFS Sink。由于数据是按天存储的,所以最好在 Hive 中使用外部分区表,这样可以提高后期的数据分析效率。
2,数据准备
(1)Flume 需要采集的数据包括用户信息、直播信息和送礼信息。这 3 种数据会被记录到同一个日志文件中,Flume 在采集时需要自行拆分。
- 用户信息数据格式如下:
{
"uid": "861848974414839801",
"nickname": "hangge",
"usign": "",
"sex": 1,
"birthday": "",
"face": "",
"big_face": "",
"email": "hangge@hangge.com",
"mobile": "",
"reg_type": "102",
"last_login_time": "1494344580",
"regtime": "1494344580",
"last_update_time": "1494344580",
"status": "5",
"is_verified": "0",
"verified_info": "",
"is_seller": "0",
"level": 1,
"exp": 0,
"anchor_level": 0,
"anchor_exp": 0,
"os": "android",
"timestamp": 1494344580,
"type": "userInfo"
}
- 直播信息数据格式如下:
{
"id": "14943445328940974601",
"uid": "840717325115457536",
"lat": "53.530598",
"lnt": "-2.5620373",
"hots": 0,
"title": "0",
"status": "1",
"topicId": "0",
"end_time": "1494344570",
"watch_num": 0,
"share_num": "1",
"replay_url": null,
"replay_num": 0,
"start_time": "1494344544",
"timestamp": 1494344571,
"type": "videoInfo"
}
- 送礼信息数据格式如下:
{
"send_id": "834688818270961664",
"good_id": "223",
"video_id": "14943443045138661356",
"gold": "10",
"timestamp": 1494344574,
"type": "qiftRecord"
}
(2)Flume 将这些数据采集到 HDFS 后,需要先按“天”再按“类型”分目录存储,主要是因为后期的需求大部分都需要按天和类型分别统计分析。
3,在 Hive 中创建外部分区表
(1)对于 JSON 格式的数据,在 Hive 中创建表时无法直接把每个字段都定义出来。常见的解决方案是:先开发一个 MapReduce/Spark 数据清洗程序,对 JSON 格式的数据进行解析,把每个字段的值都解析出来,拼成一行(在字段值中可以使用逗号将其进行分隔);然后基于解析之后的数据在 Hive 中建表。这个解决方案没有什么大问题,唯一的缺点是:需要开发 MapReduce/Spark 程序,比较麻烦。
(2)还有一种解决方案是:直接使用 Hive 解析数据,通过 get_json_object() 函数从 JSON 格式的数据中解析出指定字段值。这种方式不需要写代码,比较简单,具体实现步骤如下:
- 基于原始的 JSON 数据创建一个外部分区表,表中只有一个字段,保存原始的 JSON 字符串,分区字段是日期和类型。
- 创建一个视图,视图的功能是:查询前面创建的外部分区表,在视图中解析 JSON 数据中的字段。这样就比较方便了,以后直接查询视图即可,一行代码都不需要写。
(3)本文采用第二种方案,首先建立一个外部分区表 ex_par_more_type:
create external table ex_par_more_type( log string ) partitioned by(dt string, d_type string) row format delimited fields terminated by '\t' location '/moreType';
(4)由于数据已经被 Flume 采集到 HDFS 中了,所以接下来不需要使用 load 命令,只需要使用 alter 命令添加分区信息即可。
alter table ex_par_more_type add partition(dt='20240301',d_type='giftRecord')location'/moreType/20240301/giftRecord'; alter table ex_par_more_type add partition(dt='20240301',d_type='userInfo')location'/moreType/20240301/userInfo'; alter table ex_par_more_type add partition(dt='20240301',d_type='videoInfo')location'/moreType/20240301/videoInfo';
(5)此时即可查到表中的数据:
select * from ex_par_more_type where dt = '20240301' and d_type = 'giftRecord';
4,关联分区的操作封装脚本
(1)由于关联分区的操作需要每天都执行一次,所以最好将其封装到脚本中,每天定时调度一次。首先我们创建一个 shell 脚本:
vi addPartition.sh
(2)脚本里的内容如下:
#!/bin/bash
# 每天凌展 1 点定时添加当天日期的分区
if [ "a$1" = "a" ]
then
dt=`date +%Y%m%d`
else
dt=$1
fi
#指定添加分区操作
/usr/local/hive/bin/hive -e "
alter table ex_par_more_type add if not exists partition(dt='${dt}',d_type='giftRecord') location '/moreType/${dt}/giftRecord';
alter table ex_par_more_type add if not exists partition(dt='${dt}',d_type='userInfo') location '/moreType/${dt}/userInfo';
alter table ex_par_more_type add if not exists partition(dt='${dt}',d_type='videoInfo') location '/moreType/${dt}/videoInfo';
"
(3)然后给该脚本设置权限:
chomod 777 addPartition.sh
(4)这个脚本需要配置一个定时任务,可以使用 Crontab 定时器。首先执行如下命令编辑 crontab 配置文件:
vi /etc/crontab
(5)里面添加如下内容,这样脚本每天凌晨 1 点便会执行:
00 01 * * * root /bin/bash /usr/local/addPartition.sh >> /usr/local/addPartition.log
5,创建视图
接下来基于表 ex_par_more_type 创建视图,由于 3 种数据类型的字段是不一样的,所以需要对每一种数据类型都创建一个视图。
(1)首先执行如下命令创建 userlnfo 类型的视图:
create view user_info_view as select get_json_object(log, '$.uid') as uid, get_json_object(log, '$.nickname') as nickname, get_json_object(log, '$.usign') as usign, get_json_object(log, '$.sex') as sex, dt from ex_par_more_type where d_type ='userInfo';
(2)接着执行如下命令创建 videolnfo 类型的视图:
create view video_info_view as select get_json_object(log, '$.id') as id, get_json_object(log, '$.uid') as uid, get_json_object(log, '$.lat') as lat, get_json_object(log, '$.lnt') as lnt, dt from ex_par_more_type where d_type = 'videoInfo';
(3)最后执行如下命令创建 giftRecord 类型的视图:
create view gift_record_view as select get_json_object(log, '$.send_id') as send_id, get_json_object(log, '$.good_id') as good_id, get_json_object(log, '$.video_id') as video_id, get_json_object(log, '$.gold') as gold, dt from ex_par_more_type where d_type = 'giftRecord';
6,使用视图进行查询统计
(1)查看 2024 年 3 月 1 日这一天的所有用户信息:
select * from user_info_view where dt = '20240301';
(2)查看 2024 年 3 月 1 日这一天的所有直播信息:
select * from video_info_view where dt ='20240301';

(3)查看 2024 年 3 月 1 日这一天的所有送礼信息:
select * from gift_record_view where dt ='20240301';
全部评论(0)