一:Hive简介

Hive是构建在hadoop上的数据仓库,可以把结构化的数据文件映射成表,并提供SQL查询功能,用于查询的SQL语句会被转成MapReduce 任务提交到hadoop上运行。

Hive出现的原因? 

面对海量数据的分析hadoop是个好东西,但是学习成本比较高,难度大,需要使用人员得会编程,相比编程,SQL的学习成本较低,简单,易上手,于是hive就出现了。

优点:

  1. 简单,易上手,使得会SQL但不懂编程的人员可以对海量数据进行分析。
  2. 统一的元数据管理,可与 sparkSQL/impala等共享数据。
  3. 灵活性高,可以自定义用户函数(UDF)和存储格式。

缺点:

  1. 延迟性高,不适合做数据的实时处理,但适合做海量数据的离线处理。

数据库与数据仓库的区别?

功能

数据库

数据仓库

应用场景

维持业务正常运转的操作类的数据

面向分析,支持侧重决策分析

数据范围

当前状态数据

存储历史、完整、反应历史变化的数据

数据变化

支持频繁的增删改查操作

可增加,查询,无删除更新操作

处理数据量

频繁、小批次、高并发、低延迟

非频繁、大批量、高吞吐、有延迟

设计理论

遵循数据库三范式,避免冗余

违范式,适当冗余

建模方式

范式建模

范式建模+维度建模

 

二:Hive架构

了解一个技术的架构,首先从角色入手,架构中有哪些角色以及每个角色的功能

Hive自学学习路线 hive难吗_Hive自学学习路线

 

用户访问接口

Cli (Command Line Interface):用户可以使用Hive自带的命令行接口执行Hive QL、设置参数等功能

JDBC/ODBC :用户可以使用基于Thrift协议的JDBC或者ODBC的方式在代码中操作Hive

Web GUI:浏览器接口,用户可以在浏览器中对Hive进行操作(2.2之后淘汰)

MetaStore

Hive 中的元数据通常包括:表的名字,表的列和分区及其属性,表的属性(内部表和 外部表),表的数据所在目录

Metastore 默认存在自带的 Derby 数据库中。Derby是一个内存数据库,不能持久化,不适合多用户操作,并且数据存储目录不固定。数据库跟着 Hive 走,极度不方便管理

在实际的生产环境中一般使用MySQL代替Derby

Driver

Hive Driver是Hive的核心,包括解析器、编译器、执行器、优化器,完成从SQL语句到MapReduce任务的解析优化执行过程

HDFS

Hive的数据存储在Hdfs上

三:Hive的搭建模式

(1)使用默认的Derby数据库

(2)使用远程数据库

(3)使用远程服务器模式,在服务器端启动MetaStoreServer,客户端使用Thrift协议通过MetaStoreServer访问数据库,实现了hive与MetaStore的解耦,另外把元数据抽象成一个服务,spark-sql 也可以使用

四:HQL的执行过程

语法解析:Antlr定义SQL的语法规则,完成SQL的词法,语法解析,将SQL转化为抽象语法树AST Tree

语义解析:遍历AST Tree,抽象出查询的基本组成单元QueryBlock

生成逻辑执行计划:遍历 QueryBlock,翻译为执行操作树 OperatorTree

优化逻辑执行计划:逻辑层优化器进行 OperatorTree 变换,合并不必要的 ReduceSinkOperator,减少 shuffle 数据量。

生成物理执行计划:遍历 OperatorTree,翻译为 MapReduce 任务

优化物理执行计划:物理层优化器进行 MapReduce 任务的变换,生成最终的执行计划

五:Hive的执行过程

 

Hive自学学习路线 hive难吗_数据_02

Hive自学学习路线 hive难吗_hive_03

(1)执行查询

  用户通过Hive访问接口将查询发送给Driver

(2)获取计划

  Driver借助查询编译器解析SQL,检查语法和查询需求

(3)获取元数据

  编译器将获取元数据请求发送给MetaStore

(4)发送元数据

  MetaStore将元数据作为对编译器的响应发送出去

(5)发送计划

  编译器检查需求并将计划重新发送给Driver,到目前为止,查询的解析和编译已经完成

(6)执行计划

  Driver将执行计划发送给执行引擎

