hive 之实战统计地区产品点击TOPN

目录

1.数据准备

2.安装sqoop

3.使用sqoop将mysql中数据抽到hive

4.求每个区域点击Top3的产品


1.数据准备

1.1产品信息表,存放在msyql关系型数据库

    hive 之实战统计地区产品点击TOPN_第1张图片

sql脚本百度网盘链接:
链接:https://pan.baidu.com/s/1dT8Rt2L49VMoi6OY3qCE2g
提取码:bhbx

1.2城市信息表,存放在mysql关系型数据库

 

   hive 之实战统计地区产品点击TOPN_第2张图片

sql脚本百度网盘链接:
链接:https://pan.baidu.com/s/1jJHVWTAMDMkpBNndCQxTUQ
提取码:jh2i

1.3用户点击行为信息表,生产中是是日志数据(页面埋点得到),存放在hdfs,为hive表

用户点击日志数据网盘链接:
链接:https://pan.baidu.com/s/1wFXTcQL-_wXEKQT1PM-c3g
提取码:b31w
#创建hive表,并加载数据
create table user_click(
user_id int,
session_id string,
action_time string,
city_id int,
product_id int
) partitioned by (day string)
row format delimited fields terminated by ',';
load data local inpath '/home/hadoop/data/topn/user_click.txt' overwrite into table user_click partition(day='2016-05-05');

2.安装sqoop

2.1sqoop简介

  一个将关系型数据库中的数据高效导入hadoop生态圈的工具。是apache的顶级项目。生产中更倾向使用的Sqoop1的相关版本,sqoop2版本并不好用,与sqoop1不兼容,不适用于生产部署。

  本质是MR的作业。

2.2下载

  我安装的是CDH5.7.0系列的软件,故我下载的是sqoop-1.4.6-cdh5.7.0.tar.gz版本

  下载地址:http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.6-cdh5.7.0.tar.gz

2.3解压安装

  tar -zxvf sqoop-1.4.6-cdh5.7.0.tar.gz -C ~/app/

2.4拷贝mysql驱动jar包

cd ~/app/sqoop-1.4.6-cdh5.7.0/
cp ~/app/hive-1.1.0-cdh5.7.0/lib/mysql-connector-java-5.1.25.jar ~/app/sqoop-1.4.6-cdh5.7.0/lib/

2.5修改配置文件

cp conf/sqoop-env-template.sh conf/sqoop-env.sh #复制一份配置文件
vim conf/sqoop-env.sh #修改或追加,hadoop和hive的安装目录配置
export HADOOP_COMMON_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.7.0
export HADOOP_MAPRED_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.7.0
export HIVE_HOME=/home/hadoop/app/hive-1.1.0-cdh5.7.0

2.6添加环境变量

vim ~/.bash_profile  #添加如下环境变量
export SQOOP_HOME=/home/hadoop/app/sqoop-1.4.6-cdh5.7.0
export PATH=$SQOOP_HOME/bin:$PATH
source ~/.bash_profile #使环境变量生效
sqoop help #查看sqoop的命令帮助

 扩展1:sqoop上的导入(import)指的是外部数据导入到Hadoop生态圈,导出(export)是将Hadoop生态圈上的数据导出到外部。

3.使用sqoop将mysql中数据抽到hive

3.1 查看sqoop的命令使用帮助

sqoop help 
sqoop import --help  #查看数据导入的命令帮助

3.2 hive创建相应的表

create table city_info(
city_id int,
city_name string,
area string
)row format delimited fields terminated by '\t';

create table product_info(
product_id int,
product_name string,
extend_info string
)row format delimited fields terminated by '\t';

 扩展2:生产上,sqoop数据导入时,hive上的表最好是手动创建的,不然可能会有各种问题。

3.3使用sqoop命令将mysql数据导入hive表中

sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root --password 123456 \
--delete-target-dir \
--table city_info \
--hive-import \
--hive-table hive.city_info \
--hive-overwrite \
--fields-terminated-by '\t' \
--lines-terminated-by '\n' \
--split-by city_id \
-m 2

我这里报异常信息:Exception in thread "main" java.lang.NoClassDefFoundError: org/json/JSONObject ,确实是少了对应的json 的 jar包,去http://www.java2s.com/Code/Jar/j/Downloadjavajsonjar.htm下载对应jar包,放到lib目录。

