Hive基本原理与数据开发
目录
1.什么是Hive
2.Hive的特点和优势
2.1.Hive的特点
2.1.1.易用性
2.1.2.高效性
2.1.3.兼容性
2.1.4.可扩展性
2.1.5.容错性
2.2.与传统数据库的区别
3.hive的架构
3.1.hive的核心组件(如 Metastore、Driver、Query Compiler、Execution Engine 等)
3.1.1.用户接口(Client):包括CLI、JDBC/ODBC、WebGUI
3.1.2.元数据存储(Meta Store)
3.1.3.Driver驱动模块( 解释器、编译器、优化器)
3.1.4.执行器
3.2.Hive 与 HDFS 的集成
3.3.Hive 的工作流程:
3.3.1.客户端提交SQL语句
3.3.2.SQL解析成抽象语法树(AST)
3.3.3.语义分析与查询块(Query Block)构建
3.3.4.生成逻辑查询计划(Operator Tree)
3.3.5.逻辑计划优化
3.3.6.生成物理计划(MapReduce任务)
3.3.7.物理计划优化
3.3.8.提交MapReduce作业
3.3.9.结果返回给客户端
4.Hive中表、数据库、分区和桶的概念
4.1.Databases数据库
4.2.表
4.3.分区
4.4.分桶
5.HiveSQL基础语法
5.1.数据定义语言 (DDL)
5.1.1.创建数据库和表
5.1.2.修改表
5.1.3.删除数据库和表
5.2.数据操作语言 (DML)
5.2.1.插入数据
5.2.2. 更新数据
5.2.3.删除数据
5.3.查询语句 (SELECT)
6.优化hive查询
6.1.使用分区和桶优化数据存储和查询性能。
6.1.1.分区
6.1.2.分桶
6.2.使用 Hive 内置的优化器和性能调优方法
6.2.1.压缩
6.2.1.1.启动压缩
6.2.1.2.选择合适的数据存储格式:
6.2.2.其他调优方法
6.2.2.1.并行执行
6.2.2.2.启动CBO
6.2.2.3.减少小文件
1.什么是Hive
hive是基于hadoop 的一个数据仓库工具,用于进行数据提取、转化、加载、这是一种可以存储,查询和分析存储在hadoop中的大规模数据机制。 hive数据仓库工具能够将结构化的数据文件映射为一张数据库表,并提供SQL查询功能,能够SQL语句转变成MapReduce任务来执行。Hive的优点是学习成本低,可以通过类似SQL语句实现快速MapReduce统计,使MapReduce变得更加简单,而不必开发专门的MapReduce应用程序。hive十分适合对数据仓库进行统计分析。
2.Hive的特点和优势
2.1.Hive的特点
2.1.1.易用性
SQL查询语言:Hive提供类似SQL的HiveSQL查询语言,降低了Hadoop编程的门槛,使用户无需编写复杂的MapReduce程序就能进行大数据分析。
易于集成:Hive 可以与其他 Hadoop 生态系统组件(如 HDFS、YARN、HBase)无缝集成,便于用户构建复杂的数据处理管道。
2.1.2.高效性
大规模数据处理能力:Hive 构建在 Hadoop 之上,利用 Hadoop 的分布式计算和存储能力,能够处理 PB 级别的数据。
优化执行:Hive 支持多种执行引擎(如 MapReduce、Tez、Spark),可以根据具体场景选择最优的执行引擎,优化查询性能。
列存储格式:Hive 支持 ORC、Parquet 等列式存储格式,有助于数据压缩和快速读取,进一步提升查询效率。
2.1.3.兼容性
兼容多种数据格式:支持多种数据格式(如文本,JSON,Avro,ORC,Parquet等),使得Hive能够处理多种来源和格式的数据。
与传统数据库兼容:Hive支持许多SQL标准,并可以与传统数据仓库(如MYSQL,PostgreSQL等)中SQL语句兼容 ,易于数据库管理员和分析人员上手。
2.1.4.可扩展性
支持用户自定义函数(UDF):Hive 支持用户自定义函数(UDFs),使用户可以扩展 HiveSQL 的功能来满足特定的业务需求。
支持多种存储系统:除了 HDFS,Hive 还支持多种存储系统(如 Amazon S3、Azure Blob Storage 等),提高了数据存储和管理的灵活性。
2.1.5.容错性
自动任务重试机制:利用 Hadoop 提供的分布式计算和存储的优势,Hive 能够在任务失败时自动重试,具有较好的容错性和稳定性。
2.2.与传统数据库的区别
Hive | RDBMS | |
架构 | 分布式架构 | 单机/集群 |
数据量级 | PB | GB |
数据存储 | HDFS | Raw Device or Local FS |
数据更新 | 不支持频繁改写和添加 | 支持改写和添加 |
查询语言 | Hsql | SQL |
执行延迟 | 高 | 低 |
可扩展性 | 高 | 低 |
索引 | 无 | 有 |
引擎 | MR、Tez或Spark | Excutor |
事务支持 | 不支持 ACID 事务 | 支持 ACID 事务 |
数据一致性 | 数据一致性要求相对较低 | 提供严格的数据一致性保证 |
数据一致性 | Schema-on-Read | Schema-on-Write |
查询优化 | 依赖于CBO和底层执行引擎优化 | 内置强大的查询优化器 |
使用场景 | 数据仓库、批处理、大数据分析 | 事务处理、实时查询、高并发场景 |
3.hive的架构
3.1.hive的核心组件(如 Metastore、Driver、Query Compiler、Execution Engine 等)
3.1.1.用户接口(Client):包括CLI、JDBC/ODBC、WebGUI
Hive的用户接口主要有3个:CLI(命令行界面),Client(客户端)和WUI(web用户界面)。CLI是最常用的接口,启动CLI时会启动一个Hive副本。Client时Hive的客户端,用户通过Client连接至Hive server。启动Client模式时,需要指定Hive Server所在节点,并在该节点启动Hive Server。WUI则是通过浏览器访问Hive。
3.1.2.元数据存储(Meta Store)
Hive将元数据存储再数据库中,如Mysql,Derby等。Hive中的元数据包括表的名字、表的列和分区及其属性、表的属性(是否为外部表等)、表的数据所在目录等。这些元数据信息对于Hive的操作和管理非常重要。
3.1.3.Driver驱动模块( 解释器、编译器、优化器)
解释器、编译器、优化器是Hive的核心组件,用于完成HSQL查询语句的解析、编译和优化。解释器负责将HSQL查询语句进行词法分析和语法分析,编译器则将解析后的语法树进行编译和优化,生成高效的查询计划。优化器则进一步对查询计划进行优化,提高查询的效率和性能。生成的查询计划存储在HDFS中,供后续的MapReduce调用执行。
3.1.4.执行器
执行器是Hive的执行模块,负责执行查询计划并生成相应的MapReduce任务。Hive通过与Hadoop集成,利用MapReduce框架处理和计算大规模数据。执行器生成的MapReduce任务会被提交到Hadoop集群中运行,最终返回查询结果。
3.2.Hive 与 HDFS 的集成
数据存储在 HDFS 中,Hive 用于处理和分析数据。
Hive是一个基于Hadoop文件系统之上的数据仓库架构,存储用hdfs,计算MapReduce。
3.3.Hive 的工作流程:
Hive的本质就是将HSQL转换成MapReduce程序
3.3.1.客户端提交SQL语句
用户在hive客户端,(如Hive CLI或Beeline)中输入SQL查询语句
例如Select * from table_name WHERE column > 100;
3.3.2.SQL解析成抽象语法树(AST)
hive的Sql解析器(Parser)读取SQL查询,并将其解析为一个抽象语法树(AST),用于表示SQL查询的语法结构。解析器会检查SQL的语法正确性,并生成对应的AST。
对于示例查询,AST会包括节点表示:
select | 关键字 |
* | 选择所有列 |
from table_name | 指定数据源 |
where column > 100 | 过滤条件 |
3.3.3.语义分析与查询块(Query Block)构建
Hive的语义分析器(Semantic Analyzer)遍历 AST 进行语义检查(例如表名、列名的正确性,用户权限检查等)。语义分析通过后,将查询拆分为多个查询块(Query Block)。每个查询块代表一个基础查询单元,例如一个子查询或 JOIN 操作。例如:
检查table_name 表是否存在 |
检查 column 列是否存在于 table_name 表中 |
验证用户权限,确保用户有权访问和查询该表 |
3.3.4.生成逻辑查询计划(Operator Tree)
Hive 编译器(Compiler)将查询块(Query Block)转换为逻辑查询计划,通常称为 操作符树(Operator Tree)。这棵树结构表示了查询中各个操作(如过滤、连接、聚合等)的逻辑步骤。操作符树中的每个节点代表一个逻辑操作符,例如 TableScanOperator
(扫描表)、FilterOperator
(过滤操作)、JoinOperator
(连接操作)等。
TableScanOperator | 扫描table_name表的所有数据 |
FilterOperator | 应用 WHERE column > 100 过滤条件 |
3.3.5.逻辑计划优化
Hive 的逻辑优化器(Logical Optimizer)对操作符树进行一系列的逻辑优化。例如,合并不必要的 ReduceSinkOperator
,以减少数据在 MapReduce 作业中的 shuffle
操作量,从而优化性能。优化后的操作符树将生成一个更高效的查询执行策略。
确认FilterOperator尽可能靠近TableScanOperator,以便尽早过滤数据,减少后续操作的数据量。
3.3.6.生成物理计划(MapReduce任务)
优化后的操作符树被进一步转换为一个或多个 MapReduce 任务。在这个阶段,每个操作符或操作符子树被映射为一个对应的 MapReduce 作业。生成的物理计划详细描述了如何使用 Hadoop 的 MapReduce 框架来执行查询,包括映射(Map)阶段和归约(Reduce)阶段的逻辑。
Mapper阶段 | 从HDFS中读取table_name表的数据 |
Mapper阶段 | 使用过滤条件 column > 100 ,将符合条件的记录输出到临时存储。 |
Reduce阶段 | 因为这个查询没有聚合或 JOIN 操作,所以不需要 Reduce 阶段。作业优化器可以决定省略 Reduce 阶段。 |
3.3.7.物理计划优化
物理计划生成后,物理优化器(Physical Optimizer)对 MapReduce 作业进行进一步优化。例如,重新排列 MapReduce 作业的执行顺序、合并多个 MapReduce 作业、启用数据压缩、选择合适的数据格式等。优化的结果是一个经过调整的最终执行计划,这个计划会被转换为 Hadoop 可执行的 MapReduce 作业。例如:
确认不需要Reduce阶段,直接输出Mapper的结果 |
选择合适的数据格式(如ORC、Parquet)和压缩方式以便提高性能。 |
3.3.8.提交MapReduce作业
Hive 的执行引擎将生成的 MapReduce 作业提交给 Hadoop 的 YARN集群资源管理器。YARN 负责管理作业的资源分配、任务调度和执行。
Hive 执行引擎将物理执行计划(即生成的 MapReduce 作业)提交给 Hadoop YARN |
YARN 分配集群资源,调度并管理 MapReduce 作业的执行 |
Hadoop的MapReduce框架执行计划的Map阶段任务:
从HDFS中读取table_name表的数据,逐行读取每条记录 |
应用过滤条件column>100 |
过滤符合条件的记录写入临时文件存储 |
由于没有 Reduce 阶段,任务直接输出结果
3.3.9.结果返回给客户端
MapReduce 作业执行完成后,Hive 执行引擎收集结果,并将最终结果返回给客户端。用户可以在客户端(如 Hive CLI 或 Beeline)查看查询结果,即所有满足 column > 100
条件的行。
4.Hive中表、数据库、分区和桶的概念
hive中所有的数据都存储在hdfs中,它包含数据库( Database )、表( Table )、分区表( Partition )和桶表( Bucket ) 4 种数据类型,其模型如图所示。
4.1.Databases数据库
Hive作为一个数据仓库,在结构上积极向传统数据看齐,也分数据库(Schema),每个数据库下面有各自的表组成。默认数据库default。
Hive的数据都是存储在HDFS上的,默认有一个根目录,在hive-site.xml中,由参数hive.metastore.warehouse.dir指定。默认值为/user/hive/warehouse。
因此,Hive中的数据库在HDFS上的存储路径为:${hive.metastore.warehouse.dir}/databasename.db
比如,名为itcast的数据库存储路径为:
/user/hive/warehouse/itcast.db
4.2.表
Hive表与关系数据库中的表相同。hive中的表所对应的数据通常是存储在hdfs中,而表相关的元数据是存储在RDBMS中。
Hive中的表数据在HDFS上的存储路径为:
${hive.metastore.warehouse.dir}/databasename.db/tablename
比如,itcast的数据库下t_user表存储路径为:
/user/hive/warehouse/itcast.db/t_user
4.3.分区
Partition分区时hive的一种优化手段表。分区时指根据分区列(例如“日期day”)的值将表划分为不同分区。这样可以更快的指定分区数据进行查询。
分区存储层面表现是:table表目录下以子文件夹形式存在。
一个文件夹表示一个分区。子文件命名标准:分区列=分区值。
hive还支持分区下继续创建分区,所谓的多重分区。
比如,itcast的数据库下t_student表下按照性别分区存储路径为:
//user/hive/warehouse/itcast.db/t_student/sex=male
//user/hive/warehouse/itcast.db/t_student/sex=female
4.4.分桶
Bucket分桶表是hive的一种优化手段表。分桶是指根据表中字段(例如 “编号ID”)的值,经过hash计算规划将数据文件划分成指定的若干个小文件。
比如可以这样理解:"23届大学生" 的数据已经按照班级分区好了,每个班级的数据分到不同的文件夹中,但如果每个班级的数据量依然很大,查询起来效率低。这时候可以再对每个班级的数据进行分桶,比如按照学生的学号列的哈希值,将数据分成多个桶文件存储。
5.HiveSQL基础语法
5.1.数据定义语言 (DDL)
5.1.1.创建数据库和表
创建数据库
CREATE DATABASE IF NOT EXISTS db_name;
创建表
CREATE TABLE IF NOT EXISTS table_name (
column1 datatype,
column2 datatype,
...
)
COMMENT 'Table description'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
--IF NOT EXISTS:这表示如果表已经存在,则不再重新新创建,以防止因重复创建表而报错。
--COMMENT:为表提供一个描述性的注释,便于理解表的用途或数据内容。这是可选的,不会影响表的功能。
--ROW FORMAT DELIMITED:这部分定义了表的行格式,即数据文件中每一行的分隔方式。
--FIELDS TERMINATED BY ',':指定每一行中字段之间的分隔符。在这个例子中,逗号 , 是字段的分隔符,表示表中的数据以逗号分隔。
--STORED AS:指定表的数据存储格式。
--TEXTFILE:表示表的数据以文本文件格式存储,这是Hive中常用的一种数据存储格式。每行数据将以纯文本格式存储。
5.1.2.修改表
向表中添加新列
ALTER TABLE table_name ADD COLUMNS (new_column datatype);
--ALTER TABLE 用于修改现有的表结构。ADD COLUMNS 可以向表中添加新的列。
5.1.3.删除数据库和表
删除数据库:如果数据库存在则删除,并强制删除相关表
DROP DATABASE IF EXISTS db_name CASCADE;
--DROP DATABASE 用于删除数据库。
--IF EXISTS 防止数据库不存在时报错。
--CASCADE 表示删除数据库的同时,删除该数据库下的所有表。
删除表
DROP TABLE IF EXISTS table_name;
--DROP TABLE 用于删除一个表,IF EXISTS 防止在表不存在时报错。
5.2.数据操作语言 (DML)
5.2.1.插入数据
插入一条或多条数据到表中:
INSERT INTO TABLE table_name VALUES (value1, value2, ...);
-- INSERT INTO TABLE 用于向表中插入数据,VALUES 指定插入的值。
从查询结果中插入数据到目标表:
INSERT INTO TABLE target_table SELECT * FROM source_table;
-- 这条语句从源表中查询数据,并将结果插入到目标表。SELECT * 表示选择源表的所有列。
5.2.2. 更新数据
HiveSQL不直接支持UPDATE操作。通常会通过创建临时表来模拟更新操作。
5.2.3.删除数据
HiveSQL中不支持逐行删除数据,但可以通过删除整个表或分区来实现类似效果。
5.3.查询语句 (SELECT)
--基本查询
SELECT column1, column2 FROM table_name;
--过滤条件 使用 WHERE 语句进行数据过滤:
SELECT * FROM table_name WHERE column1 = 'value';
--排序使用 ORDER BY 进行排序:
SELECT * FROM table_name ORDER BY column1 ASC;
-- 聚合操作 使用聚合函数如 COUNT、SUM、AVG 等:
SELECT COUNT(*) FROM table_name;
--分组聚合 使用 GROUP BY 进行分组聚合:
SELECT column1, COUNT(*) FROM table_name GROUP BY column1;
--连接操作 使用 JOIN 连接多个表:
SELECT a.column1, b.column2
FROM table_a a
JOIN table_b b ON a.id = b.id;
6.优化hive查询
6.1.使用分区和桶优化数据存储和查询性能。
6.1.1.分区
分区是一种将大表的数据按某个字段进行拆分的方式。通过分区,可以避免每次查询都扫描整个表的数据,减少数据扫描量,提升查询速度。
CREATE TABLE table_name (
column1 datatype,
column2 datatype,
...
)
PARTITIONED BY (partition_column datatype);
--PARTITIONED BY 用于定义分区字段,例如按日期、地区或类别来划分数据。
在查询时,通过 WHERE 子句限制在特定分区上进行查询,可以显著减少扫描的数据量。
示例:
SELECT * FROM table_name WHERE partition_column = '2024-09-01';
这个查询只会扫描符合特定分区条件的数据,从而提升查询效率。
6.1.2.分桶
分桶是另一种将数据划分成更小单元的方法。它基于哈希函数来将数据分散到不同的桶中。在与分区配合使用时,分桶可以进一步提升查询效率,尤其是对具有相同分桶字段的表进行联接操作时。
CREATE TABLE table_name (
column1 datatype,
column2 datatype,
...
)
CLUSTERED BY (bucket_column) INTO num_buckets BUCKETS;
--CLUSTERED BY 指定用于分桶的列。
--INTO num_buckets BUCKETS 定义桶的数量,Hive 会将数据分成相应数量的文件。
示例
SELECT * FROM table_name WHERE bucket_column = 'value';
使用分桶可以有效缩小查询范围,从而加快查询速度,特别是在联接操作中表现尤为显著。
6.2.使用 Hive 内置的优化器和性能调优方法
6.2.1.压缩
压缩数据可以显著减少存储空间和 I/O 负载。Hive 支持多种压缩格式,比如 Gzip
、Snappy
、Bzip2
等。在进行查询时,压缩数据也会减少磁盘读取时间,从而加速查询。
6.2.1.1.启动压缩
SET hive.exec.compress.output=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
以上设置会启用压缩输出,并使用 Snappy 压缩格式。
6.2.1.2.选择合适的数据存储格式:
TextFile | 默认格式适合简单存储,但效率较低 |
SequenceFile | 支持压缩的二进制格式,适合大批量数据处理 |
ORC | 面向列存储的格式,适合需要快速查询和聚合的场景,通常用于数据仓库。 |
Parquet | 类似 ORC 的列存储格式,常用于与 Spark、Impala 等系统集成。 |
选择数据格式的示例:
CREATE TABLE table_name (
column1 datatype,
column2 datatype,
...
)
STORED AS ORC;
--STORED AS ORC 将表的数据存储为 ORC 格式,这种格式压缩率高且查询性能好。
6.2.2.其他调优方法
6.2.2.1.并行执行
SET hive.exec.parallel=true;
-- 允许 Hive 并行执行多个任务,提升任务整体的执行效率。
6.2.2.2.启动CBO
SET hive.cbo.enable=true;
-- CBO 是基于代价的优化器,通过分析查询代价,选择最优的执行计划。
6.2.2.3.减少小文件
当表中有大量小文件时,会影响查询性能,可以通过 hive.merge.mapfiles
和 hive.merge.mapredfiles
参数在查询时合并小文件:
SET hive.merge.mapfiles=true;
SET hive.merge.mapredfiles=true;