(7)执行结果

  在内部,执行任务的过程是MapReduce Job。执行引擎将Job发送到ResourceManager(在这里注意,执行器在执行方案时,会判断:如果当前方案不涉及到MR组件,比如为表添加分区信息、比如字符串操作等,比如简单的查询操作等,此时就会直接和元数据库交互,然后去HDFS上去找具体数据。如果方案需要转化成MR job),ResourceManager位于NameNode节点中,并将job分配给DataNode中的NodeManager。在这里,查询执行MapReduce任务。在执行的同时,执行引擎可以使用Metastore执行元数据操作。

(8)获取结果

  执行引擎从DataNode获取结果集

(9)发送结果给Driver

  执行引擎将结果发送给Driver

(10)发送结果给用户

  Driver将结果发送到Hive接口

六:Hive的压缩和存储

1. Hadoop压缩配置

(1)MR支持的压缩编码

压缩格式

算法

文件扩展名

是否切片

换成压缩格式后,原来的程序是否需要修改

DEFLATE

DEFLATE

.deflate


和文本处理一样,不需要修改

GZIP

DEFLATE

.gz


和文本处理一样,不需要修改

BZIP2

BZIP2

.bz2


和文本处理一样,不需要修改

LZO

LZO

.lzo


需要建索引,还需要指定输入格式

SNAPPY

SNAPPY

.snappy


和文本处理一样,不需要修改

 为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器,如下表所示

压缩格式

对应的编码/解释器

DEFLATE

org.apache.hadoop.io.compress.DefaultCodec

GZIP

org.apache.hadoop.io.compress.GzipCodec

BZIP2

org.apache.hadoop.io.compress.BZip2Codec

LZO

com.hadoop.compression.lzo.LzopCodec

SNAPPY

org.apache.hadoop.io.compress.SnappyCodec

(2)压缩配置参数

要在Hadoop中启用压缩,可以配置如下参数(mapred-site.xml文件中):

参数

默认值

阶段

建议

io.compression.codecs (在core-site.xml中配置)

org.apache.hadoop.io.compress.DefaultCodec,

org.apache.hadoop.io.compress.GzipCodec, 

org.apache.hadoop.io.compress.BZip2Codec,

org.apache.hadoop.io.compress.Lz4Codec

输入压缩

Hadoop使用文件扩展名判断是否支持某种编解码器

mapreduce.map.output.compress

false

mapper输出

这个参数设为true启用压缩

mapreduce.map.output.compress.codec

org.apache.hadoop.io.compress.DefaultCodec

mapper输出

使用LZO、LZ4或snappy编解码器在此阶段压缩数据

mapreduce.output.fileoutputformat.compress

false

reducer输出

这个参数设为true启用压缩

mapreduce.output.fileoutputformat.compress.codec

org.apache.hadoop.io.compress. DefaultCodec

reducer输出

使用标准工具或者编解码器,如gzip和bzip2

mapreduce.output.fileoutputformat.compress.type

RECORD

reducer输出

SequenceFile输出使用的压缩类型:NONE和BLOCK

(3)开启Map输出阶段压缩

开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量。具体配置如下:

--1)开启hive中间传输数据压缩功能
    hive (default)>set hive.exec.compress.intermediate=true;
--2)开启mapreduce中map输出压缩功能
    hive (default)>set mapreduce.map.output.compress=true;
--3)设置mapreduce中map输出数据的压缩方式
    hive (default)>set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;

--4)执行查询语句
hive (default)> select count(*) from aaaa;

(4)开启Reduce输出阶段压缩

当Hive将输出写入到表中时,输出内容同样可以进行压缩。属性hive.exec.compress.output控制着这个功能。用户可能需要保持默认设置文件中的默认值false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。

--1)开启hive最终输出数据压缩功能
    hive (default)>set hive.exec.compress.output=true;
--2)开启mapreduce最终输出数据压缩
    hive (default)>set mapreduce.output.fileoutputformat.compress=true;
--3)设置mapreduce最终数据输出压缩方式
    hive (default)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
--4)设置mapreduce最终数据输出压缩为块压缩
    hive (default)> set mapreduce.output.fileoutputformat.compress.type=BLOCK;
--5)测试一下输出结果是否是压缩文件
    hive (default)> insert overwrite local directory '/root/data' select * from aaaa;

 2. 文件存储格式

格式

说明