再次执行后报异常信息:ERROR hive.HiveConfig: Could not load org.apache.hadoop.hive.conf.HiveConf. Make sure HIVE_CONF_DIR is set correctly,显示是缺少了hive的jar包,复制hive的执行jar包到lib下。
cp ~/app/hive-1.1.0-cdh5.7.0/lib/hive-exec-1.1.0-cdh5.7.0.jar ~/app/sqoop-1.4.6-cdh5.7.0/lib/
再次执行加载数据语句,数据成功从mysql加载到hive。 

#执行加载产品表sqoop命令
sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root --password 123456 \
--delete-target-dir \
--table product_info \
--hive-import \
--hive-table hive.product_info \
--hive-overwrite \
--fields-terminated-by '\t' \
--lines-terminated-by '\n' \
--split-by product_id \
-m 2
#检查hive上的数据目录,发现有两个文件
hdfs dfs -ls /user/hive/warehouse/hive/city_info

 扩展3:由于sqoop在map任务前数据的分割与导出表主键相关,若导出表无主键,则必须指定数据分割的字段,这里指定的--split-by city_id,。

 扩展4:sqoop只有MAP操作,且默认的MAP数是4,通过-m去调整

4.求每个区域点击Top3的产品

4.1创建临时的商品基本信息表

create table tmp_product_click_basic_info
as
select u.product_id, u.city_id, c.city_name, c.area
from
(select product_id, city_id from user_click where day='2016-05-05' ) u
join
(select city_id, city_name,area from city_info) c
on u.city_id = c.city_id;

4.2创建各区域下各产品访问次数临时表

create table tmp_area_product_click_count
as
select
product_id, area, count(1) click_count
from
tmp_product_click_basic_info
group by
product_id, area

4.3获取完整的商品信息的各区域的访问次数

create table tmp_area_product_click_count_full_info
as
select
a.product_id, b.product_name, a.area, a.click_count
from
tmp_area_product_click_count a join product_info b
on a.product_id = b.product_id

4.4获取区域点击top3的商品。使用窗口函数row_number() over()

select *
from (
select
product_id, product_name,area, click_count,
row_number() over(partition by area order by click_count desc) rank
from
tmp_area_product_click_count_full_info
) t where t.rank <=3;

4.5创建一个topN结果表

create table area_product_click_count_top3
as
select t.*,'2016-05-05' as day
from (
select
product_id, product_name,area, click_count,
row_number() over(partition by area order by click_count desc) rank
from
tmp_area_product_click_count_full_info
) t where t.rank <=3;

4.6使用sqoop将topn的结果导入到mysql数据库。

#在mysql中创建一个top3的点击表
create table area_product_click_count_top3
(product_id int(11),
product_name varchar(255),
area varchar(255),
click_count int(11),
rank int(11),
day varchar(20))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
#使用sqoop将hive中的数据导出到mysql
sqoop export \
--connect jdbc:mysql://localhost:3306/test \
--username root --password 123456 \
--table area_product_click_count_top3 \
--columns product_id,product_name,area,click_count,rank,day \
--export-dir /user/hive/warehouse/hive.db/area_product_click_count_top3 \
--input-fields-terminated-by '\001' \
-m 2

此时我们可以从msyql的area_product_click_count_top3中查询出TopN的结果。若我们再次执行导出的语句会发现相同的数据会存在两份。故优化添加两行配置重新导入数据。

sqoop export \
--connect jdbc:mysql://localhost:3306/test \
--username root --password 123456 \
--table area_product_click_count_top3 \
--columns product_id,product_name,area,click_count,rank,day \
--update-key product_id \
--update-mode updateonly \
--export-dir /user/hive/warehouse/hive.db/area_product_click_count_top3 \
--input-fields-terminated-by '\001' \
-m 2

 扩展5:等值连接[“=”,join ,inner join],显示左右表共有的部分,即字段值在左右表都出现了。

 扩展6:大数据最好采取列式存储数据,因为如果一行的字段很多上百以上,即使只查询几个字段,行存储数据,在sql查询时依旧会查询所有字段,高IO。

 至此整个流程完成,上述整个流程是每天定时运行的,故我们可以编写一个shell脚本将hive的sql语句写进去,使用定时器定时的去执行。 这种处理是典型的离线处理方案。另外,上面很多group by 这可能会导致数据倾斜,那么数据倾斜应该怎么去解决???(面试必问)

 

 

你可能感兴趣的:(Hive)