目录标题
Hive的简介
hive可以理解为一个将SQL转换为MapReduce的任务的工具,甚至更进一步可以说hive就是一个MapReduce的客户端
为什么用Hive
- 采用类SQL语法去操作数据,提供快速开发的能力。
- 避免了去写MapReduce,减少开发人员的学习成本。
- 功能扩展很方便。
Hive的分层架构
Hive利HDFS存储数据,利用MapReduce查询分析数据
Hive的安装
这里我们选用的是:Hive2.1.1
hive2.1.1下载地址
1.上传并解压安装包
将我们的hive的安装包上传到第三台服务器的/export/softwares路径下,然后进行解压
cd /export/softwares/
tar -zxvf apache-hive-2.1.1-bin.tar.gz -C ../servers/
2.安装mysql
Hive的元数据信息:记录表和文件之间的对应关系,和记录表字段和文件字段之间的关系,本来这些元数据信息是要存到Hive自带的derby数据库中的,但是derby是有很大的缺陷,所以我们在生产环境中放弃使用derby数据库,改为mysql数据库
3.修改Hive的配置文件
这里我们使用Notepad++连接hadoop连接方式参考:
Notepad++连接hadoop
修改hive-env.sh
cd /export/servers/apache-hive-2.1.1-bin/conf
cp hive-env.sh.template hive-env.sh
红色框框部分内容改为此内容:
HADOOP_HOME=/export/servers/hadoop-2.7.5
export HIVE_CONF_DIR=/export/servers/apache-hive-2.1.1-bin/conf
修改hive-site.xml
创建一个hive-site.xml,把以下内容添加到文件内,通过拷贝粘贴,到conf路径下
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<!--指定数据库连接的用户名称-->
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<!--指定数据库连接的密码-->
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
<property>
<!--指定hive库的路径,和如果hive库不存在的情况下进行创建-->
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node03:3306/hive?createDatabaseIfNotExist=true&useSSL=false</value>
</property>
<property>
<!--指定数据库连接的驱动-->
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<!--指定元数据是否要进行校验-->
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
<property>
<!--是否要自动创建一些核心的文件-->
<name>datanucleus.schema.autoCreateAll</name>
<value>true</value>
</property>
<property>
<!--hive服务器绑定主机-->
<name>hive.server2.thrift.bind.host</name>
<value>node03</value>
</property>
</configuration>
4.添加mysql的驱动包到Hive的lib目录下
hive使用mysql作为元数据存储,必然需要连接mysql数据库,所以我们添加一个mysql的连接驱动包到hive的安装目录下,然后就可以准备启动hive了
将我们准备好的mysql-connector-java-5.1.38.jar 这个jar包直接上传到
/export/servers/apache-hive-2.1.1-bin/lib 这个目录下即可
至此,hive的安装部署已经完成,接下来我们来看下hive的三种交互方式
5.配置Hive环境变量
node02服务器执行以下命令配置hive的环境变量
vim /etc/profile
export HIVE_HOME=/export/servers/apache-hive-2.1.1-bin
export PATH=:$HIVE_HOME/bin:$PATH
别忘记让修改生效
source /etc/profile
Hive交互
1.bin/hive交互方式
cd /export/servers/apache-hive-2.1.1-bin/
bin/hive
创建一个数据库,创建一个表,这些hive操作就会在mysql数据库中产生一条hive的元数据信息
create database if not exists mytest
use mytest
create table t_test(id int,name string)
通过sql脚本进行操作
cd /exprot/servers
vim hive.sql
脚本内容
create database if not exists mytest;
use mytest;
create table stu(id int,name string);
通过hive -f 来执行我们的sql脚本,但是我们需要先进入我们的hive安装目录
cd /export/servers/apache-hive-2.1.1-bin/
bin/hive -f /export/servers/hive.sql
hive的基本操作
1.数据库操作
(1)创建数据库
create database if not exists myhive;
use myhive;
hive的数据库和数据表都是以目录形式存在的
(2)创建数据库并制定位置
create database myhive2 location "/myhive2";
(3)设置数据库键值对信息
键值对信息是帮助我们来描述此数据库的基本情况和内容,方便我们快速查找所数据库
create database my_yuge with dbproperties("owner"="itcast","data"="20190508")
查看数据库的键值对信息
describe database extend my_yuge;
修改数据库键值对信息
alter database my_yuge set dbproperties("owner"="zhangge")
(4)查看数据库更多详细信息
desc database extended my_yuge;
(5)删除数据库
删除一个空数据库,如果数据库下面有数据表,那么就会报错
drop database my_yuge;
强制删除数据库,包含数据库下面的表一起删除
drop database my_yuge cascade;
2.数据表操作
(1)创建表
create [external] table [if not exists] table_name (
col_name data_type [comment '字段描述信息']
col_name data_type [comment '字段描述信息'])
[comment '表的描述信息'] //表示注释.默认不能使用中文
[partitioned by (col_name data_type,...)] //将表数据分为不同的文件夹目录存储
[clustered by (col_name,col_name,...)] //分桶类似于MR的分区
[sorted by (col_name [asc|desc],...) into num_buckets buckets] //排序,还可以指定排序规则
[row format row_format] //指定文件中的字段分隔符
[storted as ....] //指定hive表的数据存储类型
[location '指定表的路径'] //指定hive表文件的存储路径
说明:
关键字+[中括号]:表示可以写也可以不写
- create table
创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常。 - external
可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。 - comment
表示注释,默认不能使用中文 - partitioned by
表示使用表分区,一个表可以拥有一个或者多个分区,每一个分区单独存在一个目录下 . - clustered by
对于每一个表分文件, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。 - sorted by
指定排序字段和排序规则 - row format
指定表文件字段分隔符 - storted as指定表文件的存储格式, 常用格式:SEQUENCEFILE, TEXTFILE, RCFILE,如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 storted as SEQUENCEFILE(二进制文件)。
- location
指定表文件的存储路径(hdfs路径)
(2)内部表的操作
- 建表入门
use myhive;
create table stu(id int,name string);
insert into stu values (1,"zhangsan"); #插入数据
select * from stu;
(3)外部表的操作
-
外部表说明
外部表因为是指定其他的hdfs路径的数据加载到表当中来,所以hive表会认为自己不完全独占这份数据,所以删除hive表的时候,数据仍然存放在hdfs当中,不会删掉. -
内部表和外部表的使用场景
每天将收集到的网站日志定期流入HDFS文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表。
1.操作案例
分别创建老师与学生表外部表,并向表中加载数据
- 创建老师表
create external table teacher(t_id string,t_name string)row format delimited fields terminated by "\t";
- 1.创建学生表
create external table student(t_id string,t_name string,s_birth string,s_sex string)row format delimited fields terminated by "\t";
row format delimited fields terminated by “\t"设置表字段的分隔符号为”\t",默认是-001
2.通过上传到指定文件夹加载数据
- 2.1创建一个teacher.txt文件把以下内容放入文件中
vim teacher.txt
1 zhangsan
2 wangwu
3 lisi
- 2.2把teacher.txt上传至hdfs操作系统下外部表目录下
hdfs dfs -put teacher.txt /user/hive/warehouse/myhive.db/teacher
3.通过本地操作系统加载数据
- 3.1上传数据文件到相应目录
cd /export/servers
mkdir hivedatas
cd hivedatas
通过xshell的xftp上传student.csv文件到hivedatas中
- 3.2通过hive的命令实现本地上传到外部表中
load data local inpath "/export/servers/hivedatas/student.csv" into table student;
- 加载并覆盖已有数据
load data local inpath "/export/servers/hivedatas/student.csv" overwrite into table student;
4.通过hdfs加载数据
cd /export/servers/hivedatas
hdfs dfs -mkdir -p /hivedatas
hdfs dfs -put techer.csv /hivedatas/
load data inpath "/hivedatas/teacher.csv" into table teacher;
(4)分区表操作
分区表实际上就是把一个大的hive表数据分成一些小文件,然后存储在不同文件夹中
1.创建分区表语法
create table score(s_id string,c_id string, s_score int) partitioned by (month string) row format delimited fields terminated by '\t';
分区的核心是关键字partitioned by 后面跟上分区字段(month string)
2.创建一个表带多个分区
create table score2 (s_id string,c_id string, s_score int) partitioned by (year string,month string,day string) row format delimited fields terminated by '\t';
3.加载数据到分区表中
load data local inpath '/export/servers/hivedatas/score.csv' into table score partition (month='20180101');
4.加载数据到多分区表
load data local inpath '/export/servers/hivedatas/score.csv' into table score2 partition(year='2018',month='06',day='01');
5.指定某个分区来查询
select * from score where month="20180102";
6.查询多个分区
lect * from score where month = '20180101' union all select * from score where month = '20180102';
7.查看分区
show partitions score;
8.添加一个分区
alter table score add partition(month='201805');
9.删除分区
alter table score drop partition(month = '201806');
(5)分桶表操作
分桶,就是将数据按照指定的字段进行划分到多个文件当中去,分桶就是MapReduce中的分区.
开启Hive的分桶功能
set hive.enforce.bucketing=true;
设置Reduce个数
set mapreduce.job.reduces=3;
创建分桶表
create table course (c_id string,c_name string,t_id string) clustered by(c_id) into 3 buckets row format delimited fields terminated by '\t';
clustered by分桶的关键字,into 3 buckets表示将我们的数据分到三个桶里面
(6)桶表的数据加载
创建普通表,这个表类似中间表,而且他的字段要和分桶表的字段一一对应起来
create table course_common (c_id string,c_name string,t_id string) row format delimited fields terminated by '\t';
向中间表中加载数据
load data local inpath '/export/servers/hivedatas/course.csv' into table course_common;
通过insert overwrite把中间表中数据加载到桶表中
insert overwrite table course select * from course_common cluster by(c_id);
这里要注意才创建分桶的时候是clustered,而在这里是不需要加ed
(7)修改表结构
1.重命名
alter table old_table_name rname to new_table_name;
把表score4修改成score5
alter table score4 rename to score5;
2.增加修改列信息
- 查询表结构
desc score5
- 添加列
alter table score5 add columns(mycol string,mysco int);
- 更新列alter
alter table score5 change column mysco mysconew int;
- 删除表
drop table score5;
3.Hive查询语法
1.SELECT
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list [HAVING condition]] //分组
[CLUSTER BY col_list //排序
| [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list] //分区 排序 排序
]
[LIMIT number]
- order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间,因为所有的数据都堆在一个Reduce上。
- sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全局有序。
- distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列。
- cluster by(字段) 除了具有distribute by的功能外,还会对该字段进行排序.
因此,如果distribute 和sort字段是同一个时,此时,cluster by = distribute by + sort by
2.查询语法
(1)全表查询
select * from score
(2)选择特定列
select s_id,c_id from score;
(3)列别名
1)重命名一个列。
2)便于计算。
3)紧跟列名,也可以在列名和别名之间加入关键字‘AS’
select s_id as myid ,c_id from score;
(4)常用函数
- 求总行数
select count(1) from score;
- 求分数的最大值
select max(s_score) from score;
- 求分数的最小值
select min(s_score) from score;
- 求分数的总和
select sum(s_score) from score;
- 求分数的平均值
select avg(s_score) from score;
(5)LIMIT语句
LIMIT子句用于限制返回的行数。
select * from sscore limit 3;
(6)WHERE语句
- 使用WHERE 子句,将不满足条件的行过滤掉。
- WHERE 子句紧随 FROM 子句。
select * from score where s_score >60;
- 查询分数在80到100的所有数据
select * from score where s_score between 80 and 100;
- 查询成绩为空的所有数据
select * from score where s_score is null;
- 查询成绩是80和90的数据
select * from score where s_score in(80,90);
(7)LIKE和RLIKE
- 使用LIKE运算选择类似的值
- 选择条件可以包含字符或数字:
% 代表零个或多个字符(任意个字符)。
_ 代表一个字符。
查找以8开头的所有成绩
select * from score where s_score like '8%';
查找第二个数值为9的所有成绩数据
select * from score where s_score like '_9%';
- RLIKE子句是Hive中这个功能的一个扩展,其可以通过Java的正则表达式这个更强大的语言来指定匹配条件。
查找s_id中含1的数据
select * from score where s_id rlike '[1]';
(8)分组
GROUP BY语句
- 计算每个学生的平均分数
select s_id,avg(s_score) from score group by s_id;
- 计算每个学生最高成绩
select s_id,max(s_score) from score group by s_id;
HIVING语句
having与where不同点
- where针对表中的列发挥作用,查询数据;having针对查询结果中的列发挥作用,筛选数据。
- where后面不能写分组函数,而having后面可以使用分组函数。
- having只用于group by分组统计语句。
求每个学生平均分数大于85的人
select s_id,avg(s_score) as avgscore from score group by s_id having avgscore>85;
(9)JOIN语句
Hive支持通常的SQL JOIN语句,但是只支持等值连接,不支持非等值连接。
案例操作: 查询分数对应的姓名
select s.s_id,s.s_score,stu.s_name,stu.s_birth from score s join student stu on s.s_id = stu.s_id;
on s.s_id = stu.s_id叫连表条件,只有符合了这个相等的字段,我们才进行连接
(10)内连接
内连接:只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来,也就是说求两种表的交集
select * from teacher t inner join course c on t.t_id = c.t_id
(11)左外连接
左表为主,优先输出,如果右表有匹配数据的化输出,没有匹配的化右表会补一个null
select * from teacher t left join course c on t.t_id = c.t_id;
(12)右外连接
与左外连接刚好相反
(13)多表连接
注意:连接 n个表,至少需要n-1个连接条件。例如:连接三个表,至少需要两个连接条件。
多表连接查询,查询老师对应的课程,以及对应的分数,对应的学生
select * from teacher t
left join course c
on t.t_id = c.t_id
left join score s
on s.c_id = c.c_id
left join student stu
on s.s_id = stu.s_id;
(14)排序
Order By:全局排序,只能有一个reduce
- 使用 ORDER BY 子句排序
ASC(ascend): 升序(默认)
DESC(descend): 降序 - ORDER BY 子句在SELECT语句的结尾。
查询学生的成绩,并按照分数降序排列
select * from student s left join score sco on s.s_id = sco.s_id order by sco.s_score desc
多个列排序
select s_id,avg(s_score) avg from score group by s_id order by s_id,avg;
Sort By局部排序:可以对每个MapReduce内部进行排序
设置reduce个数
set mapreduce.job.reduces=3
查询成绩按照成绩升序排列
select * from score sort by s_score;
将查询结果导入到文件中
insert overwrite local directory '/export/servers/hivedatas/sort' select * from score sort by s_score;
(15)分区排序
Distribute By:类似MR中partition,进行分区,结合sort by使用。
注意,Hive要求distribute by语句要写在sort by语句之前。
对于distribute by进行测试,一定要分配多reduce进行处理,否则无法看到distribute by的效果。
案例实操:先按照学生id进行分区,再按照学生成绩进行排序。
- 设置reduce的个数,将我们对应的s_id划分到对应的reduce当中去
set mapreduce.job.reduces=7;
- 通过distribute by 进行数据的分区
insert overwrite local directory '/export/servers/hivedatas/sort' select * from score distribute by s_id sort by s_score;
CLUSTER BY
当distribute by和sort by字段相同时,可以使用cluster by方式。
cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是倒序排序,不能指定排序规则为ASC或者DESC。
以下两种写法等价
select * from score cluster by s_id;
select * from score distribute by s_id sort by s_id;
3.Hive Shell参数
(1)Hive命令行
bin/hive [-hiveconf ] [-i ] [-f|-e] [-S]
1、 -i 从文件初始化HQL。
2、 -e从命令行执行指定的HQL
3、 -f 执行HQL脚本
4、 -v 输出执行的HQL语句到控制台
5、 -p 指定服务器端口号
6、 -hiveconf 设置hive运行时候的参数配置
(2)Hive参数配置方式
开发Hive应用时,不可避免地需要设定Hive的参数。设定Hive的参数可以调优HQL代码的执行效率,或帮助定位问题。
对于一般参数,有以下三种设定方式:
- 配置文件
- 命令行参数
- 参数声明
- 配置文件:Hive的配置文件包括
- 用户自定义配置文件:安装目录下 /hive-site.xml
- 默认配置文件: 安装目录下 /hive-default.xml
用户自定义配置会覆盖默认配置。
另外,Hive也会读入Hadoop的配置,因为Hive是作为Hadoop的客户端启动的,Hive的配置会覆盖Hadoop的配置。
配置文件的设定对本机启动的所有Hive进程都有效。
- 命令行参数:启动Hive(客户端或Server方式)时,可以在命令行添加-hiveconf param=value来设定参数,例如:
bin/hive -hiveconf hive.root.logger=INFO,console
hive设置日志打印级别,我要点INFO级别的信息,同时打印到console控制台
- 参数声明:可以在HQL中使用SET关键字设定参数,例如:
set mapred.reduce.tasks=100;
- 优先级:
参数声明 > 命令行参数 > 配置文件参数(hive)
4.Hive函数
(1)自定义函数
- Hive 自带了一些函数,比如:max/min等,当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF).
- 根据用户自定义函数类别分为以下三种:
- UDF(User-Defined-Function)
- 一进一出
- UDAF(User-Defined Aggregation Function)
- 聚集函数,多进一出
- 类似于:count/max/min
- UDTF(User-Defined Table-Generating Functions)
- 一进多出
- 如 lateral view explore()
- UDF(User-Defined-Function)
- 编程步骤:
- 继承org.apache.hadoop.hive.ql.UDF
- 需要实现evaluate函数;evaluate函数支持重载;
- 注意事项
- UDF必须要有返回类型,可以返回null,但是返回类型不能为void;
- UDF中常用Text/LongWritable等类型,不推荐使用java类型;
(2)UDF开发案例
- 创建Maven配置
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
- 开发java类集成UDF
我们自定义一个函数,可以实现hive的upper函数字符串小写字母转成大写字母,但是我们不全部转大写,而是就首字母大写,其余不变
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class Captial_Udf extends UDF {
//模拟hive的upper方法:将字符串的第一个字符转为大写,其他字符不变
public Text evaluate(final Text line){
//首先做一个条件判断,如果是null或者是空,直接返回空串
if (line.toString() != null && !line.toString().equals("")){
String substring = line.toString().substring(0, 1).toUpperCase()+line.toString().substring(1);
return new Text(substring);
}
return new Text("");
}
}
(3)打包上传,添加使用自定义函数
- 把上面写的自定义函数使用maven的打包工具打包
- 将打好的jar包上传至hive目录下lib下
- 添加jar包
重命名我们的jar包
cd /export/servers/apache-hive-2.7.5-bin/lib
mv test01-1.0-SNAPSHOT.jar my_upper.jar
hive的客户端添加我们的jar包
add jar /export/servers/apache-hive-2.1.1-bin/lib/my_upper.jar;
- 设置函数与我们的自定义函数关联
create temporary function my_upper as "itcast.Captial_Udf";
as后面是类的全路径类名
- 使用自定义函数
select my_upper("hello")
4.hive的数据压缩(Snappy压缩)
(1)查看hadoop支持的压缩方式
cd /export/servers/hadoop-2.7.5
bin/hadoop checknative
(2)开启Map输出阶段压缩
开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量。具体配置如下:
- 开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;
- 开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;
- 设置mapreduce中map输出数据的压缩方式
set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;
- 执行查询语句
select count(1) from score; //统计score表中有多少行数据
(3)Reduce输出阶段压缩
- 开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;
- 开启mapreduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;
- 设置mapreduce最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
- 设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
- 测试一下输出结果是否是压缩文件
insert overwrite local directory '/export/servers/snappy' select * from score distribute by s_id sort by s_id desc;
5.hive数据存储格式
Hive支持的存储数的格式主要有:TEXTFILE(行式存储) 、SEQUENCEFILE(行式存储)、ORC(列式存储)、PARQUET(列式存储)。
存储格式 | 优劣 |
---|---|
行式存储 | 1.行查询效率高 2.列查询效率低 3.数据压缩效率低 |
列式存储 | 1.行查询效率低 2.列查询效率高 3.数据压缩效率高 |
(1)TEXTFILE
1.创建表,存储数据格式为TEXTFILE
create table log_text (
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE ;
- 向表中加载数据
load data local inpath '/export/servers/hivedatas/log.data' into table log_text ;
- 查看表中数据大小
dfs -du -h /user/hive/warehouse/myhive.db/log_text;
原文件数据大小与textfile格式下文件大小是一致的,是因为textfile这种格式并不会对我们的数据进行压缩
(2)ORC
- 创建表,存储数据格式为ORC
create table log_orc(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc ;
- 向表中加载数据
insert into table log_orc select * from log_text ;
- 查看表中数据大小
dfs -du -h /user/hive/warehouse/myhive.db/log_orc;
2.8M说明ORC数据格式对我们的文件进行了压缩,而且压缩的相当厉害
(3)parquet
- 创建表,存储数据格式为parquet
create table log_parquet(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS PARQUET ;
- 向表中加载数据
insert into table log_parquet select * from log_text ;
- 查看表中数据大小
dfs -du -h /user/hive/warehouse/myhive.db/log_parquet;
存储文件的压缩比总结:
ORC > Parquet > textFile
ORC存储 指定压缩方式
ORC存储配置表
(1)创建一个SNAPPY压缩的ORC存储方式
- 建表
create table log_orc_snappy(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc tblproperties ("orc.compress"="SNAPPY");
- 插入数据
insert into table log_orc_snappy select * from log_text ;
- 查看插入后数据大小
dfs -du -h /user/hive/warehouse/myhive.db/log_orc_snappy ;
(2)存储方式和压缩总结:
在实际的项目开发当中,hive表的数据存储格式一般选择:orc或parquet(都是列式存储)。压缩方式一般选择snappy。
Hive调优
1.Fetch抓取
Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM score;在这种情况下,Hive可以简单地读取score对应的存储目录下的文件,然后输出查询结果到控制台。通过设置hive.fetch.task.conversion参数,可以控制查询语句是否走MapReduce.
- 把hive.fetch.task.conversion设置成none,然后执行查询语句,都会执行mapreduce程序。
set hive.fetch.task.conversion=none;
select * from score;
select s_score from score;
select s_score from score limit 3;
- 把hive.fetch.task.conversion设置成more,然后执行查询语句,如下查询方式都不会执行mapreduce程序。
set hive.fetch.task.conversion=more;
select * from score;
select s_score from score;
select s_score from score limit 3;
- 适用场景:
在查询数据量不是很大的表文件的时候,就可以使用Fetch抓取
2.本地模式(单机运行)
大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,有时Hive的输入数据量是非常小的。在这种情况下,为查询触发执行任务时消耗可能会比实际job的执行时间要多的多。对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。
用户可以通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候会自动开启这个优化。
开启本地模式,并执行查询语句
set hive.exec.mode.local.auto=true;
select * from score cluster by s_id;
3.MapJoin
11.推测执行
在分布式集群环境下,因为程序Bug(包括Hadoop本身的bug),负载不均衡或者资源分布不均等原因,会造成同一个作业的多个任务之间运行速度不一致,有些任务的运行速度可能明显慢于其他任务(比如一个作业的某个任务进度只有50%,而其他所有任务已经运行完毕),则这些任务会拖慢作业的整体执行进度。为了避免这种情况发生,Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。
设置开启推测执行参数:
set mapred.map.tasks.speculative.execution=true
set mapred.reduce.tasks.speculative.execution=true
set hive.mapred.reduce.tasks.speculative.execution=true;
关于调优这些推测执行变量,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大大。