持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
前言
前两篇文章我们讨论了如何使用Hadoop和组件的hbase,对于没有java或者scala基础的数据人员,直接使用hadoop过于困难,这里我们来研究一下hive组件,hive是hadoop框架中用于解析sql直接生效于mapreduce。Hive所有命令和查询都会进入Driver(驱动模块),通过该模块对输入进行解析编译,对需求的计算进行优化,然后按照指定的步骤执行(通常是启动多个MapReduce的job来执行)。当需要启动MapReduce任务(job)时,Hive本身是不会生成Java MapReduce算法程序。相反,Hive通过一个表示“job执行计划”的XML文件驱动执行内置的、原生的Mapper和Reducer模块。
hive的安装和设置
第一种方式使用brew安装:
brew install hive ,简单有效。如果没有办法使用homebrew的情况下可以去网站下载压缩包
mirrors.bfsu.edu.cn/apache/hive… 然后手动解压,
解压以后重命名一下文件夹。
首先需要修改常量配置文件
vi ~/.zshrc#编辑配置文件添加HIVE_HOME
export HIVE_HOME=/Users/xxx/Documents/software/hive-2.3.9
export PATH=$HIVE_HOME/bin:$PATH
source ~/.zshrc#重启使其生效
我们需要修改hive的一些配置文件,首先2.3.9的版本是没有hive-site.xml这个文件的,我们使用命令复制一下
cd /usr/local/Cellar/hive-2.3.9/libexec/conf
cp hive-default.xml.template hive-site.xml
然后添加如下的配置
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/metastore?createDatabaseIfNotExist=true</value><!--MySQL地址metastore是元数据库的名称,需要在mysql中创建相同名字的数据库-->
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value><!--MySQL驱动-->
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value><!--MySQL用户名-->
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value><!--MySQL密码-->
</property>
</configuration>
默认情况下,Hive元数据保存在内嵌的Derby中,只能允许一个会话连接,只适合简单的测试。实际生产环境中不使用,为了支持多用户会话,则需要一个独立的元数据库,使用MySQL作为元数据库,Hive内部对MySQL提供了很好的支持。所以我们这里需要安装一个mysql的数据库来支持hive
打开mysql以后我们用命令建一个库create database metastore;
然后进入hive的lib目录,下载mysql驱动包。
curl -O https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar
下载以后修改hive-env.sh,只需要修改一处,即将HADOOP_HOME补充完整即可。
HADOOP_HOME=/Users/xxx/Documents/software/hadoop-3.2.3
从 Hive 2.1 版本开始, 在第一次运行hive之前,需要先运行schematool命令来执行初始化操作 首先进入文件夹:
cd /Users/xxx/Documents/software/hive-2.3.9/bin
初始化数据库组件
schematool -initSchema -dbType mysql
然后先启动 hadoop组件./start-all.sh
然后在文件夹使用hive命令启动。 可以看到报了一个异常:
从报错信息来看: 系统找不到相关jar包 ,同一类型的 jar 包有不同版本存在,系统无法决定使用哪一个
解决办法就是复制hadoop中的jar包,覆盖掉hive中的旧版本
还有就是在hive运行前需要先启动metastore 服务器
hive --service metastore
然后Ctrl+C,再hive,进去
成功运行hive
测试hive
首先创建表:
CREATE TABLE t_movie(
MovieID int, MovieName STRING, MovieType STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
WITH SERDEPROPERTIES ("field.delim" = "::");
CREATE TABLE t_user(
UserID int, Sex string, Age int, Occupation int, Zipcode int
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
WITH SERDEPROPERTIES ("field.delim" = "::");
CREATE TABLE t_rating(
UserID int, MovieID int, Rate int, Times int
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
WITH SERDEPROPERTIES ("field.delim" = "::");
然后把准备好的数据全部导入创建好的表:
load data local inpath '/Users/xxxa/Documents/software/hive-2.3.9/dat/users.dat' into table t_user;
load data local inpath '/Users/xxxa/Documents/software/hive-2.3.9/dat/ratings.dat' into table t_rating;
load data local inpath '/Users/xxxa/Documents/software/hive-2.3.9/dat/movies.dat' into table t_movie;
问题一:展示电影 ID 为 2116 这部电影各年龄段的平均影评分。
然后我们执行一下我们的sql
select a.age as age, avg(b.rate) as avgrate
from t_user a join t_rating b on a.userid=b.userid
where b.movieid=2116
group by a.age;
报了一个错
发现抛出类找不到的异常,解决办法:
将下面的配置语句,加在配置文件: hive/conf/hive-site.xml中,value中hive-contrib-*.jar的路径为你机器上实际的放置,在lib目录下寻找。
<property>
<name>hive.aux.jars.path</name>
<value>file:///home/develop/hive-2.3.9/lib/hive-contrib-2.3.9.jar</value>
<description>Added by tiger.zeng on 20120202.These JAR file are available to all users for all jobs</description>
</property>
再度运行结果显示了:
问题二:找出男性评分最高且评分次数超过 50 次的 10 部电影,展示电影名,平均影评分和评分次数。
SELECT
m.moviename,t.avgrate,t.total
FROM
t_movie m,
(
SELECT
r.movieid,
avg(r.rate) AS avgrate,
count(r.rate) AS total
FROM
t_rating r,
t_user u
WHERE
r.userid = u.userid
AND u.sex = 'M'
GROUP BY
r.movieid
HAVING
count(r.rate)>50) AS t
WHERE
m.movieid = t.movieid
ORDER BY
t.avgrate DESC
LIMIT 10;
问题三 找出影评次数最多的女士所给出最高分的 10 部电影的平均影评分,展示电影名和平均影评分(可使用多行 SQL)
分解一下这个问题,找出影评次数最多的女士所给出最高分的 10 部电影,然后再求出这10部影片的平均分
第一步 先求出这10部电影:
create table result as
select a.movieid,a.rate from t_rating a inner join
(select b.userid, count(a.movieid) as total
from t_rating a join t_user b on a.userid = b.userid
where b.sex = "F"
group by b.userid
order by total desc limit 1) t on a.userid = t.userid
order by a.rate desc limit 10;
第二步 求出这10部影片的平均分
select a.movieid, c.moviename, avg(a.rate) as avgrate
from t_rating a join result b on a.movieid = b.movieid
join t_movie c on c.movieid = a.movieid
group by a.movieid, c.moviename;
总结
hive的使用上有着多处短处:使用上强依赖hadoop组件,计算速度不尽人意-mapreduce的问题:如果使用复杂的指标和sql,可以看到程序需要map和reduce非常多的次数,导致整个计算的过程非常的耗时。但是也不能忽视他的优点:对数据分析人员非常友好,使用上完全无感知。支持纯sql,不需要学习java或者scala,维护,使用上也有着稳定可靠的优点。在部分计算指标报告的场景上,hive还是非常有竞争力和优势的。