赞
踩
什么是 Hive
Hive:由Facebook开源用于解决海量结构化日志的数据统计工具
Hive 是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能,用户只需要写HSQL,Hive将HQL转化成MapReduce程序。Hive利用HDFS存储数据,利用MapReduce查询分析数据。一句话,Hive的任务就是提供SQL语法解析编译功能,将HSQL编译成MR程序,然后剩下的就交给Hadoop了
具体来看,要记录的元数据信息包括:
1.表对应着哪个文件(位置信息)
2.表的列对应着文件哪一个字段(顺序信息)
3.文件字段之间的分隔符是什么
Hive 本质:Hive是一个数据仓库,适合用来做海量数据的离线分析
1.Hive处理的数据存储在HDFS
2.Hive分析数据底层的实现是MapReduce
3.执行程序运行在Yarn上
使用Hive处理数据的好处
1.操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)
2.避免直接写MapReduce,减少开发人员的学习成本
3.支持自定义函数,功能扩展很方便
4.背靠Hadoop,擅长存储分析海量数据集
元数据存储:元数据是描述数据的数据,通常是存储在关系数据库如mysql/derby中。Hive中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等,具体数据在HDFS
Driver驱动程序,包括语法解析器、计划编译器、优化器、执行器:完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS中,并在随后有执行引擎调用执行
执行引擎:Hive本身并不直接处理数据文件。而是通过执行引擎处理。当下Hive支持MapReduce、Tez、Spark3种执行引擎
1.执行查询:包括 CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为shell命令行;Hive中的Thrift服务器允许外部客户端通过网络与Hive进行交互,类似于JDBC或ODBC协议。WebGUI是通过浏览器访问Hive
2.获得计划:Driver根据查询编译器解析query语句,验证query语句的语法,查询计划或者查询条件
3.获取元数据:编译器将元数据请求发送给Metastore(管理元数据的服务),有了metastore后,多个客户端只需要连接metastore即可,不需要知道MySQL账号密码
生产环境一般使用远程模式部署metastore,即将服务单独部署在一个JVM中,这样其他依赖于Hive的软件都可以通过metastore访问元数据
4.接受元数据:Metastore将元数据作为响应发送给编译器
5.发送:编译器生成执行计划,Driver将执行计划发送到执行引擎
7.执行Job:hadoop内部执行的是mapreduce。在执行引擎发送任务的同时,对hive的元数据进行相应操作
8.得到执行结果:执行引擎接收数据节点(data node)的结果
9.返回结果:执行引擎发送这些合成值到Driver
10.返回最终结果:Driver将结果发送到hive接口
Hive中的数据可以在粒度级别上分为三类:
1.Table 表
2.Partition分区
3.Bucket 分桶
Hive表与关系数据库中的表相同。Hive中的表所对应的数据是存储在Hadoop的文件系统中,而表相关的元数据是存储在RDBMS中
如图,在HDFS,有数据库person,就对应一个目录,目录下有两张表,就对应两个目录,我们可以根据某一列进行分区,比如表student有一列数据who区分是小学生还是大学生,那么文件名就是分区列=分区值,来进行分区
分桶:Hash(分桶列) % 分桶个数,会生成很多小文件,一个文件对应一个桶
建立表是通过stored as指定,load命令是剪切命令,一个txt文件经过load并不会改变HDFS文件格式,即使建表的时候指定了文件格式为ORC等其他格式!所以想要将HDFS变成对应的文件类型,要用select + insert
TextFIle是Hive中默认的文件格式,存储形式为按行存储。工作中最常见的数据文件格式就是TextFile文件,几乎所有的原始数据生成都是TextFile格式。建表时不指定存储格式即为textfile,导入数据时把数据文件拷贝至hdfs不进行处理
SequenceFile是Hadoop里用来存储序列化的键值对的二进制的一种文件格式。SequenceFile文件也可以作为MapReduce作业的输入和输出。键(key)通常用于标识数据记录的唯一性或用于数据的排序。主要与 Hadoop MapReduce 配合使用。
Record针对行压缩,只压缩Value部分不压缩Key; Block是多条记录组成,对Key和Value都压缩
Parquet是一种支持嵌套结构的列式存储文件格式,通过数据编码和压缩,以及映射下推和谓词下推功能,Parquet的性能也较之其它文件格式有所提升。与 Hadoop 生态系统的多个组件,如 Spark、Hive、Impala 和 Presto 等,都有很好的集成。
关于行存储和列存储
ORC文件格式也是一种Hadoop生态圈中的列式存储格式,ORC文件是以二进制方式存储的,所以是不可以直接读取
一个ORC文件包含一个或多个stripes(groups of row data),每个stripe中包含了每个column的min/max值的索引数据
ORC索引
当查询中有大于等于小于的操作时,会根据min/max值,跳过扫描不包含的stripes
而其中为每个stripe建立的包含min/max值的索引,就称为Row Group Index行组索引,也叫min-max Index大小对比索引,或者Storage Index
为了使Row Group Index有效利用,向表中加载数据时,必须对需要使用索引的字段进行排序
set hive.optimize.index.filter=true;
--永久生效,请配置在hive-site.xml中
--创建表,并指定构建索引
create table tb_sogou_orc_index
stored as orc tblproperties ("orc.create.index"="true")
as select * from tb_sogou_source
distribute by stime
sort by stime;
--当进行范围或者等值查询(<,>,=)时就可以基于构建的索引进行查询
select count(*) from tb_sogou_orc_index where stime > '12:00:00' and stime < '18:00:00';
ORC布隆过滤器
建表时候,通过表参数”orc.bloom.filter.columns”=”columnName……”来指定为哪些字段建立BloomFilter索引,这样,在生成数据的时候,会在每个stripe中,为该字段建立BloomFilter的数据结构,当查询条件中包含对该字段的等值过滤时,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe
创建表,并指定构建索引
create table tb_sogou_orc_bloom
stored as orc tblproperties ("orc.create.index"="true",orc.bloom.filter.columns"="stime,userid")
as select * from tb_sogou_source
distribute by stime
sort by stime;
stime的范围过滤可以走row group index,userid的过滤可以走bloom filter index
select
count(*)
from tb_sogou_orc_index
where stime > '12:00:00' and stime < '18:00:00'
and userid = '3933365481995287' ;
ORC矢量化查询
Hive的默认查询执行引擎一次处理一行,而矢量化查询执行是一种Hive针对ORC文件操作的特性,目的是按照每批1024行读取数据,并且一次性对整个记录整合(而不是对单条记录)应用操作,提升了像过滤, 联合, 聚合等等操作的性能
注意:要使用矢量化查询执行,就必须以ORC格式存储数据
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;
Hive底层转换HQL运行MapReduce程序时,磁盘I/O操作、网络数据传输、shuffle和merge要花大量的时间,尤其是数据规模很大和工作负载密集的情况下,鉴于磁盘I/O和网络带宽是Hadoop的宝贵资源,数据压缩对于节省资源、最小化磁盘I/O和网络传输非常有帮助。如果磁盘I/O和网络带宽影响了MapReduce作业性能,在任意MapReduce阶段启用压缩都可以改善端到端处理时间并减少I/O和网络流量
压缩算法
临时配置MapReduce开启输出压缩及配置压缩类型
--开启输出压缩
set mapreduce.output.fileoutputformat.compress=true;
--配置压缩类型为Snappy
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
临时配置Hive开启中间结果压缩和输出压缩及配置压缩类型
-- 中间结果压缩
set hive.exec.compress.intermediate=true;
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
-- 输出结果压缩
set hive.exec.compress.output=true;
示例
创建表,指定为orc格式,并使用snappy压缩
create table tb_sogou_orc_snappy
stored as orc tblproperties ("orc.compress"="SNAPPY")
as select * from tb_sogou_source;
Hive作为一款复杂的数据仓库软件,除了一些默认的属性行为之外,还支持用户配置属性进行修改,使得在某些场景下满足用户的需求
作为用户我们需要掌握两件事:
一是:Hive有哪些属性支持修改,修改了有什么功能
二是:Hive支持哪种方式进行修改,修改是临时生效还是永久生效的
方式1:hive-site.xml配置文件
在$HIVE_HOME/conf路径下,可以添加一个hive-site.xml文件,把需要定义修改的配置属性添加进去,这个配置文件会影响到这个Hive安装包的任何一种服务启动、客户端使用方式,可以理解为是Hive的全局配置
比如我们指定使用MySQL作为Hive元数据的存储介质,那么就需要把Hive连接MySQL的相关属性配置在hive-site.xml文件中,这样不管是本地模式还是远程模式启动,不管客户端本地连接还是远程连接,都将访问同一个元数据存储介质,大家使用的元数据都是一致的
方式2:hiveconf命令行参数
hiveconf是一个命令行的参数,用于在使用Hive CLI或者Beeline CLI的时候指定配置参数。这种方式的配置在整个的会话session中有效,会话结束,失效。
比如在启动hive服务的时候,为了更好的查看启动详情,可以通过hiveconf参数修改日志级别:
$HIVE_HOME/bin/hive --hiveconf hive.root.logger=DEBUG,console
方式3:set命令
在Hive CLI或Beeline中使用set命令为set命令之后的所有SQL语句设置配置参数,这个也是会话级别的
这种方式也是用户日常开发中使用最多的一种配置参数方式 因为Hive倡导一种:谁需要、谁配置、谁使用的一种思想,避免你的属性修改影响其他用户的修改
#启用hive动态分区,需要在hive会话中设置两个参数:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
方式4:服务器特定的配置文件
您可以设置特定metastore的配置值hivemetastore-site.xml中,并在HiveServer2特定的配置值hiveserver2-site.xml中
Hive Metastore服务器读取$ HIVE_CONF_DIR或类路径中可用的hive-site.xml以及hivemetastore-site.xml配置文件
HiveServer2读取$ HIVE_CONF_DIR或类路径中可用的hive-site.xml以及hiveserver2-site.xml
如果HiveServer2以嵌入式模式使用元存储,则还将加载hivemetastore-site.xml
Hive的存储本质还是HDFS,HDFS是不利于小文件存储的,因为每个小文件会产生一条元数据信息,并且不利用MapReduce的处理,MapReduce中每个小文件会启动一个MapTask计算处理,导致资源的浪费,所以在使用Hive进行处理分析时,要尽量避免小文件的生成
Hive中提供了一个特殊的机制,可以自动的判断是否是小文件,如果是小文件可以自动将小文件进行合并
-- 如果hive的程序,只有maptask,将MapTask产生的所有小文件进行合并
set hive.merge.mapfiles=true;
-- 如果hive的程序,有Map和ReduceTask,将ReduceTask产生的所有小文件进行合并
set hive.merge.mapredfiles=true;
-- 每一个合并的文件的大小
set hive.merge.size.per.task=256000000;
-- 平均每个文件的大小,如果小于这个值就会进行合并
set hive.merge.smallfiles.avgsize=16000000;
如果遇到数据处理的输入是小文件的情况,怎么解决呢?
Hive中也提供一种输入类CombineHiveInputFormat,用于将小文件合并以后,再进行处理
-- 设置Hive中底层MapReduce读取数据的输入类:将所有文件合并为一个大文件作为输入
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
hadoop目录下/etc/hadoop/core.site.xml配置,分发到其他节点
<property>
<name>hadoop.proxyuser.gzhu.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.gzhu.groups</name>
<value>*</value>
</property>
前面我们提到,生产环境一般使用远程模式部署metastore,即将服务单独部署在一个JVM中,这样其他依赖于Hive的软件都可以通过metastore访问元数据
1.解压改名
tar zxvf apache-hive-3.1.2-bin.tar.gz
mv apache-hive-3.1.2-bin hive
2.添加mysql驱动到hive的lib目录下
3.目录/hive/conf/
mv hive-env.sh.template hive-env.sh
vim hive-env.sh
export HADOOP_HOME=/opt/module/hadoop-3.1.3
export HIVE_CONF_DIR=/opt/module/hive/conf
export HIVE_AUX_JARS_PATH=/opt/module/hive/lib
解决hadoop、hive之间guava版本差异
/hive目录下执行
rm -rf lib/guava-19.0.jar
cp /opt/module/hadoop-3.1.3/share/hadoop/common/lib/guava-27.0-jre.jar ./lib/
添加配置文件/conf/hive.site.xml
<configuration> <!-- 存储元数据mysql相关配置 --> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://ip:3306/hive?createDatabaseIfNotExist=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <!-- H2S运行绑定host --> <property> <name>hive.server2.thrift.port</name> <value>10000</value> </property> <property> <name>hive.server2.thrift.bind.host</name> <value>hadoop102</value> </property> <!-- 远程模式部署metastore 服务地址 --> <property> <name>hive.metastore.uris</name> <value>thrift://hadoop102:9083</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>zks123456</value> </property> <!-- 关闭元数据存储授权 --> <property> <name>hive.metastore.event.db.notification.api.auth</name> <value>false</value> </property> <!-- 关闭元数据存储版本的验证 --> <property> <name>hive.metastore.schema.verification</name> <value>false</value> </property> </configuration>
bin/schematool -initSchema -dbType mysql -verbos
当hive数据库生成72张表说明成功了
后台启动metastore
进程挂起 关闭使用jps + kill
输入命令回车执行 再次回车 进程将挂起后台
nohup /opt/module/hive/bin/hive --service metastore &
如今,官方推荐我们使用Hive的第二代客户端Beeline通过HiveServer2访问metastore
hive经过发展,推出了第二代客户端beeline,但是beeline客户端不是直接访问metastore服务的,而是需要单独启动hiveserver2服务
在hive运行的服务器上,首先启动metastore服务,然后启动hiveserver2服务
启动metastore服务
nohup /opt/module/hive/bin/hive --service metastore &
启动hiveserver2服务
nohup /opt/module/hive/bin/hive --service hiveserver2 &
另外一台机器上,启动beeline
bin/beeline
beeline> ! connect jdbc:hive2://hadoop102:10000
输入用户名gzhu和密码,即可使用
Hive是一个数据仓库,会有数据库、表的概念,这个我们前面也提到过
创建数据库
0: jdbc:hive2://hadoop102:10000> create database gzhu;
切换数据库
use gzhu;
查看数据库的表
show tables;
我们知道,实际的结构化文件时存储在HDFS上的,存在哪里呢,一般存在对应表的路径下。Hive表默认存储路径是由${HIVE_HOME}/conf/hive-site.xml配置文件的hive.metastore.warehouse.dir属性指定。默认值是:/user/hive/warehouse(建立的数据库的路径就在该文件下)。当然我们在建立表的时候可以通过LOCATION hdfs_path来指定使用哪个结构化文件(但这样会导致表的路径不在数据库路径下)
我们先根据结构化文件创建好表,再将文件放到该目录下
Hive就可以自动识别都数据了
创建表
,①要指定分隔符②数据类型要正确指定
create table t_person(id int,name varchar(255),age int) row format delimited
fields terminated by ',';
然后将文件放到对应路径下
查询
select * from t_person;
IDEA测试Hive
导入依赖
<dependencies> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-jdbc</artifactId> <version>3.1.2</version> <exclusions> <exclusion> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> </exclusion> <exclusion> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-runner</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>3.1.2</version> </dependency> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>3.1.2</version> </dependency> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> </dependency> </dependencies>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。