TEXTFILE

存储为纯文本文件,默认存储格式。不做压缩,磁盘开销大,数据解析开销大

SEQUENCEFILE

SequenceFile 是 Hadoop API 提供的一种二进制文件,它将数据以<key,value>的形式序列化到文件中。这种二进制文件内部使用 Hadoop 的标准的 Writable 接口实现序列化和反序列化。它与 Hadoop API 中的 MapFile 是互相兼容的。Hive 中的 SequenceFile 继承自 Hadoop API 的 SequenceFile,不过它的 key 为空,使用 value 存放实际的值,这样是为了避免 MR 在运行 map 阶段进行额外的排序操作。

RCFILE

RCFile 文件格式是 FaceBook 开源的一种 Hive 的文件存储格式,首先将表分为几个行组,对每个行组内的数据按列存储,每一列的数据都是分开存储。

ORC FILES

ORC 是在一定程度上扩展了 RCFile,是对 RCFile 的优化。

AVRO FILES

Avro 是一个数据序列化系统,设计用于支持大批量数据交换的应用。它的主要特点有:支持二进制序列化方式,可以便捷,快速地处理大量数据;动态语言友好,Avro 提供的机制使动态语言可以方便地处理 Avro 数据。

PARQUET

Parquet 是基于 Dremel 的数据模型和算法实现的,面向分析型业务的列式存储格式。它通过按列进行高效压缩和特殊的编码技术,从而在降低存储空间的同时提高了 IO 效率。

  

行存储的特点: 查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。

列存储的特点: 因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

TEXTFILE和SEQUENCEFILE的存储格式都是基于行存储的;

ORC和PARQUET是基于列式存储的。

主流文件存储格式对比实验

--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 ;
--(2)向表中加载数据
    hive (default)> load data local inpath '/root/log' into table log_text ;
--(3)查看表中数据大小
    dfs -du -h /user/hive/warehouse/log_text;
    18.1 M  /user/hive/warehouse/log_text/log.data
--2)ORC
--(1)创建表,存储数据格式为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 ;
--(2)向表中加载数据
    insert into table log_orc select * from log_text ;
--(3)查看表中数据大小
    dfs -du -h /user/hive/warehouse/log_orc/ ;
    2.8 M  /user/hive/warehouse/log_orc/000000_0
--3)Parquet
--(1)创建表,存储数据格式为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 ;    
--(2)向表中加载数据
    insert into table log_parquet select * from log_text ;
--(3)查看表中数据大小
    dfs -du -h /user/hive/warehouse/log_parquet/ ;
    13.1 M  /user/hive/warehouse/log_parquet/000000_0
--存储文件的压缩比总结:
    ORC >  Parquet >  textFile

3. 存储和压缩相结合

key

default

notes

orc.compress

ZLIB

high level compression (one of NONE, ZLIB, SNAPPY)

orc.compress.size

262,144

number of bytes in each compression chunk  

orc.stripe.size

67,108,864

number of bytes in each stripe

orc.row.index.stride

10,000

number of rows between index entries (must be >= 1000)

orc.create.index

true

whether to create row indexes  

orc.bloom.filter.columns

""

comma separated list of column names for which bloom filter should be created

orc.bloom.filter.fpp

0.05

false positive probability for bloom filter (must >0.0 and <1.0)

--1)创建一个非压缩的的ORC存储方式
--(1)建表语句
    create table log_orc_none(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"="NONE");
--(2)插入数据
    insert into table log_orc_none select * from log_text ;
--(3)查看插入后数据
    dfs -du -h /user/hive/warehouse/log_orc_none/ ;
    7.7 M  /user/hive/warehouse/log_orc_none/000000_0
--2)创建一个SNAPPY压缩的ORC存储方式
--(1)建表语句
    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");
--(2)插入数据
    insert into table log_orc_snappy select * from log_text ;
--(3)查看插入后数据
    dfs -du -h /user/hive/warehouse/log_orc_snappy/ ;
    3.8 M  /user/hive/warehouse/log_orc_snappy/000000_0
--3)上一节中默认创建的ORC存储方式,导入数据后的大小为
    2.8 M  /user/hive/warehouse/log_orc/000000_0
--总结
    比Snappy压缩的还小。原因是orc存储文件默认采用ZLIB压缩。比snappy压缩的小。